diff --git a/.dorpsgek.yml b/.dorpsgek.yml new file mode 100644 index 0000000000..a8b976f5c7 --- /dev/null +++ b/.dorpsgek.yml @@ -0,0 +1,13 @@ +notifications: + push: + irc: + - openttd + - openttd.notice + pull-request: + irc: + - openttd + - openttd.notice + issue: + irc: + - openttd + - openttd.notice diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d77071e669..2c7ce528c9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -107,7 +107,7 @@ git clone https://github.com/OpenTTD/OpenTTD-git-hooks.git openttd_hooks cd openttd git remote add upstream https://github.com/OpenTTD/OpenTTD.git cd .git/hooks -ln -s -t . ../../../openttd_hooks/hooks/* +ln -s ../../../openttd_hooks/hooks/* . ``` 2. If you cloned a while ago, get the latest changes from upstream: @@ -149,6 +149,16 @@ git push **IMPORTANT**: By submitting a patch, you agree to the [License](#license). +### Privacy Notice + +We would like to make you aware that contributing to OpenTTD via git will permanently store the name and email address you provide as well as the actual changes and the time and date you made it inside git's version history. + +This is inevitable, because it is a main feature of git. If you are concerned about your privacy, we strongly recommend to use "Anonymous <anonymous@openttd.org>" as the git commit author. We might refuse anonymous contributions if malicious intent is suspected. + +Please note that the contributor identity, once given, is used for copyright verification and to provide proof should a malicious commit be made. As such, the [EU GDPR](https://www.eugdpr.org/key-changes.html) "right to be forgotten" does not apply, as this is an overriding legitimate interest. + +Please also note that your commit is public and as such will potentially be processed by many third-parties. Git's distributed nature makes it impossible to track where exactly your commit, and thus your personal data, will be stored and be processed. If you would not like to accept this risk, please do either commit anonymously or refrain from contributing to the OpenTTD project. + ### Pull request validation Continuous integration (CI) tools monitor pull requests, and help us identify build and code quality issues. @@ -168,3 +178,4 @@ By contributing your code, you agree to license your contribution under the [GPL ### Attribution of this Contributing Guide This contributing guide is adapted from [Bootstrap](https://github.com/twbs/bootstrap/blob/master/CONTRIBUTING.md) under the [Creative Commons Attribution 3.0 Unported License](https://github.com/twbs/bootstrap/blob/master/docs/LICENSE) terms for Bootstrap documentation. +The GDPR notice is adapted from [rsyslog](https://github.com/rsyslog/rsyslog/blob/master/CONTRIBUTING.md) under the [GNU General Public License](https://github.com/rsyslog/rsyslog/blob/master/COPYING). diff --git a/Doxyfile b/Doxyfile index 58d7f0a89a..251b36be15 100644 --- a/Doxyfile +++ b/Doxyfile @@ -8,9 +8,14 @@ #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = OpenTTD +PROJECT_NUMBER = +PROJECT_BRIEF = +PROJECT_LOGO = OUTPUT_DIRECTORY = docs/source/ -CREATE_SUBDIRS = NO +CREATE_SUBDIRS = YES +ALLOW_UNICODE_NAMES = NO OUTPUT_LANGUAGE = English BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES @@ -32,22 +37,42 @@ STRIP_FROM_PATH = ./ STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = YES +QT_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO INHERIT_DOCS = YES -DISTRIBUTE_GROUP_DOC = NO +SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 2 ALIASES = +TCL_SUBST = OPTIMIZE_OUTPUT_FOR_C = YES OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +EXTENSION_MAPPING = +MARKDOWN_SUPPORT = YES +TOC_INCLUDE_HEADINGS = 0 +AUTOLINK_SUPPORT = YES +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +GROUP_NESTED_COMPOUNDS = NO SUBGROUPING = YES +INLINE_GROUPED_CLASSES = NO +INLINE_SIMPLE_STRUCTS = NO +TYPEDEF_HIDES_STRUCT = NO +LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- EXTRACT_ALL = NO EXTRACT_PRIVATE = YES +EXTRACT_PACKAGE = NO EXTRACT_STATIC = YES EXTRACT_LOCAL_CLASSES = YES EXTRACT_LOCAL_METHODS = YES +EXTRACT_ANON_NSPACES = YES HIDE_UNDOC_MEMBERS = NO HIDE_UNDOC_CLASSES = NO HIDE_FRIEND_COMPOUNDS = NO @@ -55,11 +80,17 @@ HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO CASE_SENSE_NAMES = YES HIDE_SCOPE_NAMES = NO +HIDE_COMPOUND_REFERENCE= NO SHOW_INCLUDE_FILES = YES +SHOW_GROUPED_MEMB_INC = NO +FORCE_LOCAL_INCLUDES = NO INLINE_INFO = YES SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO +SORT_MEMBERS_CTORS_1ST = NO +SORT_GROUP_NAMES = NO SORT_BY_SCOPE_NAME = NO +STRICT_PROTO_MATCHING = NO GENERATE_TODOLIST = YES GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES @@ -67,22 +98,27 @@ GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES -SHOW_DIRECTORIES = YES +SHOW_FILES = YES +SHOW_NAMESPACES = YES FILE_VERSION_FILTER = +LAYOUT_FILE = +CITE_BIB_FILES = #--------------------------------------------------------------------------- -# configuration options related to warning and progress messages +# Configuration options related to warning and progress messages #--------------------------------------------------------------------------- QUIET = NO WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = NO +WARN_AS_ERROR = NO WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = #--------------------------------------------------------------------------- -# configuration options related to the input files +# Configuration options related to the input files #--------------------------------------------------------------------------- INPUT = ./src/ +INPUT_ENCODING = UTF-8 FILE_PATTERNS = *.c \ *.cc \ *.cxx \ @@ -93,31 +129,38 @@ FILE_PATTERNS = *.c \ RECURSIVE = YES EXCLUDE = EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = */3rdparty */.svn */script/api +EXCLUDE_PATTERNS = */3rdparty \ + */script/api +EXCLUDE_SYMBOLS = EXAMPLE_PATH = EXAMPLE_PATTERNS = * EXAMPLE_RECURSIVE = NO -IMAGE_PATH =./docs/ +IMAGE_PATH = ./docs/ INPUT_FILTER = FILTER_PATTERNS = FILTER_SOURCE_FILES = NO +FILTER_SOURCE_PATTERNS = +USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- -# configuration options related to source browsing +# Configuration options related to source browsing #--------------------------------------------------------------------------- SOURCE_BROWSER = YES INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES REFERENCED_BY_RELATION = YES REFERENCES_RELATION = YES +REFERENCES_LINK_SOURCE = YES +SOURCE_TOOLTIPS = YES +USE_HTAGS = NO VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index +# Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = NO COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = #--------------------------------------------------------------------------- -# configuration options related to the HTML output +# Configuration options related to the HTML output #--------------------------------------------------------------------------- GENERATE_HTML = YES HTML_OUTPUT = html @@ -125,19 +168,58 @@ HTML_FILE_EXTENSION = .html HTML_HEADER = HTML_FOOTER = HTML_STYLESHEET = -HTML_ALIGN_MEMBERS = YES -GENERATE_HTMLHELP = YES +HTML_EXTRA_STYLESHEET = +HTML_EXTRA_FILES = +HTML_COLORSTYLE_HUE = 220 +HTML_COLORSTYLE_SAT = 100 +HTML_COLORSTYLE_GAMMA = 80 +HTML_TIMESTAMP = NO +HTML_DYNAMIC_MENUS = YES +HTML_DYNAMIC_SECTIONS = NO +HTML_INDEX_NUM_ENTRIES = 100 +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_BUNDLE_ID = org.doxygen.Project +DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_PUBLISHER_NAME = Publisher +GENERATE_HTMLHELP = NO CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO +CHM_INDEX_ENCODING = BINARY_TOC = NO TOC_EXPAND = YES +GENERATE_QHP = NO +QCH_FILE = +QHP_NAMESPACE = org.doxygen.Project +QHP_VIRTUAL_FOLDER = doc +QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = +QHG_LOCATION = +GENERATE_ECLIPSEHELP = NO +ECLIPSE_DOC_ID = org.doxygen.Project DISABLE_INDEX = NO -ENUM_VALUES_PER_LINE = 4 GENERATE_TREEVIEW = YES +ENUM_VALUES_PER_LINE = 4 TREEVIEW_WIDTH = 250 +EXT_LINKS_IN_WINDOW = NO +FORMULA_FONTSIZE = 10 +FORMULA_TRANSPARENT = YES +USE_MATHJAX = NO +MATHJAX_FORMAT = HTML-CSS +MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/ +MATHJAX_EXTENSIONS = +MATHJAX_CODEFILE = +SEARCHENGINE = NO +SERVER_BASED_SEARCH = NO +EXTERNAL_SEARCH = NO +SEARCHENGINE_URL = +SEARCHDATA_FILE = searchdata.xml +EXTERNAL_SEARCH_ID = +EXTRA_SEARCH_MAPPINGS = #--------------------------------------------------------------------------- -# configuration options related to the LaTeX output +# Configuration options related to the LaTeX output #--------------------------------------------------------------------------- GENERATE_LATEX = NO LATEX_OUTPUT = latex @@ -147,12 +229,18 @@ COMPACT_LATEX = NO PAPER_TYPE = a4wide EXTRA_PACKAGES = LATEX_HEADER = +LATEX_FOOTER = +LATEX_EXTRA_STYLESHEET = +LATEX_EXTRA_FILES = PDF_HYPERLINKS = NO USE_PDFLATEX = NO LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO +LATEX_SOURCE_CODE = NO +LATEX_BIB_STYLE = plain +LATEX_TIMESTAMP = NO #--------------------------------------------------------------------------- -# configuration options related to the RTF output +# Configuration options related to the RTF output #--------------------------------------------------------------------------- GENERATE_RTF = NO RTF_OUTPUT = rtf @@ -160,27 +248,33 @@ COMPACT_RTF = NO RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = +RTF_SOURCE_CODE = NO #--------------------------------------------------------------------------- -# configuration options related to the man page output +# Configuration options related to the man page output #--------------------------------------------------------------------------- GENERATE_MAN = NO MAN_OUTPUT = man MAN_EXTENSION = .3 +MAN_SUBDIR = MAN_LINKS = NO #--------------------------------------------------------------------------- -# configuration options related to the XML output +# Configuration options related to the XML output #--------------------------------------------------------------------------- GENERATE_XML = NO XML_OUTPUT = xml -XML_SCHEMA = -XML_DTD = XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output +# Configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- +GENERATE_DOCBOOK = NO +DOCBOOK_OUTPUT = docbook +DOCBOOK_PROGRAMLISTING = NO +#--------------------------------------------------------------------------- +# Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- -# configuration options related to the Perl module output +# Configuration options related to the Perl module output #--------------------------------------------------------------------------- GENERATE_PERLMOD = NO PERLMOD_LATEX = NO @@ -195,42 +289,67 @@ EXPAND_ONLY_PREDEF = YES SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = -PREDEFINED = ENABLE_NETWORK WITH_ZLIB WITH_LZO WITH_LZMA WITH_SDL WITH_PNG WITH_FONTCONFIG WITH_FREETYPE WITH_ICU_SORT WITH_ICU_LAYOUT UNICODE _UNICODE _GNU_SOURCE FINAL= +PREDEFINED = ENABLE_NETWORK \ + WITH_ZLIB \ + WITH_LZO \ + WITH_LZMA \ + WITH_SDL \ + WITH_PNG \ + WITH_FONTCONFIG \ + WITH_FREETYPE \ + WITH_ICU_SORT \ + WITH_ICU_LAYOUT \ + UNICODE \ + _UNICODE \ + _GNU_SOURCE \ + FINAL= EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- -# Configuration::additions related to external references +# Configuration options related to external references #--------------------------------------------------------------------------- TAGFILES = GENERATE_TAGFILE = objs/openttd.tag ALLEXTERNALS = NO EXTERNAL_GROUPS = YES +EXTERNAL_PAGES = YES PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- CLASS_DIAGRAMS = YES +MSCGEN_PATH = +DIA_PATH = HIDE_UNDOC_RELATIONS = YES HAVE_DOT = NO +DOT_NUM_THREADS = 0 +DOT_FONTNAME = Helvetica +DOT_FONTSIZE = 10 +DOT_FONTPATH = CLASS_GRAPH = YES COLLABORATION_GRAPH = YES GROUP_GRAPHS = YES UML_LOOK = NO +UML_LIMIT_NUM_FIELDS = 10 TEMPLATE_RELATIONS = NO INCLUDE_GRAPH = YES INCLUDED_BY_GRAPH = YES CALL_GRAPH = NO +CALLER_GRAPH = NO GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png +INTERACTIVE_SVG = NO DOT_PATH = DOTFILE_DIRS = +MSCFILE_DIRS = +DIAFILE_DIRS = +PLANTUML_JAR_PATH = +PLANTUML_CFG_FILE = +PLANTUML_INCLUDE_PATH = +DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 1000 DOT_TRANSPARENT = NO DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES DOT_CLEANUP = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- -SEARCHENGINE = NO diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index af7968e71e..0000000000 --- a/Jenkinsfile +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env groovy - -// The stages we run one by one -// Please don't add more than 2 items in a single stage; this hurts performance -def ci_stages = [ - "Checkers": [ - "commit-checker": "openttd/compile-farm-ci:commit-checker", - ], - "Compilers": [ - "linux-amd64-gcc-6": "openttd/compile-farm-ci:linux-amd64-gcc-6", - "linux-amd64-clang-3.8": "openttd/compile-farm-ci:linux-amd64-clang-3.8", - ], - "Archs": [ - "linux-i386-gcc-6": "openttd/compile-farm-ci:linux-i386-gcc-6", - ], - "OS": [ - "osx-10.9": "openttd/compile-farm-ci:osx-10.9", - ], -] - -def generateStage(targets) { - return targets.collectEntries{ key, target -> - ["${key}": generateCI(key, target)] - } -} - -def generateCI(display_name, image_name) { - return { - githubNotify context: 'openttd/' + display_name, description: 'This commit is being built', status: 'PENDING' - - try { - dir("${display_name}") { - unstash "source" - - docker.image("${image_name}").pull() - docker.image("${image_name}").withRun("--volumes-from ${hostname} --workdir " + pwd()) { c -> - sh "docker logs --follow ${c.id}; exit `docker wait ${c.id}`" - } - } - - githubNotify context: 'openttd/' + display_name, description: 'The commit looks good', status: 'SUCCESS' - } - catch (error) { - githubNotify context: 'openttd/' + display_name, description: 'The commit cannot be built', status: 'FAILURE' - throw error - } - } -} - -node { - ansiColor('xterm') { - stage("Checkout") { - checkout scm - - // Ensure user.email and user.name is set, otherwise rebase cannot work - sh "git config user.email 'info@openttd.org'" - sh "git config user.name 'OpenTTD CI'" - - // Ensure we also have origin/master available - sh "git fetch --no-tags origin master:refs/remotes/origin/master" - - // Try to rebase to origin/master; if this fails, fail the CI - sh "git rebase origin/master" - - stash name: "source", useDefaultExcludes: false - } - - ci_stages.each { ci_stage -> - stage(ci_stage.key) { - parallel generateStage(ci_stage.value) - } - } - } -} - diff --git a/Makefile.lang.in b/Makefile.lang.in index fbed06b790..2853ae3898 100644 --- a/Makefile.lang.in +++ b/Makefile.lang.in @@ -6,7 +6,6 @@ # 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 . STRGEN = !!STRGEN!! -ENDIAN_CHECK = !!ENDIAN_CHECK!! SRC_DIR = !!SRC_DIR!! LANG_DIR = !!LANG_DIR!! BIN_DIR = !!BIN_DIR!! @@ -25,11 +24,6 @@ ifeq ($(LANG_SUPPRESS), yes) LANG_ERRORS = >/dev/null 2>&1 endif -# Make sure endian_host.h is reachable as if it was in the src/ dir -CFLAGS_BUILD += -I $(LANG_OBJS_DIR) - -ENDIAN_TARGETS := endian_host.h endian_target.h $(ENDIAN_CHECK) - # Check if we want to show what we are doing ifdef VERBOSE Q = @@ -43,19 +37,19 @@ RES := $(shell mkdir -p $(BIN_DIR)/lang ) all: table/strings.h $(LANGS) -strgen_base.o: $(SRC_DIR)/strgen/strgen_base.cpp $(SRC_DIR)/strgen/strgen.h endian_host.h $(SRC_DIR)/table/control_codes.h $(SRC_DIR)/table/strgen_tables.h $(SRC_DIR)/safeguards.h +strgen_base.o: $(SRC_DIR)/strgen/strgen_base.cpp $(SRC_DIR)/strgen/strgen.h $(SRC_DIR)/table/control_codes.h $(SRC_DIR)/table/strgen_tables.h $(SRC_DIR)/safeguards.h $(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.cpp=%.cpp)' $(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) -DSTRGEN -c -o $@ $< -strgen.o: $(SRC_DIR)/strgen/strgen.cpp $(SRC_DIR)/strgen/strgen.h endian_host.h $(SRC_DIR)/table/control_codes.h $(SRC_DIR)/table/strgen_tables.h $(SRC_DIR)/safeguards.h +strgen.o: $(SRC_DIR)/strgen/strgen.cpp $(SRC_DIR)/strgen/strgen.h $(SRC_DIR)/table/control_codes.h $(SRC_DIR)/table/strgen_tables.h $(SRC_DIR)/safeguards.h $(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.cpp=%.cpp)' $(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) -DSTRGEN -c -o $@ $< -string.o: $(SRC_DIR)/string.cpp endian_host.h $(SRC_DIR)/safeguards.h +string.o: $(SRC_DIR)/string.cpp $(SRC_DIR)/safeguards.h $(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.cpp=%.cpp)' $(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) -DSTRGEN -c -o $@ $< -alloc_func.o: $(SRC_DIR)/core/alloc_func.cpp endian_host.h $(SRC_DIR)/safeguards.h +alloc_func.o: $(SRC_DIR)/core/alloc_func.cpp $(SRC_DIR)/safeguards.h $(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.cpp=%.cpp)' $(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) -DSTRGEN -c -o $@ $< @@ -80,21 +74,11 @@ $(LANGS): %.lng: $(LANG_DIR)/%.txt $(STRGEN) lang/english.txt $(E) '$(STAGE) Compiling language $(*F)' $(Q)./$(STRGEN) $(STRGEN_FLAGS) -s $(LANG_DIR) -d $(LANG_OBJS_DIR) $< $(LANG_ERRORS) && cp $@ $(BIN_DIR)/lang || true # Do not fail all languages when one fails -# The targets to compile the endian-code - -endian_host.h: $(ENDIAN_CHECK) - $(E) '$(STAGE) Testing endianness for host' - $(Q)./$(ENDIAN_CHECK) > $@ - -$(ENDIAN_CHECK): $(SRC_DIR)/endian_check.cpp - $(E) '$(STAGE) Compiling and Linking $@' - $(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) $(LDFLAGS_BUILD) $< -o $@ - depend: clean: $(E) '$(STAGE) Cleaning up language files' - $(Q)rm -f strgen.o string.o alloc_func.o getoptdata.o table/strings.h $(STRGEN) $(LANGS) $(LANGS:%=$(BIN_DIR)/lang/%) lang/english.* $(ENDIAN_TARGETS) + $(Q)rm -f strgen_base.o strgen.o string.o alloc_func.o getoptdata.o table/strings.h $(STRGEN) $(LANGS) $(LANGS:%=$(BIN_DIR)/lang/%) lang/english.* mrproper: clean $(Q)rm -rf $(BIN_DIR)/lang diff --git a/Makefile.setting.in b/Makefile.setting.in index d89501d21b..1e2dc992f8 100644 --- a/Makefile.setting.in +++ b/Makefile.setting.in @@ -6,7 +6,6 @@ # 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 . SETTINGSGEN = !!SETTINGSGEN!! -ENDIAN_CHECK = !!ENDIAN_CHECK!! SRC_DIR = !!SRC_DIR!! CXX_BUILD = !!CXX_BUILD!! CFLAGS_BUILD = !!CFLAGS_BUILD!! @@ -15,8 +14,6 @@ LDFLAGS_BUILD = !!LDFLAGS_BUILD!! STAGE = !!STAGE!! SETTING_OBJS_DIR = !!SETTING_OBJS_DIR!! -ENDIAN_TARGETS := endian_host.h endian_target.h $(ENDIAN_CHECK) - # Check if we want to show what we are doing ifdef VERBOSE Q = @@ -32,7 +29,7 @@ settingsgen.o: $(SRC_DIR)/settingsgen/settingsgen.cpp $(SRC_DIR)/string_func.h $ $(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.cpp=%.cpp)' $(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) -DSETTINGSGEN -c -o $@ $< -alloc_func.o: $(SRC_DIR)/core/alloc_func.cpp endian_host.h $(SRC_DIR)/safeguards.h +alloc_func.o: $(SRC_DIR)/core/alloc_func.cpp $(SRC_DIR)/safeguards.h $(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.cpp=%.cpp)' $(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) -DSETTINGSGEN -c -o $@ $< @@ -40,7 +37,7 @@ getoptdata.o: $(SRC_DIR)/misc/getoptdata.cpp $(SRC_DIR)/misc/getoptdata.h $(SRC_ $(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/misc/%.cpp=%.cpp)' $(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) -DSETTINGSGEN -c -o $@ $< -string.o: $(SRC_DIR)/string.cpp endian_host.h $(SRC_DIR)/safeguards.h +string.o: $(SRC_DIR)/string.cpp $(SRC_DIR)/safeguards.h $(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.cpp=%.cpp)' $(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) -DSETTINGSGEN -c -o $@ $< @@ -57,21 +54,11 @@ table/settings.h: $(SETTINGSGEN) $(SRC_DIR)/table/settings.h.preamble $(SRC_DIR) @mkdir -p table $(Q)./$(SETTINGSGEN) -o table/settings.h -b $(SRC_DIR)/table/settings.h.preamble -a $(SRC_DIR)/table/settings.h.postamble $(SRC_DIR)/table/*.ini -# The targets to compile the endian-code - -endian_host.h: $(ENDIAN_CHECK) - $(E) '$(STAGE) Testing endianness for host' - $(Q)./$(ENDIAN_CHECK) > $@ - -$(ENDIAN_CHECK): $(SRC_DIR)/endian_check.cpp - $(E) '$(STAGE) Compiling and Linking $@' - $(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) $(LDFLAGS_BUILD) $< -o $@ - depend: clean: $(E) '$(STAGE) Cleaning up settings files' - $(Q)rm -f settingsgen.o alloc_func.o getoptdata.o ini_load.o $(SETTINGSGEN) $(ENDIAN_TARGETS) table/settings.h + $(Q)rm -f settingsgen.o alloc_func.o getoptdata.o string.o ini_load.o $(SETTINGSGEN) table/settings.h mrproper: clean diff --git a/Makefile.src.in b/Makefile.src.in index a2069a2b7b..0589ba69a6 100644 --- a/Makefile.src.in +++ b/Makefile.src.in @@ -29,9 +29,7 @@ SCRIPT_SRC_DIR = !!SCRIPT_SRC_DIR!! MEDIA_DIR = !!MEDIA_DIR!! TTD = !!TTD!! STRGEN = !!STRGEN!! -ENDIAN_CHECK = !!ENDIAN_CHECK!! DEPEND = !!DEPEND!! -ENDIAN_FORCE = !!ENDIAN_FORCE!! OS = !!OS!! STAGE = !!STAGE!! MAKEDEPEND = !!MAKEDEPEND!! @@ -40,7 +38,6 @@ SORT = !!SORT!! AWK = !!AWK!! CONFIG_CACHE_COMPILER = $(SRC_OBJS_DIR)/!!CONFIG_CACHE_COMPILER!! CONFIG_CACHE_LINKER = $(SRC_OBJS_DIR)/!!CONFIG_CACHE_LINKER!! -CONFIG_CACHE_ENDIAN = $(SRC_OBJS_DIR)/!!CONFIG_CACHE_ENDIAN!! CONFIG_CACHE_SOURCE = $(SRC_OBJS_DIR)/!!CONFIG_CACHE_SOURCE!! CONFIG_CACHE_VERSION = $(SRC_OBJS_DIR)/!!CONFIG_CACHE_VERSION!! @@ -52,19 +49,16 @@ OBJS := $(OBJS_C) $(OBJS_CPP) $(OBJS_MM) $(OBJS_RC) SRCS := !!SRCS!! # All C-files depend on those 3 files -FILE_DEP := $(CONFIG_CACHE_COMPILER) endian_target.h +FILE_DEP := $(CONFIG_CACHE_COMPILER) # Create all dirs and subdirs RES := $(shell mkdir -p $(BIN_DIR) $(sort $(dir $(OBJS)))) -# Make sure endian_target.h is reasable as if it was in the src/ dir CFLAGS += -I $(SRC_OBJS_DIR) -I $(LANG_OBJS_DIR) -I $(SETTING_OBJS_DIR) CFLAGS_MAKEDEP += -I $(SRC_OBJS_DIR) -I $(LANG_OBJS_DIR) -I $(SETTING_OBJS_DIR) ifdef SCRIPT_SRC_DIR CFLAGS_MAKEDEP += -I $(SCRIPT_SRC_DIR) endif -ENDIAN_TARGETS := endian_target.h $(ENDIAN_CHECK) - # Check if we want to show what we are doing ifdef VERBOSE Q = @@ -108,7 +102,6 @@ endif # This helps to recompile if flags change RES := $(shell if [ "`cat $(CONFIG_CACHE_COMPILER) 2>/dev/null`" != "$(CFLAGS) $(CXXFLAGS)" ]; then echo "$(CFLAGS) $(CXXFLAGS)" > $(CONFIG_CACHE_COMPILER); fi ) RES := $(shell if [ "`cat $(CONFIG_CACHE_LINKER) 2>/dev/null`" != "$(LDFLAGS) $(LIBS)" ]; then echo "$(LDFLAGS) $(LIBS)" > $(CONFIG_CACHE_LINKER); fi ) -RES := $(shell if [ "`cat $(CONFIG_CACHE_ENDIAN) 2>/dev/null`" != "$(ENDIAN_FORCE)" ]; then echo "$(ENDIAN_FORCE)" > $(CONFIG_CACHE_ENDIAN); fi ) # If there is a change in the source-file-list, make sure we recheck the deps RES := $(shell if [ "`cat $(CONFIG_CACHE_SOURCE) 2>/dev/null`" != "$(SRCS)" ]; then echo "$(SRCS)" > $(CONFIG_CACHE_SOURCE); fi ) @@ -121,7 +114,7 @@ DEP_MASK := %.d DEPS := $(OBJS:%.o=%.d) # Only include the deps if we are compiling everything -ifeq ($(filter $(ENDIAN_TARGETS) %.o clean mrproper, $(MAKECMDGOALS)),) +ifeq ($(filter %.o clean mrproper, $(MAKECMDGOALS)),) -include $(DEPS) else # In case we want to compile a single target, include the .d file for it @@ -155,7 +148,7 @@ DEP_MASK := DEPS := Makefile.dep # Only include the deps if we are not cleaning -ifeq ($(filter $(ENDIAN_TARGETS) depend clean mrproper, $(MAKECMDGOALS)),) +ifeq ($(filter depend clean mrproper, $(MAKECMDGOALS)),) -include Makefile.dep endif @@ -264,14 +257,7 @@ endif $(TTD): $(OBJS) $(CONFIG_CACHE_LINKER) $(E) '$(STAGE) Linking $@' -ifeq ($(OS), PSP) - # Because of a bug in the PSP GCC tools, linking via CXX results - # in total chaos and more problems then you can handle. So we need - # CC to link OpenTTD for PSP - $(Q)+$(CC_HOST) $(LDFLAGS) $(OBJS) $(LIBS) -o $@ -else $(Q)+$(CXX_HOST) $(LDFLAGS) $(OBJS) $(LIBS) -o $@ -endif ifdef STRIP $(Q)$(STRIP) $@ endif @@ -280,16 +266,6 @@ ifeq ($(OS), DOS) $(Q)$(ROOT_DIR)/os/dos/make_dos_binary_selfcontained.sh $(SRC_OBJS_DIR)/$@ endif -# The targets to compile the endian-code - -endian_target.h: $(ENDIAN_CHECK) $(CONFIG_CACHE_ENDIAN) - $(E) '$(STAGE) Testing endianness for target' - $(Q)./$(ENDIAN_CHECK) $(ENDIAN_FORCE) > $@ - -$(ENDIAN_CHECK): $(SRC_DIR)/endian_check.cpp - $(E) '$(STAGE) Compiling and Linking $@' - $(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $(CXXFLAGS_BUILD) $(LDFLAGS_BUILD) $< -o $@ - # Revision files $(SRC_DIR)/rev.cpp: $(CONFIG_CACHE_VERSION) $(SRC_DIR)/rev.cpp.in @@ -304,7 +280,7 @@ depend: $(DEPS) clean: $(E) '$(STAGE) Cleaning up object files' - $(Q)rm -f $(DEPS) $(OBJS) $(TTD) $(DEPEND) $(TTD:%=$(BIN_DIR)/%) $(BIN_DIR)/baseset/openttd.32.bmp $(CONFIG_CACHE_COMPILER) $(CONFIG_CACHE_LINKER) $(CONFIG_CACHE_ENDIAN) $(CONFIG_CACHE_SOURCE) $(ENDIAN_TARGETS) + $(Q)rm -f $(DEPS) $(OBJS) $(TTD) $(DEPEND) $(TTD:%=$(BIN_DIR)/%) $(BIN_DIR)/baseset/openttd.32.bmp $(CONFIG_CACHE_COMPILER) $(CONFIG_CACHE_LINKER) $(CONFIG_CACHE_SOURCE) mrproper: clean $(Q)rm -f $(SRC_DIR)/rev.cpp $(SRC_DIR)/os/windows/ottdres.rc diff --git a/README.md b/README.md index f8773ec25b..96d3e49f36 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ - 4.4) [Files in tar (archives)](#44-files-in-tar-archives) - 5.0) [OpenTTD features](#50-openttd-features) - 5.1) [Logging of potentially dangerous actions](#51-logging-of-potentially-dangerous-actions) + - 5.2) [Frame rate and performance metrics](#52-frame-rate-and-performance-metrics) - 6.0) [Configuration file](#60-configuration-file) - 7.0) [Compiling](#70-compiling) - 7.1) [Required/optional libraries](#71-requiredoptional-libraries) @@ -42,9 +43,10 @@ The easiest way to contact the OpenTTD team is by submitting bug reports or posting comments in our forums. You can also chat with us on IRC (#openttd on irc.oftc.net). -The OpenTTD homepage is [http://www.openttd.org/](http://www.openttd.org/). +The OpenTTD homepage is https://www.openttd.org. -You can also find the OpenTTD forums at [http://forum.openttd.org/](http://forum.openttd.org/). +You can also find the OpenTTD forums at +[https://www.tt-forums.net](https://www.tt-forums.net/viewforum.php?f=55). ### 2.1) Reporting bugs @@ -52,12 +54,12 @@ First of all, check whether the bug is not already known. Do this by looking through the file called 'known-bugs.txt' which is distributed with OpenTTD like this readme. -For tracking our bugs we are using Githubs issue tracker. You can find -the tracker at [https://github.com/OpenTTD/OpenTTD/issues](https://github.com/OpenTTD/OpenTTD/issues). Before actually reporting take a look -through the already reported bugs there to see if the bug is already known. -The 'known-bugs.txt' file might be a bit outdated at the moment you are -reading it as only bugs known before the release are documented there. Also -look through the recently closed bugs. +For tracking our bugs we are using GitHub's issue tracker. You can find +the tracker at https://github.com/OpenTTD/OpenTTD/issues. Before actually +reporting take a look through the already reported bugs there to see if +the bug is already known. The 'known-bugs.txt' file might be a bit outdated +at the moment you are reading it as only bugs known before the release +are documented there. Also look through the recently closed bugs. When you are sure it is not already reported you should: @@ -80,8 +82,8 @@ following information in your bug report: - Bug details, including instructions how to reproduce it - Platform (Windows, Linux, FreeBSD, …) and compiler (including version) if you compiled OpenTTD yourself. -- The processor architecture of your OS (32 bits Windows, 64 bits Windows, - Linux on an ARM, Mac OS X on a PowerPC, …) +- The processor architecture of your OS (32-bit Windows, 64-bit Windows, + Linux on an ARM, Mac OS X on a PowerPC, etc.) - Attach a saved game **and** a screenshot if possible - If this bug only occurred recently please note the last version without the bug and the first version including the bug. That way we can fix it @@ -154,7 +156,7 @@ platforms are: - DOS (Allegro) - FreeBSD (SDL) - Linux (SDL or Allegro) -- MacOS X (universal) (Cocoa video and sound drivers) +- macOS (universal) (Cocoa video and sound drivers) - MorphOS (SDL) - OpenBSD (SDL) - OS/2 (SDL) @@ -210,9 +212,9 @@ when using other versions of the game. The free data files, split into OpenGFX for graphics, OpenSFX for sounds and OpenMSX for music can be found at: -- [http://www.openttd.org/download-opengfx](http://www.openttd.org/download-opengfx) for OpenGFX -- [http://www.openttd.org/download-opensfx](http://www.openttd.org/download-opensfx) for OpenSFX -- [http://www.openttd.org/download-openmsx](http://www.openttd.org/download-openmsx) for OpenMSX +- https://www.openttd.org/download-opengfx for OpenGFX +- https://www.openttd.org/download-opensfx for OpenSFX +- https://www.openttd.org/download-openmsx for OpenMSX Please follow the readme of these packages about the installation procedure. The Windows installer can optionally download and install these packages. @@ -224,7 +226,6 @@ have to copy the data files from the CD-ROM into the baseset/ directory. It does not matter whether you copy them from the DOS or Windows version of Transport Tycoon Deluxe. The Windows install can optionally copy these files. You need to copy the following files: - - sample.cat - trg1r.grf or TRG1.GRF - trgcr.grf or TRGC.GRF @@ -234,11 +235,11 @@ You need to copy the following files: #### 4.1.3) Original Transport Tycoon Deluxe music -If you want the Transport Tycoon Deluxe music, copy the files from the gm/ -folder from the Windows version of Transport Tycoon Deluxe to the baseset -folder in your OpenTTD folder (also explained in the following sections). -The music from the DOS version as well as the original Transport Tycoon does -not work. +If you want the Transport Tycoon Deluxe music, copy the appropriate files from +the original game into the baseset folder. +- TTD for Windows: All files in the gm/ folder (gm_tt00.gm up to gm_tt21.gm) +- TTD for DOS: The GM.CAT file +- Transport Tycoon Original: The GM.CAT file, but rename it to GM-TTO.CAT #### 4.1.4) AIs @@ -247,10 +248,9 @@ not possible or you want to use an AI that has not been uploaded to the content download system download the tar file and place it in the ai/ directory. If the AI needs libraries you will have to download those too and put them in the ai/library/ directory. All AIs and AI Libraries that have been uploaded to -the content download system can be found at http://noai.openttd.org/downloads/ +the content download system can be found at https://noai.openttd.org/downloads. The AIs and libraries can be found their in the form of .tar.gz packages. -OpenTTD can read inside tar files but it does not extract .tar.gz files by -itself. +OpenTTD can read inside tar files but it does not extract .tar.gz files by itself. To figure out which libraries you need for an AI you have to start the AI and wait for an error message to pop up. The error message will tell you @@ -278,47 +278,50 @@ The main OpenTTD directories can be found in various locations, depending on your operating system: 1. The current working directory (from where you started OpenTTD) - For non-Windows operating systems OpenTTD will not scan for files in this - directory if it is your personal directory, i.e. '~/', or when it is the - root directory, i.e. '/'. + + For non-Windows operating systems OpenTTD will not scan for files in this + directory if it is your personal directory, i.e. '~/', or when it is the + root directory, i.e. '/'. + 2. Your personal directory - Windows: - `C:\My Documents\OpenTTD` (95, 98, ME) - `C:\Documents and Settings\\My Documents\OpenTTD` (2000, XP) - - `C:\Users\\Documents\OpenTTD` (Vista, 7) - - Mac OSX: `~/Documents/OpenTTD` + - `C:\Users\\Documents\OpenTTD` (Vista, 7, 8.1, 10) + - macOS: `~/Documents/OpenTTD` - Linux: `$XDG_DATA_HOME/openttd` which is usually `~/.local/share/openttd` - when built with XDG base directory support, otherwise `~/.openttd` + when built with XDG base directory support, otherwise `~/.openttd` 3. The shared directory - Windows: - `C:\Documents and Settings\All Users\Shared Documents\OpenTTD` (2000, XP) - - `C:\Users\Public\Documents\OpenTTD` (Vista, 7) - - Mac OSX: `/Library/Application Support/OpenTTD` + - `C:\Users\Public\Documents\OpenTTD` (Vista, 7, 8.1, 10) + - macOS: `/Library/Application Support/OpenTTD` - Linux: not available 4. The binary directory (where the OpenTTD executable is) - Windows: `C:\Program Files\OpenTTD` - Linux: `/usr/games` 5. The installation directory (Linux only) - Linux: `/usr/share/games/openttd` -6. The application bundle (Mac OSX only) - It includes the OpenTTD files (grf+lng) and it will work as long as they - are not touched +6. The application bundle (macOS only) + + It includes the OpenTTD files (grf+lng) and it will work as long as they + are not touched Different types of data or extensions go into different subdirectories of the chosen main OpenTTD directory: -| data type | directory | additional info | +| data type | directory | additional info | | --- | --- | --- | | Config File | (no subdirectory) | | | Screenshots | screenshot | | -| Base Graphics | baseset| (or a subdirectory thereof) | -| Sound Sets | baseset| (or a subdirectory thereof) | -| NewGRFs | newgrf| (or a subdirectory thereof) | -| 32bpp Sets | newgrf| (or a subdirectory thereof) | -| Music Sets | baseset| (or a subdirectory thereof) | -| AIs | ai| (or a subdirectory thereof) | -| AI Libraries | ai/library| (or a subdirectory thereof) | -| Game Scripts (GS) | game| (or a subdirectory thereof) | +| Base Graphics | baseset | (or a subdirectory thereof) | +| Sound Sets | baseset | (or a subdirectory thereof) | +| NewGRFs | newgrf | (or a subdirectory thereof) | +| 32bpp Sets | newgrf | (or a subdirectory thereof) | +| Music Sets | baseset | (or a subdirectory thereof) | +| AIs | ai | (or a subdirectory thereof) | +| AI Libraries | ai/library | (or a subdirectory thereof) | +| Game Scripts (GS) | game | (or a subdirectory thereof) | | GS Libraries | game/library | (or a subdirectory thereof) | | Savegames | save | | | Automatic Savegames | save/autosave | | @@ -330,16 +333,16 @@ use and no files should be added to it or its subdirectories manually. #### Notes: - Linux in the previous list means .deb, but most paths should be similar for - others. + others. - The previous search order is also used for NewGRFs and openttd.cfg. - If openttd.cfg is not found, then it will be created using the 2, 4, 1, 3, - 5 order. When built with XDG base directory support, openttd.cfg will be - created in $XDG_CONFIG_HOME/openttd which is usually ~/.config/openttd. + 5 order. When built with XDG base directory support, openttd.cfg will be + created in $XDG_CONFIG_HOME/openttd which is usually ~/.config/openttd. - Savegames will be relative to the config file only if there is no save/ - directory in paths with higher priority than the config file path, but - autosaves and screenshots will always be relative to the config file. - Unless the configuration file is in $XDG_CONFIG_HOME/openttd, then all - other files will be saved under $XDG_DATA_HOME/openttd. + directory in paths with higher priority than the config file path, but + autosaves and screenshots will always be relative to the config file. + Unless the configuration file is in $XDG_CONFIG_HOME/openttd, then all + other files will be saved under $XDG_DATA_HOME/openttd. #### The preferred setup: @@ -389,19 +392,18 @@ OpenTTD has a lot of features going beyond the original Transport Tycoon Deluxe emulation. Unfortunately, there is currently no comprehensive list of features, but there is a basic features list on the web, and some optional features can be controlled through the Advanced Settings dialog. We also implement some -features known from [TTDPatch](http://www.ttdpatch.net/). +features known from [TTDPatch](https://www.ttdpatch.net). Several important non-standard controls: - Ctrl modifies many commands and makes them more powerful. For example Ctrl - clicking on signals with the build signal tool changes their behaviour, holding - Ctrl while the track build tool is activated changes it to the track removal - tool, and so on. See [http://wiki.openttd.org/Hidden_features](http://wiki.openttd.org/Hidden_features) - for a non-comprehensive list or look at the tooltips. -- Ingame console. More information at - [http://wiki.openttd.org/index.php/Console](http://wiki.openttd.org/index.php/Console) + clicking on signals with the build signal tool changes their behaviour, + holding Ctrl while the track build tool is activated changes it to the track + removal tool, and so on. See https://wiki.openttd.org/Hidden_features + for a non-comprehensive list or look at the tooltips. +- Ingame console. More information at https://wiki.openttd.org/Console - Hovering over a GUI element shows tooltips. This can be changed to right click - via the advanced settings. + via the advanced settings. ### 5.1) Logging of potentially dangerous actions @@ -422,7 +424,7 @@ Information logged: - Changing NewGRF parameters, loading compatible NewGRF - Changing game mode (scenario editor <-> normal game) - Loading game saved in a different OpenTTD / TTDPatch / Transport Tycoon Deluxe / - original Transport Tycoon version + original Transport Tycoon version - Running a modified OpenTTD build - Changing settings affecting NewGRF behaviour (non-network-safe settings) - Triggering NewGRF bugs @@ -432,6 +434,70 @@ No personal information is stored. You can show the game log by typing 'gamelog' in the console or by running OpenTTD in debug mode. +### 5.2) Frame rate and performance metrics + +The Help menu in-game has a function to open the Frame rate window. This +window shows various real-time performance statistics, measuring what parts +of the game require the most processing power currently. + +A summary of the statistics can also be retrieved from the console with the +`fps` command. This is especially useful on dedicated servers, where the +administrator might want to determine what's limiting performance in a slow +game. + +The frame rate is given as two figures, the simulation rate and the graphics +frame rate. Usually these are identical, as the screen is rendered exactly +once per simulated tick, but in the future there might be support for graphics +and simulation running at different rates. When the game is paused, the +simulation rate drops to zero. + +In addition to the simulation rate, a game speed factor is also calculated. +This is based on the target simulation speed, which is 30 milliseconds per +game tick. At that speed, the expected frame rate is 33.33 frames/second, and +the game speed factor is how close to that target the actual rate is. When +the game is in fast forward mode, the game speed factor shows how much +speed up is achieved. + +The lower part of the window shows timing statistics for individual parts of +the game. The times shown are short-term and long-term averages of how long +it takes to process one tick of game time, all figures are in milliseconds. + +Clicking a line in the lower part of the window opens a graph window, giving +detailed readings on each tick simulated by the game. + +The following is an explanation of the different statistics: + +- *Game loop* - Total processing time used per simulated "tick" in the game. + This includes all pathfinding, world updates, and economy handling. +- *Cargo handling* - Time spent loading/unloading cargo at stations, and + industries and towns sending/retrieving cargo from stations. +- *Train ticks*, *Road vehicle ticks*, *Ship ticks*, *Aircraft ticks* - + Time spent on pathfinding and other processing for each player vehicle type. +- *World ticks* - Time spent on other world/landscape processing. This + includes towns growing, building animations, updates of farmland and trees, + and station rating updates. +- *Link graph delay* - Time overruns of the cargo distribution link graph + update thread. Usually the link graph is updated in a background thread, + but these updates need to synchronise with the main game loop occasionally, + if the time spent on link graph updates is longer than the time taken to + otherwise simulate the game while it was updating, these delays are counted + in this figure. +- *Graphics rendering* - Total time spent rendering all graphics, including + both GUI and world viewports. This typically spikes when panning the view + around, and when more things are happening on screen at once. +- *World viewport rendering* - Isolated time spent rendering just world + viewports. If this figure is significantly lower than the total graphics + rendering time, most time is spent rendering GUI than rendering world. +- *Video output* - Speed of copying the rendered graphics to the display + adapter. Usually this should be very fast (in the range of 0-3 ms), large + values for this can indicate a graphics driver problem. +- *Sound mixing* - Speed of mixing active audio samples together. Usually + this should be very fast (in the range of 0-3 ms), if it is slow, consider + switching to the NoSound set. + +If the frame rate window is shaded, the title bar will instead show just the +current simulation rate and the game speed factor. + ## 6.0) Configuration file The configuration file for OpenTTD (openttd.cfg) is in a simple Windows-like @@ -445,16 +511,15 @@ create one after closing. ### Windows: -You need Microsoft Visual Studio .NET. Open the project file +You need Microsoft Visual Studio 2015 Update 3 or more recent. Open the project file and it should build automatically. In case you want to build with SDL support you need to add WITH_SDL to the project settings. -PNG (WITH_PNG) and ZLIB (WITH_ZLIB) support is enabled by default. For these -to work you need their development files. For best results, download the -openttd-useful.zip file from [http://www.openttd.org/download-openttd-useful](http://www.openttd.org/download-openttd-useful) -Put the header files into your compiler's include/ directory and the -library (.lib) files into the lib/ directory. -For more help with VS see docs/Readme_Windows_MSVC.txt. +PNG (WITH_PNG), ZLIB (WITH_ZLIB), LZO (WITH_LZO), Freetype (WITH_FREETYPE) and +LZMA (WITH_LZMA) support is enabled by default. For these to work you need their +development files. To get them just use vcpkg from https://github.com/Microsoft/vcpkg +using x86-windows-static and x64-windows-static triplets. +For more help with VS see docs/Readme_Windows_MSVC.md. You can also build it using the Makefile with MSYS/MinGW or Cygwin/MinGW. Please read the Makefile for more information. @@ -468,7 +533,7 @@ Use '`gmake`', but do a '`./configure`' before the first build. OpenTTD can be built with GNU '`make`'. On non-GNU systems it is called '`gmake`'. However, for the first build one has to do a '`./configure`' first. -### MacOS X: +### macOS: Use '`make`' or Xcode (which will then call make for you) This will give you a binary for your CPU type (PPC/Intel) @@ -509,19 +574,19 @@ The following libraries are used by OpenTTD for: - libSDL/liballegro: hardware access (video, sound, mouse) - zlib: (de)compressing of old (0.3.0-1.0.5) savegames, content downloads, - heightmaps + heightmaps - liblzo2: (de)compressing of old (pre 0.3.0) savegames - liblzma: (de)compressing of savegames (1.1.0 and later) - libpng: making screenshots and loading heightmaps - libfreetype: loading generic fonts and rendering them - libfontconfig: searching for fonts, resolving font names to actual fonts - libicu: handling of right-to-left scripts (e.g. Arabic and Persian) and - natural sorting of strings. + natural sorting of strings. OpenTTD does not require any of the libraries to be present, but without liblzma you cannot open most recent savegames and without zlib you cannot open most older savegames or use the content downloading system. -Without libSDL/liballegro on non-Windows and non-MacOS X machines you have +Without libSDL/liballegro on non-Windows and non-macOS machines you have no graphical user interface; you would be building a dedicated server. ### 7.2) Supported compilers @@ -529,25 +594,25 @@ no graphical user interface; you would be building a dedicated server. The following compilers are known to compile OpenTTD: - Microsoft Visual C++ (MSVC) 2005, 2008 and 2010. - Version 2005 gives bogus warnings about scoping issues. + Version 2005 gives bogus warnings about scoping issues. - GNU Compiler Collection (GCC) 3.3 - 4.4, 4.6 - 4.8. - Versions 4.1 and earlier give bogus warnings about uninitialised variables. - Versions 4.4, 4.6 give bogus warnings about freeing non-heap objects. - Versions 4.6 and later give invalid warnings when lto is enabled. - Intel C++ Compiler (ICC) 12.0. - Clang/LLVM 2.9 - 3.0 - Version 2.9 gives bogus warnings about code nonconformity. + Version 2.9 gives bogus warnings about code nonconformity. The following compilers are known not to compile OpenTTD: - Microsoft Visual C++ (MSVC) 2003 and earlier. - GNU Compiler Collection (GCC) 3.2 and earlier. - These old versions fail due to OpenTTD's template usage. + These old versions fail due to OpenTTD's template usage. - GNU Compiler Collection (GCC) 4.5. It optimizes enums too aggressively. - See http://bugs.openttd.org/task/5513 and references therein. + See https://github.com/OpenTTD/OpenTTD/issues/5513 and references therein. - Intel C++ Compiler (ICC) 11.1 and earlier. - Version 10.0 and earlier fail a configure check and fail with recent - system headers. + system headers. - Version 10.1 fails to compile station_gui.cpp. - Version 11.1 fails with an internal error when compiling network.cpp. - Clang/LLVM 2.8 and earlier. @@ -560,7 +625,7 @@ Patches to support more compilers are welcome. To recompile the extra graphics needed to play with the original Transport Tycoon Deluxe graphics you need GRFCodec (which includes NFORenum) as well. -GRFCodec can be found at: [http://www.openttd.org/download-grfcodec](http://www.openttd.org/download-grfcodec) +GRFCodec can be found at https://www.openttd.org/download-grfcodec. The compilation of these extra graphics does generally not happen, unless you remove the graphics file using '`make maintainer-clean`'. @@ -573,17 +638,16 @@ modification of the base set files by the build process. ## 8.0) Translating -See [http://www.openttd.org/development](http://www.openttd.org/development) for up-to-date information. +See https://www.openttd.org/development for up-to-date information. The use of the online Translator service, located at -[http://translator.openttd.org/](http://translator.openttd.org/), is highly -encouraged. For getting an account simply follow the guidelines in the FAQ of -the translator website. +https://translator.openttd.org, is highly encouraged. For getting an account +simply follow the guidelines in the FAQ of the translator website. If for some reason the website is down for a longer period of time, the information below might be of help. -Please contact the translations manager ([http://www.openttd.org/contact](http://www.openttd.org/contact)) +Please contact the translations manager (https://www.openttd.org/contact) before beginning the translation process! This avoids double work, as someone else may have already started translating to the same language. @@ -602,8 +666,8 @@ Note: Do not alter the following parts of the file: - String identifiers (the first word on each line) - Parts of the strings which are in curly braces (such as {STRING}) -- Lines beginning with ## (such as ##id), other than the first two lines of - the file +- Lines beginning with ## (such as ##id), other than the first two lines + of the file ### 8.2) Previewing @@ -635,7 +699,7 @@ If the game is acting strange and you feel adventurous you can try the debugging output. The 'name' variable can help you to display only some type of debugging messages. This is mostly undocumented so best is to look in the source code file debug.c for the various debugging types. For more information -look at [http://wiki.openttd.org/index.php/Command_line](http://wiki.openttd.org/index.php/Command_line). +look at https://wiki.openttd.org/Command_line. The most frequent problem is missing data files. Please install OpenGFX and possibly OpenSFX and OpenMSX. See section 4.1.1 for more information. @@ -659,16 +723,16 @@ and add a suitable font for the small, medium and / or large font, e.g.: You should use a font name like 'Tahoma' or a path to the desired font. -Any NewGRF file used in a game is stored inside the savegame and will refuse -to load if you do not have that NewGRF file available. A list of missing files -can be viewed in the NewGRF window accessible from the file load dialogue window. +Any NewGRF file used in a game is stored inside the savegame and will refuse to +load if you do not have that NewGRF file available. A list of missing files can +be viewed in the NewGRF window accessible from the file load dialogue window. You can try to obtain the missing files from that NewGRF dialogue or – if they -are not available online – you can search manually through our [forum's graphics -development section](http://www.tt-forums.net/viewforum.php?f=66) or GrfCrawler -(http://grfcrawler.tt-forums.net/). Put the NewGRF files in OpenTTD's newgrf folder -(see section 4.2 'OpenTTD directories') and rescan the list of available NewGRFs. -Once you have all missing files, you are set to go. +are not available online – you can search manually through our +[forum's graphics development section](https://www.tt-forums.net/viewforum.php?f=66) +or [GRFCrawler](https://grfcrawler.tt-forums.net). Put the NewGRF files in +OpenTTD's newgrf folder (see section 4.2 'OpenTTD directories') and rescan the +list of available NewGRFs. Once you have all missing files, you are set to go. ## 10.0) Licensing @@ -697,8 +761,14 @@ os/dos/exe2coff/copying.dj for the exact licensing terms. The CWSDPMI implementation in os/dos/cwsdpmi is distributed under a custom binary-only license that prohibits modification. The exact licensing terms can be found in os/dos/cwsdpmi/cwsdpmi.txt. The sources -for these files can be downloaded at its author site, at: -[http://homer.rice.edu/~sandmann/cwsdpmi/csdpmi5s.zip](http://homer.rice.edu/~sandmann/cwsdpmi/csdpmi5s.zip) +for these files can be downloaded at its author site, at +http://homer.rice.edu/~sandmann/cwsdpmi/csdpmi5s.zip. + +CONTRIBUTING.md is adapted from +[Bootstrap](https://github.com/twbs/bootstrap/blob/master/CONTRIBUTING.md) +under the [Creative Commons Attribution 3.0 Unported +License](https://github.com/twbs/bootstrap/blob/master/docs/LICENSE) +terms for Bootstrap documentation. ## X.X) Credits @@ -711,6 +781,7 @@ for these files can be downloaded at its author site, at: - Christoph Elsenhans (frosch) - General coding (since 0.6) - Loïc Guilloux (glx) - Windows Expert (since 0.4.5) - Michael Lutz (michi_cc) - Path based signals (since 0.7) +- Niels Martin Hansen (nielsm) - Music system, general coding (since 1.9) - Owen Rudge (orudge) - Forum host, OS/2 port (since 0.1) - Peter Nelson (peter1138) - Spiritual descendant from newGRF gods (since 0.4.5) - Ingo von Borstel (planetmaker) - General coding, Support (since 1.1) @@ -721,7 +792,7 @@ for these files can be downloaded at its author site, at: ### Inactive Developers: - Jean-François Claeys (Belugas) - GUI, newindustries and more (0.4.5 - 1.0) -- Bjarni Corfitzen (Bjarni) - MacOSX port, coder and vehicles (0.3 - 0.7) +- Bjarni Corfitzen (Bjarni) - macOS port, coder and vehicles (0.3 - 0.7) - Victor Fischer (Celestar) - Programming everywhere you need him to (0.3 - 0.6) - Jaroslav Mazanec (KUDr) - YAPG (Yet Another Pathfinder God) ;) (0.4.5 - 0.6) - Jonathan Coome (Maedhros) - High priest of the NewGRF Temple (0.5 - 0.6) @@ -735,10 +806,10 @@ for these files can be downloaded at its author site, at: - Tamás Faragó (Darkvater) - Ex-Lead coder (0.3 - 0.5) - Dominik Scherer (dominik81) - Lead programmer, GUI expert (0.3 - 0.3) -- Emil Djupfeld (egladil) - MacOSX port (0.4 - 0.6) +- Emil Djupfeld (egladil) - macOS port (0.4 - 0.6) - Simon Sasburg (HackyKid) - Bug fixer (0.4 - 0.4.5) - Ludvig Strigeus (ludde) - Original author of OpenTTD, main coder (0.1 - 0.3) -- Cian Duffy (MYOB) - BeOS port / manual writing (0.1 - 0.3) +- Cian Duffy (MYOB) - BeOS port / manual writing (0.1 - 0.3) - Petr Baudiš (pasky) - Many patches, newgrf support, etc. (0.3 - 0.3) - Benedikt Brüggemeier (skidd13) - Bug fixer and code reworker (0.6 - 0.7) - Serge Paquet (vurlix) - 2nd contributor after ludde (0.1 - 0.3) @@ -760,4 +831,3 @@ for these files can be downloaded at its author site, at: - All Translators - For their support to make OpenTTD a truly international game - Bug Reporters - Thanks for all bug reports - Chris Sawyer - For an amazing game! - diff --git a/azure-pipelines-ci.yml b/azure-pipelines-ci.yml new file mode 100644 index 0000000000..e71ab60ea4 --- /dev/null +++ b/azure-pipelines-ci.yml @@ -0,0 +1,116 @@ +trigger: +- master +pr: +- master + +jobs: +- job: windows + displayName: 'Windows' + pool: + vmImage: 'VS2017-Win2016' + + strategy: + matrix: + Win32: + BuildPlatform: 'Win32' + Win64: + BuildPlatform: 'x64' + + steps: + # Rebase to origin/master for every PR. This means users don't have to + # rebase every time master changes. As long as the PR applies cleanly, we + # will validate it. + - script: | + git config user.email 'info@openttd.org' + git config user.name 'OpenTTD CI' + git rebase origin/master + displayName: 'Rebase to master' + - bash: | + set -ex + curl -L https://github.com/OpenTTD/OpenTTD-CF/releases/download/latest/windows-dependencies.zip > windows-dependencies.zip + unzip windows-dependencies.zip + rm -f windows-dependencies.zip + displayName: 'Download dependencies' + workingDirectory: $(Build.ArtifactStagingDirectory) + - script: $(Build.ArtifactStagingDirectory)\windows-dependencies\vcpkg.exe integrate install + displayName: 'Install dependencies' + - bash: | + set -ex + cd bin/baseset + curl -L https://binaries.openttd.org/extra/opengfx/0.5.2/opengfx-0.5.2-all.zip > opengfx-0.5.2-all.zip + unzip opengfx-0.5.2-all.zip + rm -f opengfx-0.5.2-all.zip + displayName: 'Install OpenGFX' + - task: VSBuild@1 + displayName: 'Build' + inputs: + solution: 'projects/openttd_vs141.sln' + platform: $(BuildPlatform) + configuration: Release + maximumCpuCount: true + - script: | + call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x86 + cd projects + call regression.bat + displayName: 'Test' + +- job: linux + displayName: 'Linux' + pool: + vmImage: 'ubuntu-16.04' + + strategy: + matrix: + commit-checker: {} + linux-amd64-clang-3.8: {} + linux-amd64-gcc-6: {} + linux-i386-gcc-6: {} + + steps: + # Rebase to origin/master for every PR. This means users don't have to + # rebase every time master changes. As long as the PR applies cleanly, we + # will validate it. + - script: | + git config user.email 'info@openttd.org' + git config user.name 'OpenTTD CI' + git rebase origin/master + displayName: 'Rebase to master' + - task: Docker@1 + displayName: 'Build and test' + inputs: + command: 'Run an image' + imageName: openttd/compile-farm-ci:$(Agent.JobName) + volumes: '$(Build.SourcesDirectory):$(Build.SourcesDirectory)' + workingDirectory: '$(Build.SourcesDirectory)' + runInBackground: false + +- job: macos + displayName: 'MacOS' + pool: + vmImage: 'macOS-10.13' + + steps: + # Rebase to origin/master for every PR. This means users don't have to + # rebase every time master changes. As long as the PR applies cleanly, we + # will validate it. + - script: | + git config user.email 'info@openttd.org' + git config user.name 'OpenTTD CI' + git rebase origin/master + displayName: 'Rebase to master' + - script: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config lzo xz libpng + displayName: 'Install dependencies' + - bash: | + set -ex + mkdir -p ~/Documents/OpenTTD/baseset + cd ~/Documents/OpenTTD/baseset + wget https://binaries.openttd.org/extra/opengfx/0.5.2/opengfx-0.5.2-all.zip + unzip opengfx-0.5.2-all.zip + rm -f opengfx-0.5.2-all.zip + displayName: 'Install OpenGFX' + - script: './configure PKG_CONFIG_PATH=/usr/local/lib/pkgconfig --enable-static' + displayName: 'Configure' + - script: 'make -j2' + displayName: 'Build' + - script: 'make regression' + displayName: 'Test' diff --git a/bin/ai/regression/run.vbs b/bin/ai/regression/run.vbs new file mode 100644 index 0000000000..88cea5c4eb --- /dev/null +++ b/bin/ai/regression/run.vbs @@ -0,0 +1,154 @@ +Option Explicit + +' $Id$ +' +' 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 . + +Dim FSO +Set FSO = CreateObject("Scripting.FileSystemObject") + +Function GetTestList() + Dim retests, i, tests, dir + Set retests = New RegExp + Set GetTestList = CreateObject("Scripting.Dictionary") + + retests.Pattern = "ai/regression/tst_*" + retests.Global = True + For i = 0 To WScript.Arguments.Count - 1 + Dim test + test = "ai/regression/tst_" & WScript.Arguments.Item(i) + If FSO.FolderExists(test) Then + retests.Pattern = test + Exit For + End If + Next + + For Each dir In FSO.GetFolder("ai/regression/").SubFolders + Dim name + name = "ai/regression/" & dir.Name + If retests.Test(name) Then + GetTestList.Add name, name + End If + Next +End Function + +Function GetParams() + GetParams = "-snull -mnull -vnull:ticks=30000" + If WScript.Arguments.Count = 0 Then Exit Function + If WScript.Arguments.Item(0) <> "-r" Then Exit Function + GetParams = "" +End Function + +Sub FilterFile(filename) + Dim lines, filter, file + + Set file = FSO.OpenTextFile(filename, 1) + If Not file.AtEndOfStream Then + lines = file.ReadAll + End If + file.Close + + Set filter = New RegExp + filter.Global = True + filter.Multiline = True + filter.Pattern = "0x(\(nil\)|0+)(x0)?" + lines = filter.Replace(lines, "0x00000000") + filter.Pattern = "^dbg: \[script\]" + lines = filter.Replace(lines, "") + filter.Pattern = "^ " + lines = filter.Replace(lines, "ERROR: ") + filter.Pattern = "ERROR: \[1\] \[P\] " + lines = filter.Replace(lines, "") + filter.Pattern = "^dbg: .*\r\n" + lines = filter.Replace(lines, "") + + Set file = FSO.OpenTextFile(filename, 2) + file.Write lines + file.Close +End Sub + +Function CompareFiles(filename1, filename2) + Dim file, lines1, lines2 + Set file = FSO.OpenTextFile(filename1, 1) + If Not file.AtEndOfStream Then + lines1 = file.ReadAll + End IF + file.Close + Set file = FSO.OpenTextFile(filename2, 1) + If Not file.AtEndOfStream Then + lines2 = file.ReadAll + End IF + file.Close + CompareFiles = (lines1 = lines2) +End Function + +Function RunTest(test, params, ret) + Dim WshShell, oExec, sav, command + Set WshShell = CreateObject("WScript.Shell") + + ' Make sure that only one info.nut is present for each test run. Otherwise openttd gets confused. + FSO.CopyFile "ai/regression/regression_info.nut", test & "/info.nut" + + sav = test & "/test.sav" + If Not FSO.FileExists(sav) Then + sav = "ai/regression/empty.sav" + End If + + command = ".\openttd -x -c ai/regression/regression.cfg " & params & " -g " & sav & " -d script=2 -d misc=9" + ' 2>&1 must be after >tmp.regression, else stderr is not redirected to the file + WshShell.Run "cmd /c " & command & " >tmp.regression 2>&1", 0, True + + FilterFile "tmp.regression" + + If CompareFiles(test & "/result.txt", "tmp.regression") Then + RunTest = "passed!" + Else + RunTest = "failed!" + ret = 1 + End If + + FSO.DeleteFile test & "/info.nut" +End Function + +On Error Resume Next +WScript.StdOut.WriteLine "" +If Err.Number <> 0 Then + WScript.Echo "This script must be started with cscript." + WScript.Quit 1 +End If +On Error Goto 0 + +If Not FSO.FileExists("ai/regression/run.vbs") Then + WScript.Echo "Make sure you are in the root of OpenTTD before starting this script." + WScript.Quit 1 +End If + +If FSO.FileExists("scripts/game_start.scr") Then + FSO.MoveFile "scripts/game_start.scr", "scripts/game_start.scr.regression" +End If + +Dim params, test, ret +params = GetParams() +ret = 0 + +For Each test in GetTestList() + WScript.StdOut.Write "Running " & test & "... " + WScript.StdOut.WriteLine RunTest(test, params, ret) +Next + +If FSO.FileExists("scripts/game_start.scr.regression") Then + FSO.MoveFile "scripts/game_start.scr.regression", "scripts/game_start.scr" +End If + +If WScript.Arguments.Count > 0 Then + If WScripts.Arguments.Items(0) = "-k" Then + WScript.Quit ret + End If +End If + +FSO.DeleteFile "tmp.regression" + +WScript.Quit ret diff --git a/bin/ai/regression/tst_regression/main.nut b/bin/ai/regression/tst_regression/main.nut index f575f53fff..d36db03da7 100644 --- a/bin/ai/regression/tst_regression/main.nut +++ b/bin/ai/regression/tst_regression/main.nut @@ -1018,7 +1018,36 @@ function Regression::Rail() print(" BuildRail(): " + AIRail.BuildRail(10002, 10003, 10006)); print(" HasTransportType(): " + AITile.HasTransportType(10005, AITile.TRANSPORT_RAIL)); print(" HasTransportType(): " + AITile.HasTransportType(10006, AITile.TRANSPORT_RAIL)); - print(" RemoveRail(): " + AIRail.RemoveRail(10005, 10004, 10001)); + print(" RemoveRail(): " + AIRail.RemoveRail(10006, 10005, 10002)); + print(" HasTransportType(): " + AITile.HasTransportType(10004, AITile.TRANSPORT_RAIL)); + print(" HasTransportType(): " + AITile.HasTransportType(10005, AITile.TRANSPORT_RAIL)); + print(" BuildRailTrack(): " + AIRail.BuildRailTrack(6200, AIRail.RAILTRACK_NE_SW)); + print(" RemoveRailTrack(): " + AIRail.RemoveRailTrack(6200, AIRail.RAILTRACK_NW_NE)); + print(" RemoveRailTrack(): " + AIRail.RemoveRailTrack(6200, AIRail.RAILTRACK_NE_SW)); + print(" BuildRail(): " + AIRail.BuildRail(6200, 6200 + 256, 6200 + (256 * 4))); + print(" HasTransportType(): " + AITile.HasTransportType(6200 + (256 * 3), AITile.TRANSPORT_RAIL)); + print(" HasTransportType(): " + AITile.HasTransportType(6200 + (256 * 4), AITile.TRANSPORT_RAIL)); + print(" RemoveRail(): " + AIRail.RemoveRail(6200 + (256 * 3), 6200 + (256 * 2), 6200 - 256)); + print(" HasTransportType(): " + AITile.HasTransportType(6200 + (256 * 3), AITile.TRANSPORT_RAIL)); + print(" HasTransportType(): " + AITile.HasTransportType(6200 + (256 * 4), AITile.TRANSPORT_RAIL)); + print(" BuildRailTrack(): " + AIRail.BuildRail(14706, 14705, 12907)); + print(" HasTransportType(): " + AITile.HasTransportType(13421, AITile.TRANSPORT_RAIL)); + print(" HasTransportType(): " + AITile.HasTransportType(14191, AITile.TRANSPORT_RAIL)); + print(" RemoveRail(): " + AIRail.RemoveRail(12907, 13163, 14706)); + print(" HasTransportType(): " + AITile.HasTransportType(13421, AITile.TRANSPORT_RAIL)); + print(" HasTransportType(): " + AITile.HasTransportType(14191, AITile.TRANSPORT_RAIL)); + print(" BuildRailTrack(): " + AIRail.BuildRailTrack(61533, AIRail.RAILTRACK_NW_SW)); + print(" BuildRailTrack(): " + AIRail.BuildRailTrack(61533, AIRail.RAILTRACK_NE_SE)); + print(" BuildRailTrack(): " + AIRail.BuildRailTrack(61533, AIRail.RAILTRACK_NW_NE)); + print(" BuildRailTrack(): " + AIRail.BuildRailTrack(61533, AIRail.RAILTRACK_SW_SE)); + print(" BuildRailTrack(): " + AIRail.BuildRailTrack(61533, AIRail.RAILTRACK_NE_SW)); + print(" DemolishTile(): " + AITile.DemolishTile(61533)); + print(" BuildRailTrack(): " + AIRail.BuildRailTrack(61533, AIRail.RAILTRACK_NE_SW)); + print(" BuildRailTrack(): " + AIRail.BuildRailTrack(61533, AIRail.RAILTRACK_NW_SE)); + print(" BuildRailTrack(): " + AIRail.BuildRailTrack(61533, AIRail.RAILTRACK_NW_NE)); + print(" BuildRailTrack(): " + AIRail.BuildRailTrack(61533, AIRail.RAILTRACK_SW_SE)); + print(" DemolishTile(): " + AITile.DemolishTile(61533)); + print(" BuildRailTrack(): " + AIRail.BuildRailTrack(61533, AIRail.RAILTRACK_NW_SE)); print(" Depot"); print(" IsRailTile(): " + AIRail.IsRailTile(33411)); @@ -1053,6 +1082,31 @@ function Regression::Rail() print(" IsRailStationTile(): " + AIRail.IsRailStationTile(7957)); print(" IsRailStationTile(): " + AIRail.IsRailStationTile(7958)); print(" IsRailStationTile(): " + AIRail.IsRailStationTile(7959)); + + print(" Waypoint"); + print(" BuildRailTrack(): " + AIRail.BuildRailTrack(12646, AIRail.RAILTRACK_NW_SE)); + print(" BuildRailTrack(): " + AIRail.BuildRailTrack(12648, AIRail.RAILTRACK_NE_SW)); + print(" BuildRailTrack(): " + AIRail.BuildRailTrack(12650, AIRail.RAILTRACK_NW_NE)); + print(" BuildRailWaypoint(): " + AIRail.BuildRailWaypoint(12644)); + print(" BuildRailWaypoint(): " + AIRail.BuildRailWaypoint(12646)); + print(" BuildRailWaypoint(): " + AIRail.BuildRailWaypoint(12648)); + print(" BuildRailWaypoint(): " + AIRail.BuildRailWaypoint(12650)); + print(" IsRailWaypointTile(): " + AIRail.IsRailWaypointTile(12644)); + print(" IsRailWaypointTile(): " + AIRail.IsRailWaypointTile(12646)); + print(" IsRailWaypointTile(): " + AIRail.IsRailWaypointTile(12648)); + print(" IsRailWaypointTile(): " + AIRail.IsRailWaypointTile(12650)); + print(" RemoveRailWaypointTileRectangle():" + AIRail.RemoveRailWaypointTileRectangle(12644, 12646, false)); + print(" RemoveRailWaypointTileRectangle():" + AIRail.RemoveRailWaypointTileRectangle(12648, 12650, true)); + print(" IsRailWaypointTile(): " + AIRail.IsRailWaypointTile(12644)); + print(" IsRailWaypointTile(): " + AIRail.IsRailWaypointTile(12646)); + print(" IsRailWaypointTile(): " + AIRail.IsRailWaypointTile(12648)); + print(" IsRailWaypointTile(): " + AIRail.IsRailWaypointTile(12650)); + print(" HasTransportType(): " + AITile.HasTransportType(12644, AITile.TRANSPORT_RAIL)); + print(" HasTransportType(): " + AITile.HasTransportType(12646, AITile.TRANSPORT_RAIL)); + print(" HasTransportType(): " + AITile.HasTransportType(12648, AITile.TRANSPORT_RAIL)); + print(" HasTransportType(): " + AITile.HasTransportType(12650, AITile.TRANSPORT_RAIL)); + print(" DemolishTile(): " + AITile.DemolishTile(12648)); + print(" DemolishTile(): " + AITile.DemolishTile(12650)); } function Regression::Road() @@ -1441,7 +1495,7 @@ function Regression::TileList() print(" " + i + " => " + list.GetValue(i)); } - list = AITileList_StationType(4, AIStation.STATION_BUS_STOP); + list = AITileList_StationType(6, AIStation.STATION_BUS_STOP); print(""); print("--TileList_StationType--"); print(" Count(): " + list.Count()); diff --git a/bin/ai/regression/tst_regression/result.txt b/bin/ai/regression/tst_regression/result.txt index c909e79322..210cf2696a 100644 --- a/bin/ai/regression/tst_regression/result.txt +++ b/bin/ai/regression/tst_regression/result.txt @@ -1292,7 +1292,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetRunningCost(): 820 GetPower(): 300 GetWeight(): 47 - GetMaxTractiveEffort(): 139 + GetMaxTractiveEffort(): 136 GetVehicleType(): 0 GetRailType(): 0 GetRoadType(): -1 @@ -1436,7 +1436,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetRunningCost(): 1968 GetPower(): 1000 GetWeight(): 131 - GetMaxTractiveEffort(): 388 + GetMaxTractiveEffort(): 381 GetVehicleType(): 0 GetRailType(): 0 GetRoadType(): -1 @@ -1454,7 +1454,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetRunningCost(): 2296 GetPower(): 1200 GetWeight(): 162 - GetMaxTractiveEffort(): 480 + GetMaxTractiveEffort(): 471 GetVehicleType(): 0 GetRailType(): 0 GetRoadType(): -1 @@ -7253,7 +7253,7 @@ ERROR: IsEnd() is invalid as Begin() is never called IsBuoyTile(): false IsLockTile(): false IsCanalTile(): false - GetBankBalance(): 479851 + GetBankBalance(): 479664 BuildWaterDepot(): true BuildDock(): true BuildBuoy(): true @@ -7266,7 +7266,7 @@ ERROR: IsEnd() is invalid as Begin() is never called IsBuoyTile(): true IsLockTile(): true IsCanalTile(): true - GetBankBalance(): 465257 + GetBankBalance(): 465070 --AIWaypointList(BUOY)-- Count(): 1 @@ -7285,7 +7285,7 @@ ERROR: IsEnd() is invalid as Begin() is never called IsBuoyTile(): false IsLockTile(): false IsCanalTile(): false - GetBankBalance(): 459862 + GetBankBalance(): 459675 BuildWaterDepot(): true BuildDock(): true @@ -7334,6 +7334,35 @@ ERROR: IsEnd() is invalid as Begin() is never called HasTransportType(): true HasTransportType(): false RemoveRail(): true + HasTransportType(): false + HasTransportType(): false + BuildRailTrack(): true + RemoveRailTrack(): false + RemoveRailTrack(): true + BuildRail(): true + HasTransportType(): true + HasTransportType(): false + RemoveRail(): true + HasTransportType(): true + HasTransportType(): false + BuildRailTrack(): true + HasTransportType(): true + HasTransportType(): true + RemoveRail(): true + HasTransportType(): false + HasTransportType(): false + BuildRailTrack(): false + BuildRailTrack(): false + BuildRailTrack(): true + BuildRailTrack(): true + BuildRailTrack(): false + DemolishTile(): true + BuildRailTrack(): true + BuildRailTrack(): false + BuildRailTrack(): false + BuildRailTrack(): false + DemolishTile(): true + BuildRailTrack(): true Depot IsRailTile(): false BuildRailDepot(): false @@ -7362,6 +7391,30 @@ ERROR: IsEnd() is invalid as Begin() is never called IsRailStationTile(): false IsRailStationTile(): false IsRailStationTile(): false + Waypoint + BuildRailTrack(): true + BuildRailTrack(): true + BuildRailTrack(): true + BuildRailWaypoint(): false + BuildRailWaypoint(): true + BuildRailWaypoint(): true + BuildRailWaypoint(): false + IsRailWaypointTile(): false + IsRailWaypointTile(): true + IsRailWaypointTile(): true + IsRailWaypointTile(): false + RemoveRailWaypointTileRectangle():true + RemoveRailWaypointTileRectangle():true + IsRailWaypointTile(): false + IsRailWaypointTile(): false + IsRailWaypointTile(): false + IsRailWaypointTile(): false + HasTransportType(): false + HasTransportType(): false + HasTransportType(): true + HasTransportType(): true + DemolishTile(): true + DemolishTile(): true --RailTypeList-- Count(): 1 @@ -7485,9 +7538,9 @@ ERROR: IsEnd() is invalid as Begin() is never called GetName(0): Look, a station GetLocation(1): 29253 GetLocation(1000): -1 - GetStationID(33411): 4 + GetStationID(33411): 6 GetStationID(34411): 65535 - GetStationID(33411): 4 + GetStationID(33411): 6 HasRoadType(3, TRAM): false HasRoadType(3, ROAD): false HasRoadType(33411, TRAM): false diff --git a/bin/baseset/orig_dos.obm b/bin/baseset/orig_dos.obm new file mode 100644 index 0000000000..cdacc8e7f5 --- /dev/null +++ b/bin/baseset/orig_dos.obm @@ -0,0 +1,76 @@ +; $Id$ +; +; This represents the original music as on the Transport +; Tycoon Deluxe for DOS CD. +; +[metadata] +name = original_dos +shortname = TTDD +version = 1 +description = Original Transport Tycoon Deluxe DOS edition music. + +[files] +theme = gm.cat +old_0 = gm.cat +old_1 = gm.cat +old_2 = gm.cat +old_3 = gm.cat +old_4 = gm.cat +old_5 = gm.cat +old_6 = gm.cat +old_7 = gm.cat +old_8 = +old_9 = +new_0 = gm.cat +new_1 = gm.cat +new_2 = gm.cat +new_3 = gm.cat +new_4 = gm.cat +new_5 = gm.cat +new_6 = gm.cat +new_7 = +new_8 = +new_9 = +ezy_0 = gm.cat +ezy_1 = gm.cat +ezy_2 = gm.cat +ezy_3 = gm.cat +ezy_4 = gm.cat +ezy_5 = gm.cat +ezy_6 = +ezy_7 = +ezy_8 = +ezy_9 = + +[md5s] +gm.cat = 7a29d2d0c4f7d2e03091ffa9b2bdfffb + +[catindex] +theme = 0 +old_0 = 1 +old_1 = 8 +old_2 = 2 +old_3 = 9 +old_4 = 14 +old_5 = 15 +old_6 = 19 +old_7 = 13 +new_0 = 6 +new_1 = 11 +new_2 = 10 +new_3 = 17 +new_4 = 21 +new_5 = 18 +new_6 = 5 +ezy_0 = 12 +ezy_1 = 7 +ezy_2 = 16 +ezy_3 = 3 +ezy_4 = 20 +ezy_5 = 4 + +[names] +; Names get read from the CAT file + +[origin] +default = You can find it on your Transport Tycoon Deluxe CD-ROM. diff --git a/bin/baseset/orig_tto.obm b/bin/baseset/orig_tto.obm new file mode 100644 index 0000000000..13b3efb110 --- /dev/null +++ b/bin/baseset/orig_tto.obm @@ -0,0 +1,71 @@ +; $Id$ +; +; This represents the original music as on the Transport +; Tycoon (with World Editor) for DOS CD. +; +[metadata] +name = original_tto +shortname = TTOD +version = 1 +description = Original Transport Tycoon (Original/World Editor) music. + +[files] +theme = gm-tto.cat +old_0 = gm-tto.cat +old_1 = gm-tto.cat +old_2 = gm-tto.cat +old_3 = gm-tto.cat +old_4 = gm-tto.cat +old_5 = gm-tto.cat +old_6 = gm-tto.cat +old_7 = gm-tto.cat +old_8 = +old_9 = +new_0 = gm-tto.cat +new_1 = gm-tto.cat +new_2 = gm-tto.cat +new_3 = gm-tto.cat +new_4 = gm-tto.cat +new_5 = gm-tto.cat +new_6 = gm-tto.cat +new_7 = gm-tto.cat +new_8 = +new_9 = +ezy_0 = +ezy_1 = +ezy_2 = +ezy_3 = +ezy_4 = +ezy_5 = +ezy_6 = +ezy_7 = +ezy_8 = +ezy_9 = + +[catindex] +theme = 0 +old_0 = 1 +old_1 = 6 +old_2 = 2 +old_3 = 7 +old_4 = 11 +old_5 = 12 +old_6 = 15 +old_7 = 10 +new_0 = 4 +new_1 = 5 +new_2 = 9 +new_3 = 8 +new_4 = 13 +new_5 = 16 +new_6 = 14 +new_7 = 3 + +[md5s] +gm-tto.cat = 26e85ff84b0063aa5da05dd4698fc76e + +[names] +; Names get read from the CAT file + +[origin] +default = You can find it on your Transport Tycoon CD-ROM. diff --git a/bin/baseset/orig_win.obm b/bin/baseset/orig_win.obm index 8e2053e043..c8c4923e0e 100644 --- a/bin/baseset/orig_win.obm +++ b/bin/baseset/orig_win.obm @@ -142,5 +142,17 @@ GM_TT19.GM = Funk Central GM_TT20.GM = Jammit GM_TT21.GM = Movin' On +; MIDI timecodes where the playback should attemp to start and stop short. +; This is to allow fixing undesired silences in original MIDI files. +; However not all music drivers may support this. +[timingtrim] +; Theme has two beats silence at the beginning which prevents clean looping. +GM_TT00.GM = 768:53760 +; Can't Get There From Here from the Windows version has a long silence at the end, +; followed by a solo repeat. This isn't in the original DOS version music and is likely +; unintentional from the people who converted the music from the DOS version. +; Actual song ends after measure 152. +GM_TT10.GM = 0:235008 + [origin] default = You can find it on your Transport Tycoon Deluxe CD-ROM. diff --git a/changelog.txt b/changelog.txt index 8edba15fb4..5e1540a1e0 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,44 @@ +1.8.0 (2018-04-01) +------------------------------------------------------------------------ +(None) + + +1.8.0-RC1 (2018-03-21) +------------------------------------------------------------------------ +- Feature: [GFX] Climate-specific Action5 extra airport sprites [FS#6664] (r27976) +- Feature: Draw vertical separators at tile distance in the train depot GUI (r27938, r27899) +- Feature: [Build] MSVC 2017 project file generator. Most noticeable, std:c++latest is enabled (r27920, r27919, r27918, r27917) +- Feature: [Build] Project file generator for kdevelop 4/5 [FS#6577] (r27897) +- Feature: Add option to close windows with right click [FS#4950] (r27826, r27825) +- Feature: Vehicle Group Info: Add profits and occupancy display to group vehicle list (r27822) +- Feature: Display aircraft type in vehicle preview/purchase/detail windows (r27802, r27799, r27797) +- Change: [NewGRF] Various performance improvements to resolving VA2 (r27989, r27985, r27984, r27983, r27982) +- Change: [NewGRF] Increase maximum allowed vehicle sprite size to reduce clipping of ships (r27987) +- Change: Check companies for bankruptcy before subtracting reoccuring monthly costs [FS#6679] (r27981) +- Change: [GFX] Replace the office building sprite on various toyland airports with a better fitting sprite [FS#6664] (r27977) +- Change: [GFX] The switch-toolbar icon contained pixels from the fire cycle. Replace the whole icon with a new version [FS#6654] (r27961) +- Change: Reword texts in industry view, when stockpiling is used (r27952) +- Change: Remove the gap between windows when positioning them after opening [FS#6568] (r27934, r27900) +- Change: [Build] Enable usage of static_assert for MSVC (r27916) +- Change: [Build] Preserve PKG_CONFIG_PATH and PKG_CONFIG_LIBDIR environment variables in config.cache file [FS#6614] (r27902) +- Change: Do not cancel headquarter construction and engine-preview-query when shift-clicking (r27889) +- Change: Parse extmidi command string for parameters to pass on (r27834) +- Change: Draw images in centre of buttons (r27829, r27821) +- Fix: Store the map variety setting in the savegame like the other mapgen settings, so restarting maps considers it [FS#6673] (r27978) +- Fix: Hair selection was missing one option [FS#6642] (r27975) +- Fix: Avoid tile operations outside map border when building lock [FS#6662] (r27973) +- Fix: Catenary sprites got mixed up for depots [FS#6670] (r27972) +- Fix: Make automatic window-positioning RTL-aware (r27934, r27900) +- Fix: Automatic window-positioning now uses GUI-scale/style dependent sizes/distances instead of fixed pixel values (r27934, r27900) +- Fix: [NewGRF] While executing random triggers, var 5F should include the new triggers (r27928) +- Fix: [NewGRF] Reset used random triggers only after all A123 chains have been resolved, so that all RA2 in all chains can test the shared triggers (r27928) +- Fix: [NewGRF] Industry random triggers are stored per tile, even when randomising the shared random bits of the parent industry (r27928) +- Fix: [NPF] Reserved track bits were not accounted for when trying to find any safe position (r27912) +- Fix: Do not modify argv[0] [FS#6575] (r27886) +- Fix: Do not search directories when opening ini files as we already have their full path [FS#6421] (r27816) +- Fix: Road tunnel/bridge heads have no trackbits wrt. catenary drawing (r27812) + + 1.7.2 (2017-12-24) ------------------------------------------------------------------------ (None) diff --git a/config.lib b/config.lib index 4dde23b457..5b399d86a3 100644 --- a/config.lib +++ b/config.lib @@ -31,7 +31,6 @@ set_default() { awk="awk" pkg_config="pkg-config" os="DETECT" - endian="AUTO" cpu_type="DETECT" config_log="config.log" prefix_dir="/usr/local" @@ -78,17 +77,19 @@ set_default() { enable_builtin_depend="1" with_makedepend="0" with_direct_music="1" + with_xaudio2="1" with_sort="1" with_iconv="1" with_midi="" with_midi_arg="" with_libtimidity="1" + with_fluidsynth="1" with_freetype="1" with_fontconfig="1" with_icu_layout="1" with_icu_sort="1" static_icu="0" - with_psp_config="1" + with_uniscribe="1" with_threads="1" with_distcc="1" with_ccache="1" @@ -109,7 +110,6 @@ set_default() { awk pkg_config os - endian cpu_type config_log prefix_dir @@ -155,17 +155,19 @@ set_default() { enable_builtin_depend with_makedepend with_direct_music + with_xaudio2 with_sort with_iconv with_midi with_midi_arg with_libtimidity + with_fluidsynth with_freetype with_fontconfig with_icu_layout with_icu_sort static_icu - with_psp_config + with_uniscribe with_threads with_distcc with_ccache @@ -224,9 +226,6 @@ detect_params() { --lipo) prev_p="lipo";; --lipo=*) lipo="$optarg";; - --endian) prev_p="endian";; - --endian=*) endian="$optarg";; - # Alias --prefix with --prefix-dir, for compatibility with GNU autotools @@ -375,6 +374,9 @@ detect_params() { --without-libtimidity) with_libtimidity="0";; --with-libtimidity=*) with_libtimidity="$optarg";; + --with-fluidsynth) with_fluidsynth="2";; + --without-fluidsynth) with_fluidsynth="0";; + --with-freetype) with_freetype="2";; --without-freetype) with_freetype="0";; --with-freetype=*) with_freetype="$optarg";; @@ -406,9 +408,9 @@ detect_params() { --static-libicu) static_icu="1";; --static-libicu=*) static_icu="$optarg";; - --with-psp-config) with_psp_config="2";; - --without-psp-config) with_psp_config="0";; - --with-psp-config=*) with_psp_config="$optarg";; + --with-uniscribe) with_uniscribe="2";; + --without-uniscribe) with_uniscribe="0";; + --with-uniscribe=*) with_uniscribe="$optarg";; --disable-builtin-depend) enable_builtin_depend="0";; --enable-builtin-depend) enable_builtin_depend="2";; @@ -422,6 +424,10 @@ detect_params() { --without-direct-music) with_direct_music="0";; --with-direct-music=*) with_direct_music="$optarg";; + --with-xaudio2) with_xaudio2="2";; + --without-xaudio2) with_xaudio2="0";; + --with-xaudio2=*) with_xaudio2="$optarg";; + --with-sort) with_sort="2";; --without-sort) with_sort="0";; --with-sort=*) with_sort="$optarg";; @@ -537,7 +543,6 @@ check_params() { # Some params want to be in full uppercase, else they might not work as # expected.. fix that here - endian=`echo $endian | tr '[a-z]' '[A-Z]'` os=`echo $os | tr '[a-z]' '[A-Z]'` cpu_type=`echo $cpu_type | tr '[a-z]' '[A-Z]'` @@ -553,21 +558,10 @@ check_params() { # Check if all params have valid values - # Endian only allows AUTO, LE and, BE - if [ -z "`echo $endian | egrep '^(AUTO|LE|BE|PREPROCESSOR)$'`" ]; then - log 1 "configure: error: invalid option --endian=$endian" - log 1 " Available options are: --endian=[AUTO|LE|BE]" - exit 1 - fi - if [ "$endian" = "PREPROCESSOR" ] && [ "$os" != "OSX" ]; then - log 1 "configure: error: invalid option --endian=$endian" - log 1 " PREPROCESSOR is only available for OSX" - exit 1 - fi - # OS only allows DETECT, UNIX, OSX, FREEBSD, DRAGONFLY, OPENBSD, NETBSD, MORPHOS, BEOS, HAIKU, SUNOS, CYGWIN, MINGW, OS2, DOS, WINCE, and PSP - if [ -z "`echo $os | egrep '^(DETECT|UNIX|OSX|FREEBSD|DRAGONFLY|OPENBSD|NETBSD|HPUX|MORPHOS|BEOS|HAIKU|SUNOS|CYGWIN|MINGW|OS2|DOS|WINCE|PSP)$'`" ]; then + # OS only allows DETECT, UNIX, OSX, FREEBSD, DRAGONFLY, OPENBSD, NETBSD, MORPHOS, BEOS, HAIKU, SUNOS, CYGWIN, MINGW, OS2, and DOS + if [ -z "`echo $os | egrep '^(DETECT|UNIX|OSX|FREEBSD|DRAGONFLY|OPENBSD|NETBSD|HPUX|MORPHOS|BEOS|HAIKU|SUNOS|CYGWIN|MINGW|OS2|DOS)$'`" ]; then log 1 "configure: error: invalid option --os=$os" - log 1 " Available options are: --os=[DETECT|UNIX|OSX|FREEBSD|DRAGONFLY|OPENBSD|NETBSD|HPUX|MORPHOS|BEOS|HAIKU|SUNOS|CYGWIN|MINGW|OS2|DOS|WINCE|PSP]" + log 1 " Available options are: --os=[DETECT|UNIX|OSX|FREEBSD|DRAGONFLY|OPENBSD|NETBSD|HPUX|MORPHOS|BEOS|HAIKU|SUNOS|CYGWIN|MINGW|OS2|DOS]" exit 1 fi # cpu_type can be either 32 or 64 @@ -766,13 +760,13 @@ check_params() { exit 1 fi else - if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ] || [ "$os" = "WINCE" ]; then + if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ]; then log 1 "checking GDI video driver... found" else log 1 "checking GDI video driver... not Windows, skipping" fi - if [ -z "$allegro_config" ] && [ -z "$sdl_config" ] && [ "$with_cocoa" = 0 ] && [ "$os" != "MINGW" ] && [ "$os" != "CYGWIN" ] && [ "$os" != "WINCE" ]; then + if [ -z "$allegro_config" ] && [ -z "$sdl_config" ] && [ "$with_cocoa" = 0 ] && [ "$os" != "MINGW" ] && [ "$os" != "CYGWIN" ]; then log 1 "configure: error: no video driver development files found" log 1 " If you want a dedicated server use --enable-dedicated as parameter" exit 1 @@ -872,14 +866,36 @@ check_params() { fi fi + if [ "$with_uniscribe" != "0" ]; then + if [ "$os" != "MINGW" ]; then + if [ "$with_uniscribe" != "1" ]; then + log 1 "configure: error: Uniscribe is only supported on native Win32 targets" + exit 1 + fi + with_uniscribe="0" + + log 1 "checking Uniscribe text layout... not Windows, skipping" + else + log 1 "checking Uniscribe text layout... found" + + # Don't use ICU unless forced. + if [ "$with_icu_layout" = "1" ]; then + with_icu_layout="0" + fi + if [ "$with_icu_sort" = "1" ]; then + with_icu_sort="0" + fi + fi + fi + detect_xdg_basedir detect_png detect_freetype detect_fontconfig detect_icu_layout detect_icu_sort - detect_pspconfig detect_libtimidity + detect_fluidsynth if [ "$with_direct_music" != "0" ]; then if [ "$os" != "MINGW" ] && [ "$os" != "CYGWIN" ]; then @@ -895,13 +911,21 @@ check_params() { fi fi - detect_sort + if [ "$with_xaudio2" != "0" ]; then + if [ "$os" != "MINGW" ] && [ "$os" != "CYGWIN" ]; then + if [ "$with_xaudio2" != "1" ]; then + log 1 "configure: error: xaudio2 is only supported on Win32 targets" + exit 1 + fi + with_xaudio2="0" - if [ "$os" = "OSX" ] && [ "$endian" = "AUTO" ]; then - endian="PREPROCESSOR" + log 1 "checking xaudio2... not Windows, skipping" + else + check_xaudio2 + fi fi - log 1 "checking endianness... $endian" + detect_sort # Suppress language errors when there is a version defined, indicating a release # It just isn't pretty if any release produces warnings in the languages. @@ -1113,7 +1137,7 @@ check_params() { fi if [ "$personal_dir" = "1" ]; then - if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ] || [ "$os" = "WINCE" ] || [ "$os" = "DOS" ] || [ "$os" = "HAIKU" ]; then + if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ] || [ "$os" = "DOS" ] || [ "$os" = "HAIKU" ]; then personal_dir="OpenTTD" elif [ "$os" = "OSX" ]; then personal_dir="Documents/OpenTTD" @@ -1211,14 +1235,14 @@ make_compiler_cflags() { # $5 - name of the features variable # Get the compiler to tell us who it is - compiler="`$1 --version | head -n1 | cut -d' ' -f1`" + version_line="`$1 --version | head -n1`" eval eval "flags=\\\$$2" eval eval "cxxflags=\\\$$3" eval eval "ldflags=\\\$$4" eval eval "features=\\\$$5" - if [ "$compiler" = "icc" ]; then + if [ `echo "$version_line" | cut -d' ' -f1` = "icc" ]; then # Enable some things only for certain ICC versions cc_version=`$1 -dumpversion | cut -c 1-4 | sed s@\\\.@@g` @@ -1293,8 +1317,6 @@ make_compiler_cflags() { if [ $cc_version -ge 110 ]; then # remark #2259: non-pointer conversion from ... to ... may lose significant bits flags="$flags -wd2259" - # Use c++0x mode so static_assert() is available - cxxflags="$cxxflags -std=c++11" fi if [ $cc_version -lt 140 ]; then @@ -1310,9 +1332,10 @@ make_compiler_cflags() { features="$features lto" fi fi - elif [ "$compiler" = "clang" ]; then + elif echo "$version_line" | grep -q "clang"; then # Enable some things only for certain clang versions - cc_version="`$1 -v 2>&1 | head -n 1 | sed s@[^0-9]@@g | cut -c 1-2`" + # Need to try really hard to get the version line, because OSX clang likes to hide its true version + cc_version="`$1 -v 2>&1 | grep -i version | head -n 1 | sed s@[^0-9]@@g | cut -c 1-2`" # aliasing rules are not held in openttd code flags="$flags -fno-strict-aliasing" @@ -1360,10 +1383,7 @@ make_compiler_cflags() { flags="$flags -Wno-unused-variable" fi - if [ "$cc_version" -ge "33" ]; then - # clang completed C++11 support in version 3.3 - flags="$flags -std=c++11" - else + if [ "$cc_version" -lt "33" ]; then log 1 "configure: error: clang version is too old: `$1 -v 2>&1 | head -n 1`, minumum: 3.3" exit 1 fi @@ -1426,12 +1446,6 @@ make_compiler_cflags() { flags="$flags -Wnon-virtual-dtor" fi - if [ $cc_version -ge 403 ] && [ $cc_version -lt 600 ]; then - # Use gnu++0x mode so static_assert() is available. - # Don't use c++0x, it breaks mingw (with gcc 4.4.0). - cxxflags="$cxxflags -std=gnu++11" - fi - if [ $cc_version -eq 405 ]; then # Prevent optimisation supposing enums are in a range specified by the standard # For details, see http://gcc.gnu.org/PR43680 @@ -1456,7 +1470,7 @@ make_compiler_cflags() { if [ $cc_version -ge 600 ]; then # -flifetime-dse=2 (default since GCC 6) doesn't play # well with our custom pool item allocator - cxxflags="$cxxflags -flifetime-dse=1 -std=gnu++14" + cxxflags="$cxxflags -flifetime-dse=1" fi if [ "$enable_lto" != "0" ]; then @@ -1519,6 +1533,8 @@ make_cflags_and_ldflags() { CFLAGS="$CFLAGS -D$os" CFLAGS_BUILD="$CFLAGS_BUILD -D$os" + CXXFLAGS="$CXXFLAGS -std=c++11" + CXXFLAGS_BUILD="$CXXFLAGS_BUILD -std=c++11" if [ "$enable_debug" = "0" ]; then # No debug, add default stuff @@ -1539,9 +1555,6 @@ make_cflags_and_ldflags() { # Each debug level reduces the optimization by a bit if [ $enable_debug -ge 1 ]; then CFLAGS="$CFLAGS -g -D_DEBUG" - if [ "$os" = "PSP" ]; then - CFLAGS="$CFLAGS -G0" - fi fi if [ $enable_debug -ge 2 ]; then CFLAGS="$CFLAGS -fno-inline" @@ -1618,23 +1631,13 @@ make_cflags_and_ldflags() { fi fi - if [ "$os" != "CYGWIN" ] && [ "$os" != "HAIKU" ] && [ "$os" != "OPENBSD" ] && [ "$os" != "MINGW" ] && [ "$os" != "MORPHOS" ] && [ "$os" != "OSX" ] && [ "$os" != "DOS" ] && [ "$os" != "WINCE" ] && [ "$os" != "PSP" ] && [ "$os" != "OS2" ]; then + if [ "$os" != "CYGWIN" ] && [ "$os" != "HAIKU" ] && [ "$os" != "OPENBSD" ] && [ "$os" != "MINGW" ] && [ "$os" != "MORPHOS" ] && [ "$os" != "OSX" ] && [ "$os" != "DOS" ] && [ "$os" != "OS2" ]; then LIBS="$LIBS -lpthread" fi - if [ "$os" != "CYGWIN" ] && [ "$os" != "HAIKU" ] && [ "$os" != "MINGW" ] && [ "$os" != "DOS" ] && [ "$os" != "WINCE" ]; then + if [ "$os" != "CYGWIN" ] && [ "$os" != "HAIKU" ] && [ "$os" != "MINGW" ] && [ "$os" != "DOS" ]; then LIBS="$LIBS -lc" fi - if [ "$os" = "WINCE" ]; then - LIBS="$LIBS -lcoredll -lcorelibc -laygshell -lws2 -e WinMainCRTStartup" - fi - if [ "$os" = "PSP" ]; then - CFLAGS="$CFLAGS -I`$psp_config -p`/include" - LDFLAGS="$LDFLAGS -L`$psp_config -p`/lib" - - CFLAGS="$CFLAGS -fno-exceptions -fno-rtti -D_PSP_FW_VERSION=150" - LIBS="$LIBS -D_PSP_FW_VERSION=150 -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk -lpspnet -lpspnet_inet -lpspnet_apctl -lpspnet_resolver -lpsputility -lpspuser -lpspkernel -lm" - fi if [ "$os" = "MORPHOS" ]; then # -Wstrict-prototypes generates much noise because of system headers @@ -1673,14 +1676,14 @@ make_cflags_and_ldflags() { CFLAGS="$CFLAGS -DUNIX" fi # And others like Windows - if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ] || [ "$os" = "WINCE" ]; then + if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ]; then CFLAGS="$CFLAGS -DWIN" fi if [ -n "$allegro_config" ]; then CFLAGS="$CFLAGS -DWITH_ALLEGRO" CFLAGS="$CFLAGS `$allegro_config --cflags`" - if [ "$os" != "MINGW" ] && [ "$os" != "CYGWIN" ] && [ "$os" != "WINCE" ]; then + if [ "$os" != "MINGW" ] && [ "$os" != "CYGWIN" ]; then if [ "$enable_static" != "0" ]; then LIBS="$LIBS `$allegro_config --static --libs`" else @@ -1693,7 +1696,7 @@ make_cflags_and_ldflags() { CFLAGS="$CFLAGS -DWITH_SDL" # SDL must not add _GNU_SOURCE as it breaks many platforms CFLAGS="$CFLAGS `$sdl_config --cflags | sed 's@-D_GNU_SOURCE[^ ]*@@'`" - if [ "$os" != "MINGW" ] && [ "$os" != "CYGWIN" ] && [ "$os" != "WINCE" ]; then + if [ "$os" != "MINGW" ] && [ "$os" != "CYGWIN" ]; then if [ "$enable_static" != "0" ]; then LIBS="$LIBS `$sdl_config --static-libs`" else @@ -1790,7 +1793,7 @@ make_cflags_and_ldflags() { CFLAGS="$CFLAGS `$freetype_config --cflags | tr '\n\r' ' '`" if [ "$enable_static" != "0" ]; then - LIBS="$LIBS `$freetype_config --libs --static | tr '\n\r' ' '`" + LIBS="$LIBS `$freetype_config --libs --static | tr '\n\r' ' '` -lfreetype" else LIBS="$LIBS `$freetype_config --libs | tr '\n\r' ' '`" fi @@ -1818,6 +1821,10 @@ make_cflags_and_ldflags() { fi fi + if [ "$with_uniscribe" != "0" ]; then + CFLAGS="$CFLAGS -DWITH_UNISCRIBE" + LIBS="$LIBS -lusp10" + fi if [ "$with_direct_music" != "0" ]; then CFLAGS="$CFLAGS -DWIN32_ENABLE_DIRECTMUSIC_SUPPORT" @@ -1829,6 +1836,10 @@ make_cflags_and_ldflags() { fi fi + if [ "$with_xaudio2" != "0" ]; then + CFLAGS="$CFLAGS -DWITH_XAUDIO2" + fi + if [ -n "$libtimidity_config" ]; then CFLAGS="$CFLAGS -DLIBTIMIDITY" CFLAGS="$CFLAGS `$libtimidity_config --cflags | tr '\n\r' ' '`" @@ -1840,6 +1851,11 @@ make_cflags_and_ldflags() { fi fi + if [ -n "$fluidsynth" ]; then + LIBS="$LIBS -lfluidsynth" + CFLAGS="$CFLAGS -DFLUIDSYNTH" + fi + if [ "$with_iconv" != "0" ]; then CFLAGS="$CFLAGS -DWITH_ICONV" if [ "$link_to_iconv" = "yes" ]; then @@ -2129,7 +2145,7 @@ check_cxx_host() { } check_windres() { - if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ] || [ "$os" = "WINCE" ]; then + if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ]; then check_compiler "host windres" "windres" "$host" "$windres" "$WINDRES" "windres" "windres" "2" "-V" fi } @@ -2196,9 +2212,7 @@ check_direct_music() { echo " #include #include - #include #include - #include int main(int argc, char *argv[]) { }" > direct_music.test.c $cxx_host $CFLAGS direct_music.test.c -o direct_music.test 2> /dev/null res=$? @@ -2217,6 +2231,35 @@ check_direct_music() { fi } +check_xaudio2() { + echo " + #include + + #undef NTDDI_VERSION + #undef _WIN32_WINNT + + #define NTDDI_VERSION NTDDI_WIN8 + #define _WIN32_WINNT _WIN32_WINNT_WIN8 + + #include + int main(int argc, char *argv[]) { }" > xaudio2.test.c + $cxx_host $CFLAGS xaudio2.test.c -o xaudio2.test 2> /dev/null + res=$? + rm -f xaudio2.test.c xaudio2.test + + if [ "$res" != "0" ]; then + if [ "$with_xaudio2" != "1" ]; then + log 1 "configure: error: xaudio2 is not available on this system" + exit 1 + fi + with_xaudio2="0" + + log 1 "checking xaudio2... not found" + else + log 1 "checking xaudio2... found" + fi +} + check_makedepend() { if [ "$enable_builtin_depend" != "0" ]; then with_makedepend="0" @@ -2335,7 +2378,7 @@ detect_awk() { detect_os() { if [ "$os" = "DETECT" ]; then - # Detect UNIX, OSX, FREEBSD, DRAGONFLY, OPENBSD, NETBSD, HPUX, MORPHOS, BEOS, SUNOS, CYGWIN, MINGW, OS2, DOS, WINCE, and PSP + # Detect UNIX, OSX, FREEBSD, DRAGONFLY, OPENBSD, NETBSD, HPUX, MORPHOS, BEOS, SUNOS, CYGWIN, MINGW, OS2, and DOS # Try first via dumpmachine, then via uname os=`echo "$host" | tr '[A-Z]' '[a-z]' | $awk ' @@ -2355,8 +2398,6 @@ detect_os() { /mingw/ { print "MINGW"; exit} /os2/ { print "OS2"; exit} /dos/ { print "DOS"; exit} - /wince/ { print "WINCE"; exit} - /psp/ { print "PSP"; exit} '` if [ -z "$os" ]; then @@ -2382,7 +2423,7 @@ detect_os() { if [ -z "$os" ]; then log 1 "detecting OS... none detected" log 1 "I couldn't detect your OS. Please use --os=OS to force one" - log 1 "Allowed values are: UNIX, OSX, FREEBSD, DRAGONFLY, OPENBSD, NETBSD, MORPHOS, HPUX, BEOS, HAIKU, SUNOS, CYGWIN, MINGW, OS2, DOS, WINCE, and PSP" + log 1 "Allowed values are: UNIX, OSX, FREEBSD, DRAGONFLY, OPENBSD, NETBSD, MORPHOS, HPUX, BEOS, HAIKU, SUNOS, CYGWIN, MINGW, OS2, and DOS" exit 1 fi @@ -2641,6 +2682,11 @@ detect_library() { eval "res=\$$2" if [ -z "$res" ]; then log 2 " trying /mingw/include/$4$5... no" + eval "$2=`ls -1 /mingw$cpu_type/include/$4*.h 2>/dev/null | egrep \"\/$5\$\"`" + fi + eval "res=\$$2" + if [ -z "$res" ]; then + log 2 " trying /mingw$cpu_type/include/$4$5... no" eval "$2=`ls -1 /opt/local/include/$4*.h 2>/dev/null | egrep \"\/$5\$\"`" fi eval "res=\$$2" @@ -2689,6 +2735,11 @@ detect_library() { eval "res=\$$2" if [ -z "$res" ]; then log 2 " trying /mingw/lib/$3... no" + eval "$2=`ls /mingw$cpu_type/lib/*.a 2>/dev/null | egrep \"\/$3\$\"`" + fi + eval "res=\$$2" + if [ -z "$res" ]; then + log 2 " trying /mingw$cpu_type/lib/$3... no" log 1 "configure: error: $2 couldn't be found" log 1 "configure: error: you requested a static link, but I can't find $3" @@ -2741,6 +2792,10 @@ detect_libtimidity() { detect_pkg_config "$with_libtimidity" "libtimidity" "libtimidity_config" "0.1" "1" } +detect_fluidsynth() { + detect_library "$with_fluidsynth" "fluidsynth" "" "" "fluidsynth.h" +} + detect_pkg_config() { # $1 - config-param ($with_lzma value) # $2 - package name ('liblzma') @@ -2825,7 +2880,7 @@ detect_fontconfig() { fontconfig_config="" return 0 fi - if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ] || [ "$os" = "WINCE" ]; then + if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ]; then log 1 "checking libfontconfig... WIN32, skipping" fontconfig_config="" return 0 @@ -2841,62 +2896,25 @@ detect_fontconfig() { } detect_icu_layout() { + if [ "$with_cocoa" != "0" ] && [ "$with_icu_layout" = "1" ]; then + log 1 "checking icu-lx... OSX, skipping" + icu_layout_config="" + return 0 + fi + detect_pkg_config "$with_icu_layout" "icu-lx" "icu_layout_config" "4.8" "1" } detect_icu_sort() { + if [ "$with_cocoa" != "0" ] && [ "$with_icu_sort" = "1" ]; then + log 1 "checking icu-i18n... OSX, skipping" + icu_sort_config="" + return 0 + fi + detect_pkg_config "$with_icu_sort" "icu-i18n" "icu_sort_config" "4.8" "1" } -detect_pspconfig() { - # 0 means no, 1 is auto-detect, 2 is force - if [ "$with_psp_config" = "0" ]; then - log 1 "checking psp-config... disabled" - - psp_config="" - return 0 - fi - - if [ "$with_psp_config" = "1" ] && [ "$os" != "PSP" ]; then - log 1 "checking psp-config... not PSP, skipping" - - psp_config=""; - return 0 - fi - - if [ "$os" != "PSP" ]; then - log 1 "checking psp-config... not PSP" - - log 1 "configure: error: psp-config is only supported for PSP" - exit 1 - fi - - if [ "$with_psp_config" = "1" ] || [ "$with_psp_config" = "" ] || [ "$with_psp_config" = "2" ]; then - psp_config="psp-config" - else - psp_config="$with_psp_config" - fi - - version=`$psp_config -p 2>/dev/null` - ret=$? - log 2 "executing $psp_config -p" - log 2 " returned $version" - log 2 " exit code $ret" - - if [ -z "$version" ] || [ "$ret" != "0" ]; then - log 1 "checking psp-config... not found" - log 1 "configure: error: psp-config couldn't be found" - - # It was forced, so it should be found. - if [ "$with_psp_config" != "1" ]; then - log 1 "configure: error: you supplied '$with_psp_config', but it seems invalid" - fi - exit 1 - fi - - log 1 "checking psp-config... found" -} - detect_iconv() { # 0 means no, 1 is auto-detect, 2 is force if [ "$with_iconv" = "0" ]; then @@ -2915,10 +2933,16 @@ detect_iconv() { # Try to find iconv.h, seems to only thing to detect iconv with if [ "$with_iconv" = "1" ] || [ "$with_iconv" = "" ] || [ "$with_iconv" = "2" ]; then - iconv=`ls -1 /usr/include 2>/dev/null | grep "iconv.h"` - if [ -z "$iconv" ]; then - iconv=`ls -1 /usr/local/include 2>/dev/null | grep "iconv.h"` - fi + # Iterate over search paths + iconv="" + search_paths=`LC_ALL=C $cxx_host $OSX_SYSROOT $CFLAGS -E - -v &1 | \ + $awk '/#include <...> search starts here:/{flag=1;next}/End of search list./{flag=0}flag'` + for path in $search_paths; do + iconv=`ls -1 $path 2>/dev/null | grep "iconv.h"` + if [ -n "$iconv" ]; then + break + fi + done else # Make sure it exists iconv=`ls $with_iconv/include/iconv.h 2>/dev/null` @@ -3262,17 +3286,14 @@ make_sed() { s@!!INSTALL_DIR!!@$install_dir@g; s@!!BINARY_NAME!!@$binary_name@g; s@!!STRGEN!!@$STRGEN@g; - s@!!ENDIAN_CHECK!!@$ENDIAN_CHECK@g; s@!!DEPEND!!@$DEPEND@g; s@!!SETTINGSGEN!!@$SETTINGSGEN@g; - s@!!ENDIAN_FORCE!!@$endian@g; s@!!STAGE!!@$STAGE@g; s@!!MAKEDEPEND!!@$makedepend@g; s@!!CFLAGS_MAKEDEP!!@$cflags_makedep@g; s@!!SORT!!@$sort@g; s@!!CONFIG_CACHE_COMPILER!!@config.cache.compiler@g; s@!!CONFIG_CACHE_LINKER!!@config.cache.linker@g; - s@!!CONFIG_CACHE_ENDIAN!!@config.cache.endian@g; s@!!CONFIG_CACHE_SOURCE!!@config.cache.source@g; s@!!CONFIG_CACHE_VERSION!!@config.cache.version@g; s@!!CONFIG_CACHE_SOURCE_LIST!!@config.cache.source.list@g; @@ -3506,8 +3527,7 @@ showhelp() { echo " --os=OS the OS we are compiling for [DETECT]" echo " DETECT/UNIX/OSX/FREEBSD/DRAGONFLY/OPENBSD/" echo " NETBSD/MORPHOS/HPUX/BEOS/SUNOS/CYGWIN/" - echo " MINGW/OS2/DOS/WINCE/PSP/HAIKU" - echo " --endian=ENDIAN set the endian of the HOST (AUTO/LE/BE)" + echo " MINGW/OS2/DOS/HAIKU" echo "" echo "Paths:" echo " --prefix-dir=dir specifies the prefix for all installed" @@ -3578,6 +3598,7 @@ showhelp() { echo " midi-player" echo " --with-libtimidity[=\"pkg-config libtimidity\"]" echo " enables libtimidity support" + echo " --with-fluidsynth enables fluidsynth support" echo " --with-allegro[=\"pkg-config allegro\"]" echo " enables Allegro video driver support" echo " --with-cocoa enables COCOA video driver (OSX ONLY)" @@ -3603,7 +3624,6 @@ showhelp() { echo " --static-icu try to link statically (libsicu instead of" echo " libicu; can fail as the new name is guessed)" echo " --with-iconv[=iconv-path] enables iconv support" - echo " --with-psp-config[=psp-config] enables psp-config support (PSP ONLY)" echo " --disable-builtin-depend disable use of builtin deps finder" echo " --with-makedepend[=makedepend] enables makedepend support" echo " --with-ccache enables ccache support" diff --git a/configure b/configure index 5edbca1867..afc1de51b4 100755 --- a/configure +++ b/configure @@ -75,13 +75,12 @@ save_params make_cflags_and_ldflags EXE="" -if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ] || [ "$os" = "OS2" ] || [ "$os" = "DOS" ] || [ "$os" = "WINCE" ]; then +if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ] || [ "$os" = "OS2" ] || [ "$os" = "DOS" ]; then EXE=".exe" fi TTD="openttd$EXE" STRGEN="strgen$EXE" -ENDIAN_CHECK="endian_check$EXE" DEPEND="depend$EXE" SETTINGSGEN="settings_gen$EXE" @@ -114,7 +113,6 @@ AWKCOMMAND=' if ($0 == "PNG" && "'$png_config'" == "") { next; } if ($0 == "OSX" && "'$os'" != "OSX") { next; } if ($0 == "OS2" && "'$os'" != "OS2") { next; } - if ($0 == "PSP" && "'$os'" != "PSP") { next; } if ($0 == "DEDICATED" && "'$enable_dedicated'" != "1") { next; } if ($0 == "AI" && "'$enable_ai'" == "0") { next; } if ($0 == "COCOA" && "'$with_cocoa'" == "0") { next; } @@ -124,10 +122,10 @@ AWKCOMMAND=' if ($0 == "WIN32" && "'$os'" != "MINGW" && "'$os'" != "CYGWIN" && "'$os'" != "MSVC") { next; } if ($0 == "MORPHOS" && "'$os'" != "MORPHOS") { next; } - if ($0 == "WINCE" && "'$os'" != "WINCE") { next; } if ($0 == "MSVC" && "'$os'" != "MSVC") { next; } if ($0 == "DIRECTMUSIC" && "'$with_direct_music'" == "0") { next; } if ($0 == "LIBTIMIDITY" && "'$libtimidity'" == "" ) { next; } + if ($0 == "FLUIDSYNTH" && "'$fluidsynth'" == "" ) { next; } if ($0 == "HAVE_THREAD" && "'$with_threads'" == "0") { next; } if ($0 == "SSE" && "'$with_sse'" != "1") { next; } diff --git a/docs/Readme_Windows_MSVC.md b/docs/Readme_Windows_MSVC.md new file mode 100644 index 0000000000..c60904c72a --- /dev/null +++ b/docs/Readme_Windows_MSVC.md @@ -0,0 +1,70 @@ +# Compiling OpenTTD using Microsoft Visual C++ + +Last updated: 2018-12-27 + +## Supported MSVC compilers + +OpenTTD includes projects for Visual Studio 2015 Update 3 or more recent. +You can download the free Visual Studio Community Edition from Microsoft at +https://visualstudio.microsoft.com/vs/community/. + +## Required files + +### Microsoft platform files + +OpenTTD needs the Platform SDK, if it isn't installed already. This can be +done during installing Visual Studio, by selecting +`Visual C++ MFC for x86 and x64` (and possibly +`Visual C++ ATL for x86 and x64` depending on your version). If not, you +can get it at this location: + +- [MS Windows Platform SDK](http://www.microsoft.com/downloads/details.aspx?FamilyId=A55B6B43-E24F-4EA3-A93E-40C0EC4F68E5&displaylang=en) + +Install the SDK by following the instructions as given. + +### OpenTTD dependencies + +Dependencies for OpenTTD on Windows are handled via +[vcpkg](https://github.com/Microsoft/vcpkg/). First you need to install vcpkg +by following the `Quick Start` intructions of their +[README](https://github.com/Microsoft/vcpkg/blob/master/README.md). + +After this, you can install the dependencies OpenTTD needs. We advise to use +the `static` versions, and OpenTTD currently needs the following dependencies: + +- freetype +- liblzma +- libpng +- lzo +- zlib + +To install both the x64 (64bit) and x86 (32bit) variants, you can use: + +```ps +.\vcpkg install freetype:x64-windows-static liblzma:x64-windows-static libpng:x64-windows-static lzo:x64-windows-static zlib:x64-windows-static +.\vcpkg install freetype:x86-windows-static liblzma:x86-windows-static libpng:x86-windows-static lzo:x86-windows-static zlib:x86-windows-static +``` + +## TTD Graphics files + +See section 4.1 of README.md for the required 3rdparty files and how to install them. + +## Compiling + +Open the appropriate `sln` (Solution) file for your version of Visual Studio: + +- VS 2015: projects/openttd_vs140.sln +- VS 2017: projects/openttd_vs141.sln + +Set the build mode to `Release` in +`Build > Configuration manager > Active solution configuration`. +You can now compile. + +If everything works well the binary should be in `objs\Win[32|64]\Release\openttd.exe` +and in `bin\openttd.exe` + +## Problems + +If compilation fails, double-check that you are using the latest github +source. If it still doesn't work, check in on IRC (irc://irc.oftc.net/openttd), +to ask for help. diff --git a/docs/Readme_Windows_MSVC.txt b/docs/Readme_Windows_MSVC.txt deleted file mode 100644 index 65701e0e86..0000000000 --- a/docs/Readme_Windows_MSVC.txt +++ /dev/null @@ -1,108 +0,0 @@ -Compiling OpenTTD using Microsoft Visual C++ -Last updated: 2010-01-03 --------------------------------------------- -PLEASE READ THE ENTIRE DOCUMENT BEFORE DOING ANY ACTUAL CHANGES!! - - -SUPPORTED MSVC COMPILERS ------------------------- -OpenTTD includes projects for MSVC 2005.NET and MSVC 2008.NET. Both will -compile out of the box, providing you have the required libraries/headers; -which ones, see below. There is no support for VS6 or MSVC 2002, or -MSVC 2003.NET. You are therefore strongly encouraged to either upgrade to -MSVC 2008 Express (free) or use GCC. - - -1) REQUIRED FILES ------------------ -You might already have some of the files already installed, so check before -downloading; mostly because the DirectX SDK and Platform SDK are about -500MB each. -Download the following files: - - * openttd-useful.zip (http://binaries.openttd.org/extra/openttd-useful/) - * DirectX 8.1 SDK (http://neuron.tuke.sk/~mizanin/eng/Dx81sdk-include-lib.rar) (or alternatively the latest DirectX SDK from Microsoft) - * MS Windows Platform SDK (http://www.microsoft.com/downloads/details.aspx?FamilyId=A55B6B43-E24F-4EA3-A93E-40C0EC4F68E5&displaylang=en) - * afxres.h (http://www-d0.fnal.gov/d0dist/dist/packages/d0ve/devel/windows/AFXRES.H) - -...and of course the newest source from svn://svn.openttd.org/trunk - -You need an SVN-client to download the source from subversion: - - * CLI Subversion (http://subversion.tigris.org/) - * GUI TortoiseSVN (http://tortoisesvn.tigris.org/) - - -2) INCLUDES AND LIBRARIES -------------------------- -Put the newly downloaded files in the VC lib\ and include\ directories; where -"C:\Program Files\Microsoft Visual Studio 9.0\VC" is your location of Visual C. -If you are compiling for an x64 system, use the include\ and lib\ directories -from the win64/ folder. - - * openttd-useful.zip\include\* - * afxresh.h - to > C:\Program Files\Microsoft Visual Studio 9.0\VC\Include - - * openttd-useful.zip\lib\* - to > C:\Program Files\Microsoft Visual Studio 9.0\VC\Lib - -Custom directories might be recommended, check 2.2) - - -2.1) INCLUDES AND LIBRARIES - DIRECTX/PLATFORM SDK --------------------------------------------------- -Basically the same procedure as with the useful zip file, providing -you are not using the Microsoft installer. Put the include files in the -include\ directory and the library files to the Lib\ directory. - -It is recommended to use custom directories so you don't overwrite any -default header or library files. - - -2.2) CUSTOM DIRECTORIES ------------------------ -If you have put the above include and/or library files into custom folders, -MSVC will not find them by default. You need to add these paths to VC through: - -Tools > Options > Projects and Solutions > VC++ Directories > show directories for - - * Include files: Add the DirectX/Platform SDK include dir you've created - * Library files: Add the path to the SDK custom lib dir - -NOTE: make sure that the directory for the DirectX SDK is the first one in the -list, above all others, otherwise compilation will most likely fail!! - - -3) TTD GRAPHICS FILES ---------------------- -See section 4.1 of README.md for the required 3rdparty files and how to install them. - - -4) COMPILING ------------- -Open trunk/openttd_vs[89]0.sln -Set the build mode to 'Release' in -Build > Configuration manager > Active solution configuration > select "Release" -Compile... - -If everything works well the binary should be in trunk/objs/Win[32|64]/Release/openttd.exe - - -5) EDITING, CHANGING SOURCE CODE --------------------------------- -Set the build mode (back to) 'Debug' -Change the startup project to openttd by right-clicking the 'openttd' project -in the Solution Explorer and selecting 'Set as Startup Project'. The 'openttd' -project should now show up bold instead of 'strgen'. - - -6) PROBLEMS? ------------- -If compilation fails, double-check that you are using the latest SVN (!) -source. If it still doesn't work, check in on IRC (irc://irc.oftc.net/openttd), -to ask about reasons; or just wait. The problem will most likely solve itself -within a few days as the problem is noticed and fixed. - -An up-to-date version of this README can be found on the wiki: -http://wiki.openttd.org/Microsoft_Visual_C%2B%2B_2008_Express_Editions diff --git a/docs/landscape.html b/docs/landscape.html index f60e859fc3..a345128ea4 100644 --- a/docs/landscape.html +++ b/docs/landscape.html @@ -226,7 +226,7 @@
  • m1 bits 4..0: owner of the tile
  • m2: see signals
  • m3 bits 7..4: see signals
  • -
  • m3 bits 3..0 = track type: +
  • m8 bits 5..0 = track type: @@ -626,7 +626,8 @@
  • m5 bit 6 set: level crossing
    • m1 bits 4..0: owner of the railway track
    • -
    • m3 bits 3..0: railway track type
    • +
    • m5 bit 5: set if crossing lights are on
    • +
    • m5 bit 4: pbs reservation state
    • m5 bit 0: direction
  • 0 
    @@ -639,9 +640,8 @@
  • -
  • m5 bit 5: set if crossing lights are on
  • m7 bits 4..0: owner of the road type 0 (normal road)
  • -
  • m5 bit 4: pbs reservation state
  • +
  • m8 bits 5..0: railway track type
  • @@ -860,7 +860,6 @@
  • m2: index into the array of stations
  • m3 bits 7..4: persistent random data for railway stations/waypoints and airports)
  • m3 bits 7..4: owner of tram tracks (road stop)
  • -
  • m3 bits 3..0: track type for railway stations/waypoints
  • m4: custom station id; 0 means standard graphics
  • m5: graphics index (range from 0..255 for each station type): @@ -979,6 +978,7 @@
  • m7 bits 4..0: owner of road (road stops)
  • m7 bits 7..6: present road types (road stops)
  • m7: animation frame (railway stations/waypoints, airports)
  • +
  • m8 bits 5..0: track type for railway stations/waypoints
  • @@ -1444,7 +1444,6 @@
    • m1 bits 4..0: owner
    • m3 bits 7..4: owner of tram
    • -
    • m3 bits 3..0: track type for railway
    • m5 bit 4: pbs reservation state for railway
    • m5 bits 7 clear: tunnel entrance/exit
    • m5 bit 7 set: bridge ramp @@ -1582,6 +1581,7 @@
    • m7 bits 4..0: owner of road
    • m7 bit 5 set = on snow or desert
    • m7 bits 7..6: present road types for road
    • +
    • m8 bits 5..0: track type for railway
    diff --git a/docs/landscape_grid.html b/docs/landscape_grid.html index d34fe9840c..8519fa990a 100644 --- a/docs/landscape_grid.html +++ b/docs/landscape_grid.html @@ -37,6 +37,7 @@ the array so you can quickly see what is used and what is not.
  • m5 - 8 bits in size, is used for general storage
  • m6 - 8 bits in size, is used for general storage
  • m7 - 8 bits in size, is used for general storage
  • +
  • m8 - 16 bits in size, is used for general storage
  • @@ -52,6 +53,7 @@ the array so you can quickly see what is used and what is not. + @@ -64,6 +66,7 @@ the array so you can quickly see what is used and what is not. + @@ -77,6 +80,7 @@ the array so you can quickly see what is used and what is not. + @@ -89,6 +93,7 @@ the array so you can quickly see what is used and what is not. + @@ -97,11 +102,12 @@ the array so you can quickly see what is used and what is not. - + + @@ -109,11 +115,12 @@ the array so you can quickly see what is used and what is not. - + + @@ -121,11 +128,12 @@ the array so you can quickly see what is used and what is not. - + + @@ -139,6 +147,7 @@ the array so you can quickly see what is used and what is not. + @@ -146,11 +155,12 @@ the array so you can quickly see what is used and what is not. - - - + + + + @@ -163,6 +173,7 @@ the array so you can quickly see what is used and what is not. + @@ -176,6 +187,7 @@ the array so you can quickly see what is used and what is not. + @@ -189,6 +201,7 @@ the array so you can quickly see what is used and what is not. + @@ -197,11 +210,12 @@ the array so you can quickly see what is used and what is not. - + + @@ -214,6 +228,7 @@ the array so you can quickly see what is used and what is not. + @@ -226,6 +241,7 @@ the array so you can quickly see what is used and what is not. + @@ -238,6 +254,7 @@ the array so you can quickly see what is used and what is not. + @@ -250,6 +267,7 @@ the array so you can quickly see what is used and what is not. + @@ -262,6 +280,7 @@ the array so you can quickly see what is used and what is not. + @@ -274,6 +293,7 @@ the array so you can quickly see what is used and what is not. + @@ -287,6 +307,7 @@ the array so you can quickly see what is used and what is not. + @@ -299,6 +320,7 @@ the array so you can quickly see what is used and what is not. + @@ -311,6 +333,7 @@ the array so you can quickly see what is used and what is not. + @@ -324,6 +347,7 @@ the array so you can quickly see what is used and what is not. + @@ -332,23 +356,25 @@ the array so you can quickly see what is used and what is not. - + + + - - + + @@ -362,6 +388,7 @@ the array so you can quickly see what is used and what is not. +
    m5 (8) m6 (8) m7 (8)m8 (16)
    bits7654 3210 7654 3210 7654 3210FEDC BA98 7654 3210
    0XXXX XXXX OOOX XXOO OOOO OOOOOOOO OOOO OOOO OOOO
    farmland-inherit- OOOX XXOO OOOO OOOOOOOO OOOO OOOO OOOO
    1XXXX XXXX OOOX XXXX OOOO XXXX OOOO OOOOOOOO XXXXOOOO OOOO OOOO XXXX XXXX XXXX OOOO OOOO OOOO OOOOOOOO OOOO OOXX XXXX
    rail with signals-inherit- -inherit- OOOO XXXX XXXX XXXXXXXX XXXXXXXX OOOO XXXX XXXX -inherit- OOOO OOOO OOOO OOOO-inherit-
    depot-inherit- -inherit- XXXX XXXX XXXX XXXXOOOO XXXX-inherit- OOOO XXXX XXOX OOXX OOOO OOOO OOOO OOOO-inherit-
    2XXXX XXXX OOXX XOOO XXXO XXXXOOOO OOOO OOOO OOOO
    level crossing-inherit- -inherit- -inherit-XXXX XXXX-inherit-XXXX OOOXXXXX OOOOOOOO OOOOXXXX OOOX OOXX XOOO XXXX XXXXOOOO OOOO OOXX XXXX
    road depotXXOO OOXX OOOO OOOO XXXO XXXXOOOO OOOO OOOO OOOO
    3XXXX XXXX XXXX XXOO XXXX XXXXOOOO OOOO OOOO OOOO
    4XXOO OXXX OOOO OOOO OOOO OOOOOOOO OOOO OOOO OOOO
    5XXXX XXXX OXXX XXXX XXXX XXXX XXXX XXXXXXXX XXXXXXXX OOOO XXXX XXXX XXXX XXXX OOXX XXOO XXXX XXXXOOOO OOOO OOXX XXXX
    rail waypoint-inherit- -inherit- -inherit--inherit-
    road stop~~~~ ~XXX OOXX XOOO XXOX XXXXOOOO OOOO OOOO OOOO
    dock~~~~ ~XXX OOXX XOOO OOOO OOOOOOOO OOOO OOOO OOOO
    airportXXXX XXXX OOXX XOOO XXXX XXXXOOOO OOOO OOOO OOOO
    buoy~~~~ ~~~~ OOXX XOOO OOOO OOOOOOOO OOOO OOOO OOOO
    oilrig~~~~ ~~~~ OOXX XOOO OOOO OOOOOOOO OOOO OOOO OOOO
    6X~~X XXXX OOOO OOOO OOOO OOOOOOOO OOOO OOOO OOOO
    canal, river-inherit- OOOO OOOO OOOO OOOOOOOO OOOO OOOO OOOO
    shipdepot-inherit- OOOO OOOO OOOO OOOOOOOO OOOO OOOO OOOO
    8XXXX XXXX OOXX XXOO XXXX XXXXOOOO OOOO OOOO OOOO
    9XXXX XXXX OOOX XXXX OOOO OOOO OOOO OOOOXXXX XXXXXXXX OOOO OOOO OOOO XOOX XXXX OOOO OOOO XXXX XXXXOOOO OOOO OOXX XXXX
    bridge ramp -inherit- -inherit- -inherit-OOOO OOOO OOOO OOOO -inherit--inherit--inherit-OOOO OOOO -inherit- OOXX XXOO -inherit--inherit-
    AXXXX XXXX OOOO OOOO XXXX XXXXOOOO OOOO OOOO OOOO
    diff --git a/docs/obm_format.txt b/docs/obm_format.txt index 40f829a522..45fe5f879e 100644 --- a/docs/obm_format.txt +++ b/docs/obm_format.txt @@ -45,12 +45,15 @@ description.en_US = howdie ; The file names are case sensitive. ; You can have empty file names; in that case no song will be loaded ; for that 'entry'. +; If you want to load music from the MPS DOS music driver "cat" format, +; specify just the name of the .cat file the song is located in, then +; fill out the "catindex" section. [files] ; The theme song for OpenTTD theme = THEME_SONG.GM ; The songs in the 'old style' category -old_0 = -old_1 = +old_0 = GM.CAT +old_1 = GM.CAT old_2 = old_3 = old_4 = @@ -86,9 +89,17 @@ ezy_9 = ; Note that the list of files is case sensitive. Each file listed in the ; files section must be listed here with it's song name, otherwise you ; will get a lot of warnings when starting OpenTTD. +; You don't need to fill this out for "cat" format music, the song names +; are loaded directly from the file in that case. [names] THEME_SONG.GM = Tycoon DELUXE Theme +; If you are loading music from the DOS version "cat" format, specify +; which index into the file the song has. +[catindex] +old_0 = 1 +old_1 = 3 + ; The md5s section lists the MD5 checksum for the files that replace them. ; Note that the list of files is case sensitive. Each file listed in the ; files section must be listed here with it's MD5 checksum, otherwise you @@ -96,6 +107,13 @@ THEME_SONG.GM = Tycoon DELUXE Theme [md5s] THEME_SONG.GM = 45cfec1b9d8c7a0ad45e755833cbf221 +; If a song needs to have parts of the start or end cut off to avoid long +; silences, you can specify MIDI tick codes for start:end of the actual +; music part for each file here. +; Not all music drivers might support this feature. +[timingtrim] +THEME_SONG.GM = 768:53760 + ; The origin section provides the possibility to put and extra line into ; the warning that a file is missing/corrupt. This can be used to tell ; them where to find it. It works on the filename specified in the diff --git a/known-bugs.txt b/known-bugs.txt index e76229e722..8d4fd2204b 100644 --- a/known-bugs.txt +++ b/known-bugs.txt @@ -1,6 +1,6 @@ OpenTTD's known bugs -Last updated: 2016-07-01 -Release version: 1.6.1 +Last updated: 2018-11-05 +Release version: 1.9.0 ------------------------------------------------------------------------ @@ -14,12 +14,12 @@ Table of contents ---- ----- All bugs listed below are marked as known. Please do not submit any bugs that are the same as these. If you do, do not act surprised, because -we WILL flame you!! +we WILL flame you! The current list of known bugs that we intend to fix can be found in our -bug tracking system at: http://bugs.openttd.org -Also check the closed bugs when searching for your bug in this system as -we might have fixed the bug in the mean time. +bug tracking system at https://github.com/OpenTTD/OpenTTD/issues +Also check the closed bugs when searching for your bug in this system as we +might have fixed the bug in the mean time. 2.0) Known bugs @@ -29,436 +29,383 @@ reasons why we think that fixing them is infeasible. We might make some minor improvements that reduce the scope of these bugs, but we will not be able to completely fix them. -No suitable AI can be found - If you have no AIs and an AI is started the so-called 'dummy' AI will - be loaded. This AI does nothing but writing a message on the AI debug - window and showing a red warning. There are basically two solutions - for this problem: Either you set the number of AI players to 0 so that - no AI is started. You find that setting at the top of the window in the - "AI / Game Scripts Settings" window. - The other solution is acquiring (downloading) some AI. The easiest way - to do this is via the "Check Online Content" button in the main (intro) - menu or directly in the "AI / Game Scripts Settings" dialogue via the - "Check Online Content" button. +No suitable AI can be found: + If you have no AIs and an AI is started the so-called 'dummy' AI will + be loaded. This AI does nothing but writing a message on the AI debug + window and showing a red warning. There are basically two solutions + for this problem: Either you set the number of AI players to 0 so that + no AI is started. You find that setting at the top of the window in the + "AI / Game Scripts Settings" window. + The other solution is acquiring (downloading) some AI. The easiest way + to do this is via the "Check Online Content" button in the main (intro) + menu or directly in the "AI / Game Scripts Settings" dialogue via the + "Check Online Content" button. -After a while of playing, colours get corrupted - In Windows 7 the background slideshow corrupts the colour mapping of - OpenTTD's 8bpp screen modes. Workarounds for this are: - a) Switching to windowed mode, instead of fullscreen - b) Switching off background slideshow - c) Setting up the 32bpp-anim or 32bpp-optimized blitter +After a while of playing, colours get corrupted: + In Windows 7 the background slideshow corrupts the colour mapping + of OpenTTD's 8bpp screen modes. Workarounds for this are: + a) Switching to windowed mode, instead of fullscreen + b) Switching off background slideshow + c) Setting up the 32bpp-anim or 32bpp-optimized blitter -Long delay between switching songs/music - On Windows there is a delay of a (few) second(s) between switching of - songs for the "win32" driver. This delay is caused by the fact that - opening a MIDI file via MCI is extremely slow. +Custom vehicle type name is incorrectly aligned: + Some NewGRFs use sprites that are bigger than normal in the "buy + vehicle" window. Due to this they have to encode an offset for + the vehicle type name. Upon renaming the vehicle type this encoded + offset is stripped from the name because the "edit box" cannot show + this encoding. As a result the custom vehicle type names will get + the default alignment. The only way to (partially) fix this is by + adding spaces to the custom name. - DirectMusic, known as "dmusic" in OpenTTD, has a much shorter delay. - However, under some circumstances DirectMusic does not reset its - state properly causing wrongly pitched/bad sounding songs. This - problem is in DirectMusic as it is reproducable with Microsoft's - DirectMusic Producer. DirectMusic has been deprecated since 2004 - and as such has no support for 64 bits OpenTTD. +Clipping problems [#119]: + In some cases sprites are not drawn as one would expect. Examples of + this are aircraft that might be hidden below the runway or trees that + in some cases are rendered over vehicles. + The primary cause of this problem is that OpenTTD does not have enough + data (like a 3D model) to properly determine what needs to be drawn in + front of what. OpenTTD has bounding boxes but in lots of cases they + are either too big or too small and then cause problems with what + needs to be drawn in front of what. Also some visual tricks are used. + For example trains at 8 pixels high, the catenary needs to be drawn + above that. When you want to draw bridges on top of that, which are + only one height level (= 8 pixels) higher, you are getting into some + big problems. + We can not change the height levels; it would require us to either + redraw all vehicle or all landscape graphics. Doing so would mean we + leave the Transport Tycoon graphics, which in effect means OpenTTD + will not be a Transport Tycoon clone anymore. - As a delay is favourable over bad sounding music the "win32" driver - is the default driver for OpenTTD. You can change this default by - setting the "musicdriver" in your openttd.cfg to "dmusic". +Mouse scrolling not possible at the edges of the screen [#383] [#3966]: + Scrolling the viewport with the mouse cursor at the edges of the screen + in the same direction of the edge will fail. If the cursor is near the + edge the scrolling will be very slow. + OpenTTD only receives cursor position updates when the cursor is inside + OpenTTD's window. It is not told how far you have moved the cursor + outside of OpenTTD's window. -Custom vehicle type name is incorrectly aligned - Some NewGRFs use sprites that are bigger than normal in the "buy - vehicle" window. Due to this they have to encode an offset for the - vehicle type name. Upon renaming the vehicle type this encoded offset - is stripped from the name because the "edit box" cannot show this - encoding. As a result the custom vehicle type names will get the - default alignment. The only way to (partly) fix this is by adding - spaces to the custom name. +Lost trains ignore (block) exit signals [#1473]: + If trains are lost they ignore block exit signals, blocking junctions + with presignals. This is caused because the path finders cannot tell + where the train needs to go. As such a random direction is chosen at + each junction. This causes the trains to occasionally to make choices + that are unwanted from a player's point of view. + This will not be fixed because lost trains are in almost all cases a + network problem, e.g. a train can never reach a specific place. This + makes the impact of fixing the bug enormously small against the amount + of work needed to write a system that prevents the lost trains from + taking the wrong direction. -Clipping problems [FS#119] - In some cases sprites are not drawn as one would expect. Examples of - this are aircraft that might be hidden below the runway or trees that - in some cases are rendered over vehicles. - The primary cause of this problem is that OpenTTD does not have enough - data (like a 3D model) to properly determine what needs to be drawn in - front of what. OpenTTD has bounding boxes but in lots of cases they - are either too big or too small and then cause problems with what - needs to be drawn in front of what. Also some visual tricks are used. - For example trains at 8 pixels high, the catenary needs to be drawn - above that. When you want to draw bridges on top of that, which are - only one height level (= 8 pixels) higher, you are getting into some - big problems. - We can not change the height levels; it would require us to either - redraw all vehicle or all landscape graphics. Doing so would mean we - leave the Transport Tycoon graphics, which in effect means OpenTTD - will not be a Transport Tycoon clone anymore. +Vehicle owner of last transfer leg gets paid for all [#2427]: + When you make a transfer system that switches vehicle owners. This + is only possible with 'industry stations', e.g. the oil rig station + the owner of the vehicle that does the final delivery gets paid for + the whole trip. It is not shared amongst the different vehicle + owners that have participated in transporting the cargo. + This sharing is not done because it would enormously increase the + memory and CPU usage in big games for something that is happening + in only one corner case. We think it is not worth the effort until + sharing of stations is an official feature. -Mouse scrolling not possible at the edges of the screen [FS#383] [FS#3966] - Scrolling the viewport with the mouse cursor at the edges of the screen - in the same direction of the edge will fail. If the cursor is near the - edge the scrolling will be very slow. - OpenTTD only receives cursor position updates when the cursor is inside - OpenTTD's window. It is not told how far you have moved the cursor - outside of OpenTTD's window. +Forbid 90 degree turns does not work for crossing PBS paths [#2737]: + When you run a train through itself on a X junction with PBS turned on + the train will not obey the 'forbid 90 degree turns' setting. This is + due to the fact that we can not be sure that the setting was turned + off when the track was reserved, which means that we assume it was + turned on and that the setting does not hold at the time. We made it + this way to allow one to change the setting in-game, but it breaks + slightly when you are running your train through itself. Running a + train through means that your network is broken and is thus a user + error which OpenTTD tries to graciously handle. + Fixing this bug means that we need to record whether this particular + setting was turned on or off at the time the reservation was made. This + means adding quite a bit of data to the savegame for solving an issue + that is basically an user error. We think it is not worth the effort. -Lost trains ignore (block) exit signals [FS#1473] - If trains are lost they ignore block exit signals, blocking junctions - with presignals. This is caused because the path finders cannot tell - where the train needs to go. As such a random direction is chosen at - each junction. This causes the trains to occasionally to make choices - that are unwanted from a player's point of view. - This will not be fixed because lost trains are in almost all cases a - network problem, e.g. a train can never reach a specific place. This - makes the impact of fixing the bug enormously small against the - amount of work needed to write a system that prevents the lost trains - from taking the wrong direction. +Duplicate (station) names after renaming [#3204]: + After renaming stations one can create duplicate station names. This + is done giving a station the same custom name as another station with + an automatically generated name. + The major part of this problem is that station names are translatable. + Meaning that a station is called e.g. ' Central' in English and + ' Centraal' in Dutch. This means that in network games the + renaming of a town could cause the rename to succeed on some clients + and fail at others. This creates an inconsistent game state that will + be seen as a 'desync'. Secondly the custom names are intended to fall + completely outside of the ' ' naming of stations, so when + you rename a town all station names are updated accordingly. + As a result the decision has been made that all custom names are only + compared to the other custom names in the same class and not compared + to the automatically generated names. -Vehicle owner of last transfer leg gets paid for all [FS#2427] - When you make a transfer system that switches vehicle owners. This - is only possible with 'industry stations', e.g. the oil rig station - the owner of the vehicle that does the final delivery gets paid for - the whole trip. It is not shared amongst the different vehicle - owners that have participated in transporting the cargo. - This sharing is not done because it would enormously increase the - memory and CPU usage in big games for something that is happening - in only one corner case. We think it is not worth the effort until - sharing of stations is an official feature. +Extreme CPU usage/hangs when using SDL and PulseAudio [#3294], +OpenTTD hangs/freezes when closing, OpenTTD is slow, OpenTTD uses a lot of CPU: + OpenTTD can be extremely slow/use a lot of CPU when the sound is + played via SDL and then through PulseAudio's ALSA wrapper. Under the + same configuration OpenTTD, or rather SDL, might hang when exiting + the game. This problem is seen most in Ubuntu 9.04 and higher. -Forbid 90 degree turns does not work for crossing PBS paths [FS#2737] - When you run a train through itself on a X junction with PBS turned on - the train will not obey the 'forbid 90 degree turns' setting. This is - due to the fact that we can not be sure that the setting was turned - off when the track was reserved, which means that we assume it was - turned on and that the setting does not hold at the time. We made it - this way to allow one to change the setting in-game, but it breaks - slightly when you are running your train through itself. Running a - train through means that your network is broken and is thus a user - error which OpenTTD tries to graciously handle. - Fixing this bug means that we need to record whether this particular - setting was turned on or off at the time the reservation was made. This - means adding quite a bit of data to the savegame for solving an issue - that is basically an user error. We think it is not worth the effort. + This is because recent versions of the PulseAudio sound server + are configured to use timer-based audio scheduling rather than + interrupt-based audio scheduling. Configuring PulseAudio to force + use of interrupt-based scheduling may resolve sound problems for + some users. Under recent versions of Ubuntu Linux (9.04 and higher) + this can be accomplished by changing the following line in the + /etc/pulse/default.pa file: + load-module module-udev-detect + to + load-module module-udev-detect tsched=0 + Note that PulseAudio must be restarted for changes to take effect. Older + versions of PulseAudio may use the module-hal-detect module instead. + Adding tsched=0 to the end of that line will have a similar effect. -Duplicate (station) names after renaming [FS#3204] - After renaming stations one can create duplicate station names. This - is done giving a station the same custom name as another station with - an automatically generated name. - The major part of this problem is that station names are translatable. - Meaning that a station is called e.g. ' Central' in English and - ' Centraal' in Dutch. This means that in network games the - renaming of a town could cause the rename to succeed on some clients - and fail at others. This creates an inconsistent game state that will - be seen as a 'desync'. Secondly the custom names are intended to fall - completely outside of the ' ' naming of stations, so when - you rename a town all station names are updated accordingly. - As a result the decision has been made that all custom names are only - compared to the other custom names in the same class and not compared - to the automatically generated names. + Another possible solution is selecting the "pulse" backend of SDL + by either using "SDL_AUDIODRIVER=pulse openttd" at the command + prompt or installing the 'libsdl1.2debian-pulseaudio' package from + Ubuntu's Universe repository. For other distributions a similar + package needs to be installed. -Extreme CPU usage/hangs when using SDL and PulseAudio [FS#3294] -OpenTTD hangs/freezes when closing, OpenTTD is slow, OpenTTD uses a lot of CPU - OpenTTD can be extremely slow/use a lot of CPU when the sound is - played via SDL and then through PulseAudio's ALSA wrapper. Under the - same configuration OpenTTD, or rather SDL, might hang when exiting - the game. This problem is seen most in Ubuntu 9.04 and higher. - - This is because recent versions of the PulseAudio sound server are - configured to use timer-based audio scheduling rather than - interrupt-based audio scheduling. Configuring PulseAudio to force - use of interrupt-based scheduling may resolve sound problems for - some users. Under recent versions of Ubuntu Linux (9.04 and higher) - this can be accomplished by changing the following line in the - /etc/pulse/default.pa file: - load-module module-udev-detect - to - load-module module-udev-detect tsched=0 - Note that PulseAudio must be restarted for changes to take effect. - Older versions of PulseAudio may use the module-hal-detect module - instead. Adding tsched=0 to the end of that line will have a similar - effect. - - Another possible solution is selecting the "pulse" backend of SDL - by either using "SDL_AUDIODRIVER=pulse openttd" at the command - prompt or installing the 'libsdl1.2debian-pulseaudio' package from - Ubuntu's Universe repository. For other distributions a similar - package needs to be installed. - -OpenTTD not properly resizing with SDL on X [FS#3305] - Under some X window managers OpenTTD's window does not properly - resize. You will either end up with a black bar at the right/bottom - side of the window or you cannot see the right/bottom of the window, - e.g you cannot see the status bar. The problem is that OpenTTD does - not always receive a resize event from SDL making it impossible for - OpenTTD to know that the window was resized; sometimes moving the - window will solve the problem. - Window managers that are known to exhibit this behaviour are KDE's - and GNOME's. With the XFCE's and LXDE's window managers the resize - event is sent when the user releases the mouse. +OpenTTD not properly resizing with SDL on X [#3305]: + Under some X window managers OpenTTD's window does not properly + resize. You will either end up with a black bar at the right/bottom + side of the window or you cannot see the right/bottom of the window, + e.g. you cannot see the status bar. The problem is that OpenTTD does + not always receive a resize event from SDL making it impossible for + OpenTTD to know that the window was resized; sometimes moving the + window will solve the problem. + Window managers that are known to exhibit this behaviour are GNOME's + and KDE's. With the XFCE's and LXDE's window managers the resize + event is sent when the user releases the mouse. Incorrect colours, crashes upon exit, debug warnings and smears upon -window resizing with SDL on Mac OS X [FS#3447] - Video handling with (lib)SDL under Mac OS X is known to fail on some - versions of Mac OS X with some hardware configurations. Some of the - problems happen only under some circumstances whereas others are - always present. - We suggest that the SDL video/sound backend is not used for OpenTTD - in combinations with Mac OS X. +window resizing with SDL on macOS [#3447]: + Video handling with (lib)SDL under macOS is known to fail on some + versions of macOS with some hardware configurations. Some of + the problems happen only under some circumstances whereas others + are always present. + We suggest that the SDL video/sound backend is not used for OpenTTD + in combinations with macOS. -Train crashes entering same junction from block and path signals [FS#3928] - When a train has reserved a path from a path signal to a two way - block signal and the reservation passes a path signal through the - back another train can enter the reserved path (only) via that same - two way block signal. - The reason for this has to do with optimisation; to fix this issue - the signal update has to pass all path signals until it finds either - a train or a backwards facing signal. This is a very expensive task. - The (signal) setups that allow these crashes can furthermore be - considered incorrectly signalled; one extra safe waiting point for - the train entering from path signal just after the backwards facing - signal (from the path signal train) resolves the issue. +Train crashes entering same junction from block and path signals [#3928]: + When a train has reserved a path from a path signal to a two way + block signal and the reservation passes a path signal through the + back another train can enter the reserved path (only) via that + same two way block signal. + The reason for this has to do with optimisation; to fix this issue + the signal update has to pass all path signals until it finds either + a train or a backwards facing signal. This is a very expensive task. + The (signal) setups that allow these crashes can furthermore be + considered incorrectly signalled; one extra safe waiting point for + the train entering from path signal just after the backwards facing + signal (from the path signal train) resolves the issue. -Crashes when playing music [FS#3941] - Mac OS X's QuickTime (default music driver) and Windows' MCI (win32 - music driver) crash on some songs from OpenMSX. OpenTTD cannot do - anything about this. Please report these crashes to the authors of - OpenMSX so the crash causing songs can be removed or fixed. +Crashes when run in a VM using Parallels Desktop [#4003]: + When the Windows version of OpenTTD is executed in a VM under + Parallels Desktop a privileged instruction exception may be thrown. + As OpenTTD works natively on macOS as well as natively on Windows and + these native builds both don't exhibit this behaviour this crash is + most likely due to a bug in the virtual machine, something out of + the scope of OpenTTD. Most likely this is due to Parallels Desktop + lacking support for RDTSC calls. The problem can be avoided by using + other VM-software, Wine, or running natively on macOS. -Crashes when run in a VM using Parallels Desktop [FS#4003] - When the Windows version of OpenTTD is executed in a VM under - Parallels Desktop a privileged instruction exception may be thrown. - As OpenTTD works natively on OSX as well as natively on Windows and - these native builds both don't exhibit this behaviour this crash is - most likely due to a bug in the virtual machine, something out of - the scope of OpenTTD. Most likely this is due to Parallels Desktop - lacking support for RDTSC calls. The problem can be avoided by using - other VM-software, Wine, or running natively on OSX. +Entry- and exit signals are not dragged [#4378]: + Unlike all other signal types, the entry- and exit signals are not + dragged but instead normal signals are placed on subsequent track + sections. This is done on purpose as this is the usually more + convenient solution. There are little to no occasions where more + than one entry or exit signal in a row are useful. This is different + for all other signal types where several in a row can serve one + purpose or another. -OpenTTD hangs when started on 32 bits Windows [FS#4083] - Under some circumstances OpenTTD might hang for hours on the - initialisation of the music driver. The exact circumstances are - unknown except that it is the "dmusic" music driver that has the - problem and that the "win32" music driver does not. - As a result using the "win32" music driver will work around this - issue. +Station build date is incorrect [#4415]: + The tile query tool will show the date of the last (re)construction + at the station and not the date of the first construction. This is + due to compatability reasons with NewGRFs and the fact that it is + wrong to say that the station is built in a particular year when it + was completely destroyed/rebuilt later on. + The tile query tool can be fixed by changing the "Build date" text + to "Date at which the last (re)construction took place" but this is + deemed too specific and long for that window. - As the exact circumstances are unknown, and the obvious - configuration settings related to the music driver are at their - default we are not able to detect this failure, except when Windows' - music initialisation function returns after several hours and then - there is no point in switching the music driver anymore. - The reason we still use the "win32" music driver as default are - described in the "Long delay between switching music/song" section - of this document. +(Temporary) wrong colours when switching to full screen [#4511]: + On Windows it can happen that you temporarily see wrong colours + when switching to full screen OpenTTD, either by starting + OpenTTD in full screen mode, changing to full screen mode or by + ALT-TAB-ing into a full screen OpenTTD. This is caused by the + fact that OpenTTD, by default, uses 8bpp paletted output. The + wrong colours you are seeing is a temporary effect of the video + driver switching to 8bpp palette mode. -Pre- and exit signals are not dragged [FS#4378] - Unlike all other signal types, the entry- and exit signals are not - dragged but instead normal signals are placed on subsequent track - sections. This is done on purpose as this is the usually more con- - venient solution. There are little to no occasions where more than - one entry or exit signal in a row are useful. This is different - for all other signal types where several in a row can serve one - purpose or another. + This issue can be worked around in two ways: + a) Setting fullscreen_bpp to 32 + b) Setting up the 32bpp-anim or 32bpp-optimized blitter -Station build date is incorrect [FS#4415] - The tile query tool will show the date of the last (re)construction - at the station and not the date of the first construction. This is - due to compatability reasons with NewGRFs and the fact that it is - wrong to say that the station is built in a particular year when it - was completely destroyed/rebuilt later on. - The tile query tool can be fixed by changing the "Build date" text - to "Date at which the last (re)construction took place" but this is - deemed too specific and long for that window. +Can't run OpenTTD with the -d option from a MSYS console [#4587]: + The MSYS console does not allow OpenTTD to open an extra console for + debugging output. Compiling OpenTTD with the --enable-console + configure option prevents this issue and allows the -d option to use + the MSYS console for its output. -Can't change volume inside OpenTTD [FS#4416] - Some backends do not provide a means to change the volume of sound - effects or music. The mixing of music and sound is left to external - libraries/the operating system we can't handle the volume control - in OpenTTD. As a result you can't change the volume inside OpenTTD - for backends such as SDL; just use the volume control provided by - your operating system. +Unreadable characters for non-latin locales [#4607]: + OpenTTD does not ship a non-latin font in its graphics files. As a + result OpenTTD needs to acquire the font from somewhere else. What + OpenTTD does is ask the operating system, or a system library, for + the best font for a given language if the currently loaded font + does not provide all characters of the chosen translation. This + means that OpenTTD has no influence over the quality of the chosen + font; it just does the best it can do. -Can't run OpenTTD with the -d option from a MSYS console [FS#4587] - The MSYS console does not allow OpenTTD to open an extra console for - debugging output. Compiling OpenTTD with the --enable-console - configure option prevents this issue and allows the -d option to use - the MSYS console for its output. + If the text is unreadable there are several steps that you can take + to improve this. The first step is finding a good font and configure + this in the configuration file. See section 9.0 of README.md for + more information. You can also increase the font size to make the + characters bigger and possible better readable. -Unreadable characters for non-latin locales [FS#4607] - OpenTTD does not ship a non-latin font in its graphics files. As a - result OpenTTD needs to acquire the font from somewhere else. What - OpenTTD does is ask the operating system, or a system library, for - the best font for a given language if the currently loaded font - does not provide all characters of the chosen translation. This - means that OpenTTD has no influence over the quality of the chosen - font; it just does the best it can do. + If the problem is with the clarity of the font you might want to + enable anti-aliasing by setting the small_aa/medium_aa/large_aa + settings to "true". However, anti-aliasing only works when a 32-bit + blitter has been selected, e.g. blitter = "32bpp-anim", as with the + 8 bits blitter there are not enough colours to properly perform the + anti-aliasing. - If the text is unreadable there are several steps that you can take - to improve this. The first step is finding a good font and configure - this in the configuration file. See section 9.0 of readme.txt for - more information. You can also increase the font size to make the - characters bigger and possible better readable. +Train does not crash with itself [#4635]: + When a train drives in a circle the front engine passes through + wagons of the same train without crashing. This is intentional. + Signals are only aware of tracks, they do not consider the train + length and whether there would be enough room for a train in some + circle it might drive on. Also the path a train might take is not + necessarily known when passing a signal. + Checking all circumstances would take a lot of additional + computational power for signals, which is not considered worth + the effort, as it does not add anything to gameplay. + Nevertheless trains shall not crash in normal operation, so making + a train not crash with itself is the best solution for everyone. - If the problem is with the clarity of the font you might want to - enable anti-aliasing by setting the small_aa/medium_aa/large_aa - settings to "true". However, anti-aliasing only works when a 32 bits - blitter has been selected, e.g. blitter = "32bpp-anim", as with the - 8 bits blitter there are not enough colours to properly perform the - anti-aliasing. +Aircraft coming through wall in rotated airports [#4705]: + With rotated airports, specifically hangars, you will see that the + aircraft will show a part through the back wall of the hangar. + This can be solved by only drawing a part of the plane when being + at the back of the hangar, however then with transparency turned on + the aircraft would be shown partially which would be even weirder. + As such the current behaviour is deemed the least bad. + The same applies to overly long ships and their depots. -(Temporary) wrong colours when switching to full screen [FS#4511]: - On Windows it can happen that you temporarily see wrong colours - when switching to full screen OpenTTD, either by starting - OpenTTD in full screen mode, changing to full screen mode or by - ALT-TAB-ing into a full screen OpenTTD. This is caused by the - fact that OpenTTD, by default, uses 8bpp paletted output. The - wrong colours you are seeing is a temporary effect of the video - driver switching to 8bpp palette mode. +Vehicles not keeping their "maximum" speed [#4815]: + Vehicles that have not enough power to reach and maintain their + advertised maximum speed might be constantly jumping between two + speeds. This is due to the fact that speed and its calculations + are done with integral numbers instead of floating point numbers. + As a result of this a vehicle will never reach its equilibrium + between the drag/friction and propulsion. So in effect it will be + in a vicious circle of speeding up and slowing down due to being + just at the other side of the equilibrium. - This issue can be worked around in two ways: - a) Setting fullscreen_bpp to 32 - b) Setting up the 32bpp-anim or 32bpp-optimized blitter + Not speeding up when near the equilibrium will cause the vehicle to + never come in the neighbourhood of the equilibrium and not slowing + down when near the equilibrium will cause the vehicle to never slow + down towards the equilibrium once it has come down a hill. -Train does not crash with itself [FS#4635]: - When a train drives in a circle the front engine passes through - wagons of the same train without crashing. This is intentional. - Signals are only aware of tracks, they do not consider the train - length and whether there would be enough room for a train in some - circle it might drive on. Also the path a train might take is not - necessarily known when passing a signal. - Checking all circumstances would take a lot of additional computational - power for signals, which is not considered worth the effort, as - it does not add anything to gameplay. - Nevertheless trains shall not crash in normal operation, so making - a train not crash with itself is the best solution for everyone. + It is possible to calculate whether the equilibrium will be passed, + but then all acceleration calculations need to be done twice. -Aircraft coming through wall in rotated airports [FS#4705]: - With rotated airports, specifically hangars, you will see that the - aircraft will show a part through the back wall of the hangar. - This can be solved by only drawing a part of the plane when being - at the back of the hangar, however then with transparency turned on - the aircraft would be shown partially which would be even weirder. - As such the current behaviour is deemed the least bad. - The same applies to overly long ships and their depots. +Settings not saved when OpenTTD crashes [#4846]: + The settings are not saved when OpenTTD crashes for several reasons. + The most important is that the game state is broken and as such the + settings might contain invalid values, or the settings have not even + been loaded yet. This would cause invalid or totally wrong settings + to be written to the configuration file. -Vehicles not keeping their "maximum" speed [FS#4815]: - Vehicles that have not enough power to reach and maintain their - advertised maximum speed might be constantly jumping between two - speeds. This is due to the fact that speed and its calculations - are done with integral numbers instead of floating point numbers. - As a result of this a vehicle will never reach its equilibrium - between the drag/friction and propulsion. So in effect it will be - in a vicious circle of speeding up and slowing down due to being - just at the other side of the equilibrium. + A solution to that would be saving the settings whenever one changes, + however due to the way the configuration file is saved this requires + a flush of the file to the disk and OpenTTD needs to wait till that + is finished. On some file system implementations this causes the + flush of all 'write-dirty' caches, which can be a significant amount + of data to be written. This can further be aggravated by spinning + down disks to conserve power, in which case this disk needs to be + spun up first. This means that many seconds may pass before the + configuration file is actually written, and all that time OpenTTD + will not be able to show any progress. Changing the way the + configuration file is saved is not an option as that leaves us more + vulnerable to corrupt configuration files. - Not speeding up when near the equilibrium will cause the vehicle - to never come in the neighbourhood of the equilibrium and not - slowing down when near the equilibrium will cause the vehicle - to never slow down towards the equilibrium once it has come down - a hill. + Finally, crashes should not be happening. If they happen they should + be reported and fixed, so essentially fixing this is fixing the wrong + thing. If you really need the configuration changes to be saved, + and you need to run a version that crashes regularly, then you can + use the 'saveconfig' command in the console to save the settings. - It is possible to calculate whether the equilibrium will be - passed, but then all acceleration calculations need to be done - twice. +Not all NewGRFs, AIs, game scripts are found [#4887]: + Under certain situations, where the path for the content within a + tar file is the same as other content on the file system or in another + tar file, it is possible that content is not found. A more thorough + explanation and solutions are described in section 4.4 of README.md. -Settings not saved when OpenTTD crashes [FS#4846]: - The settings are not saved when OpenTTD crashes for several reasons. - The most important is that the game state is broken and as such the - settings might contain invalid values, or the settings have not even - been loaded yet. This would cause invalid or totally wrong settings - to be written to the configuration file. +Mouse cursor going missing with SDL [#4997]: + Under certain circumstances SDL does not notify OpenTTD of changes with + respect to the mouse pointer, specifically whether the mouse pointer + is within the bounds of OpenTTD or not. For example, if you "Alt-Tab" + to another application the mouse cursor will still be shown in OpenTTD, + and when you move the mouse outside of the OpenTTD window so the cursor + gets hidden, open/move another application on top of the OpenTTD window + and then Alt-tab back into OpenTTD the cursor will not be shown. - A solution to that would be saving the settings whenever one changes, - however due to the way the configuration file is saved this requires - a flush of the file to the disk and OpenTTD needs to wait till that - is finished. On some file system implementations this causes the - flush of all 'write-dirty' caches, which can be a significant amount - of data to be written. This can further be aggravated by spinning - down disks to conserve power, in which case this disk needs to be - spun up first. This means that many seconds may pass before the - configuration file is actually written, and all that time OpenTTD - will not be able to show any progress. Changing the way the - configuration file is saved is not an option as that leaves us more - vulnerable to corrupt configuration files. + We cannot fix this problem as SDL simply does not provide the required + information in these corner cases. This is a bug in SDL and as such + there is little that we can do about it. - Finally, crashes should not be happening. If they happen they should - be reported and fixed, so essentially fixing this is fixing the - wrong thing. If you really need the configuration changes to be - saved, and you need to run a version that crashes regularly, then - you can use the 'saveconfig' command in the console to save the - settings. +Trains might not stop at platforms that are currently being changed [#5553]: + If you add tiles to or remove tiles from a platform while a train is + approaching to stop at the same platform, that train can miss the place + where it's supposed to stop and pass the station without stopping. + This is caused by the fact that the train is considered to already + have stopped if it's beyond its assigned stopping location. We can't + let the train stop just anywhere in the station because then it would + never leave the station if you have the same station in the order + list multiple times in a row or if there is only one station + in theorder list (see #5684). -Not all NewGRFs, AIs, game scripts are found [FS#4887]: - Under certain situations, where the path for the content within a - tar file is the same as other content on the file system or in another - tar file, it is possible that content is not found. A more thorough - explanation and solutions are described in section 4.4 of readme.txt. +Inconsistent catchment areas [#5661]: + Due to performance decisions the catchment area for cargo accepted by a + station for delivery to houses or industries differs from the catchment + area for cargo that is delivered to stations from houses or industries. -Mouse cursor going missing with SDL [FS#4997]: - Under certain circumstances SDL does not notify OpenTTD of changes - with respect to the mouse pointer, specifically whether the mouse - pointer is within the bounds of OpenTTD or not. For example, if you - Alt-tab to another application the mouse cursor will still be shown - in OpenTTD, and when you move the mouse outside of the OpenTTD - window so the cursor gets hidden, open/move another application on - top of the OpenTTD window and then Alt-tab back into OpenTTD the - cursor will not be shown. + Conceptually they work the same, but the effect in game differs. They + work by finding the closest destination "around" the source which is + within a certain distance. This distance depends on the type of station, + e.g. road stops have a smaller catchment area than large airports. + In both cases the bounding box, the smallest rectangle that contains + all tiles of something, is searched for the target of the cargo, + and then spiraling outwards finding the closest tile of the target. - We cannot fix this problem as SDL simply does not provide the - required information in these corner cases. This is a bug in SDL - and as such there is little that we can do about it. + In the case of a station with two tiles spread far apart with a house + that is within the station's bounding box, it would be possible that + the spiraling search from the house does not reach one of the station + tiles before the search ends, i.e. all tiles within that distance + are searched. So the house does not deliver cargo to the station. + On the other hand, the station will deliver cargo because the house + falls within the bounding box, and thus search area. -Inconsistent catchment areas [FS#5661]: - Due to performance decisions the catchment area for cargo accepted - by a station for delivery to houses or industries differs from the - catchment area for cargo that is delivered to stations from houses - or industries. + It is possible to make these consistent, but then cargo from a house + to a station needs to search up to 32 tiles around itself, i.e. 64 + by 64 tiles, to find all possible stations it could deliver to + instead of 10 by 10 tiles (40 times more tiles). Alternatively the + search from a station could be changed to use the actual tiles, but + that would require considering checking 10 by 10 tiles for each of + the tiles of a station, instead of just once. - Conceptually they work the same, but the effect in game differs. - They work by finding the closest destination "around" the source - which is within a certain distance. This distance depends on the - type of station, e.g. road stops have a smaller catchment area than - large airports. In both cases the bounding box, the smallest - rectangle that contains all tiles of something, is searched for the - target of the cargo, and then spiraling outwards finding the closest - tile of the target. +Some houses and industries are not affected by transparency [#5817]: + Some of the default houses and industries (f.e. the iron ore mine) are + not affected by the transparency options. This is because the graphics + do not (completely) separate the ground from the building. + This is a bug of the original graphics, and unfortunately cannot be + fixed with OpenGFX for the sake of maintaining compatibility with + the original graphics. - In the case of a station with two tiles spread far apart with a house - that is within the station's bounding box, it would be possible that - the spiraling search from the house does not reach one of the station - tiles before the search ends, i.e. all tiles within that distance - are searched. So the house does not deliver cargo to the station. On - the other hand, the station will deliver cargo because the house - falls within the bounding box, and thus search area. - - It is possible to make these consistent, but then cargo from a house - to a station needs to search up to 32 tiles around itself, i.e. 64 - by 64 tiles, to find all possible stations it could deliver to - instead of 10 by 10 tiles (40 times more tiles). Alternatively the - search from a station could be changed to use the actual tiles, but - that would require considering checking 10 by 10 tiles for each of - the tiles of a station, instead of just once. - -Trains might not stop at platforms that are currently being changed [FS#5553]: - If you add tiles to or remove tiles from a platform while a train is - approaching to stop at the same platform, that train can miss the place - where it's supposed to stop and pass the station without stopping. This - is caused by the fact that the train is considered to already have stopped - if it's beyond its assigned stopping location. We can't let the train stop - just anywhere in the station because then it would never leave the station - if you have the same station in the order list multiple times in a row or - if there is only one station in the order list (see FS#5684). - -Some houses and industries are not affected by transparency [FS#5817]: - Some of the default houses and industries (f.e. the iron ore mine) are - not affected by the transparency options. This is because the graphics do - not (completely) separate the ground from the building. - This is a bug of the original graphics, and unfortunately cannot be - fixed with OpenGFX for the sake of maintaining compatibility with the - original graphics. - -Involuntary cargo exchange with cargodist via neutral station [FS#6114]: - When two players serve a neutral station at an industry, a cross-company - chain for cargo flow can and will be established which can only be - interrupted if one of the players stops competing for the ressources of - that industry. There is an easy fix for this: If you are loading at the - shared station make the order "no unload" and if you're unloading make - it "no load". Cargodist will then figure out that it should not create - such a route. +Involuntary cargo exchange with cargodist via neutral station [#6114]: + When two players serve a neutral station at an industry, a cross-company + chain for cargo flow can and will be established which can only be + interrupted if one of the players stops competing for the ressources of + that industry. There is an easy fix for this: If you are loading at the + shared station make the order "no unload" and if you're unloading make + it "no load". Cargodist will then figure out that it should not create + such a route. diff --git a/media/baseset/orig_dos.obm b/media/baseset/orig_dos.obm new file mode 100644 index 0000000000..9920bfdbe1 --- /dev/null +++ b/media/baseset/orig_dos.obm @@ -0,0 +1,76 @@ +; $Id$ +; +; This represents the original music as on the Transport +; Tycoon Deluxe for DOS CD. +; +[metadata] +name = original_dos +shortname = TTDD +version = 1 +!! description STR_BASEMUSIC_DOS_DESCRIPTION + +[files] +theme = gm.cat +old_0 = gm.cat +old_1 = gm.cat +old_2 = gm.cat +old_3 = gm.cat +old_4 = gm.cat +old_5 = gm.cat +old_6 = gm.cat +old_7 = gm.cat +old_8 = +old_9 = +new_0 = gm.cat +new_1 = gm.cat +new_2 = gm.cat +new_3 = gm.cat +new_4 = gm.cat +new_5 = gm.cat +new_6 = gm.cat +new_7 = +new_8 = +new_9 = +ezy_0 = gm.cat +ezy_1 = gm.cat +ezy_2 = gm.cat +ezy_3 = gm.cat +ezy_4 = gm.cat +ezy_5 = gm.cat +ezy_6 = +ezy_7 = +ezy_8 = +ezy_9 = + +[md5s] +gm.cat = 7a29d2d0c4f7d2e03091ffa9b2bdfffb + +[catindex] +theme = 0 +old_0 = 1 +old_1 = 8 +old_2 = 2 +old_3 = 9 +old_4 = 14 +old_5 = 15 +old_6 = 19 +old_7 = 13 +new_0 = 6 +new_1 = 11 +new_2 = 10 +new_3 = 17 +new_4 = 21 +new_5 = 18 +new_6 = 5 +ezy_0 = 12 +ezy_1 = 7 +ezy_2 = 16 +ezy_3 = 3 +ezy_4 = 20 +ezy_5 = 4 + +[names] +; Names get read from the CAT file + +[origin] +default = You can find it on your Transport Tycoon Deluxe CD-ROM. diff --git a/media/baseset/orig_tto.obm b/media/baseset/orig_tto.obm new file mode 100644 index 0000000000..ff600d00f6 --- /dev/null +++ b/media/baseset/orig_tto.obm @@ -0,0 +1,71 @@ +; $Id$ +; +; This represents the original music as on the Transport +; Tycoon (with World Editor) for DOS CD. +; +[metadata] +name = original_tto +shortname = TTOD +version = 1 +!! description STR_BASEMUSIC_TTO_DESCRIPTION + +[files] +theme = gm-tto.cat +old_0 = gm-tto.cat +old_1 = gm-tto.cat +old_2 = gm-tto.cat +old_3 = gm-tto.cat +old_4 = gm-tto.cat +old_5 = gm-tto.cat +old_6 = gm-tto.cat +old_7 = gm-tto.cat +old_8 = +old_9 = +new_0 = gm-tto.cat +new_1 = gm-tto.cat +new_2 = gm-tto.cat +new_3 = gm-tto.cat +new_4 = gm-tto.cat +new_5 = gm-tto.cat +new_6 = gm-tto.cat +new_7 = gm-tto.cat +new_8 = +new_9 = +ezy_0 = +ezy_1 = +ezy_2 = +ezy_3 = +ezy_4 = +ezy_5 = +ezy_6 = +ezy_7 = +ezy_8 = +ezy_9 = + +[catindex] +theme = 0 +old_0 = 1 +old_1 = 6 +old_2 = 2 +old_3 = 7 +old_4 = 11 +old_5 = 12 +old_6 = 15 +old_7 = 10 +new_0 = 4 +new_1 = 5 +new_2 = 9 +new_3 = 8 +new_4 = 13 +new_5 = 16 +new_6 = 14 +new_7 = 3 + +[md5s] +gm-tto.cat = 26e85ff84b0063aa5da05dd4698fc76e + +[names] +; Names get read from the CAT file + +[origin] +default = You can find it on your Transport Tycoon CD-ROM. diff --git a/media/baseset/orig_win.obm b/media/baseset/orig_win.obm index 8b35b6de9d..b5d4b024ed 100644 --- a/media/baseset/orig_win.obm +++ b/media/baseset/orig_win.obm @@ -90,5 +90,17 @@ GM_TT19.GM = Funk Central GM_TT20.GM = Jammit GM_TT21.GM = Movin' On +; MIDI timecodes where the playback should attemp to start and stop short. +; This is to allow fixing undesired silences in original MIDI files. +; However not all music drivers may support this. +[timingtrim] +; Theme has two beats silence at the beginning which prevents clean looping. +GM_TT00.GM = 768:53760 +; Can't Get There From Here from the Windows version has a long silence at the end, +; followed by a solo repeat. This isn't in the original DOS version music and is likely +; unintentional from the people who converted the music from the DOS version. +; Actual song ends after measure 152. +GM_TT10.GM = 0:235008 + [origin] default = You can find it on your Transport Tycoon Deluxe CD-ROM. diff --git a/media/extra_grf/openttdgui.png b/media/extra_grf/openttdgui.png index 710adf001b..900a612a87 100644 Binary files a/media/extra_grf/openttdgui.png and b/media/extra_grf/openttdgui.png differ diff --git a/os/debian/changelog b/os/debian/changelog index ce2582128c..bb57ca39e8 100644 --- a/os/debian/changelog +++ b/os/debian/changelog @@ -1,3 +1,15 @@ +openttd (1.8.0-0) unstable; urgency=low + + * New upstream release 1.8.0 + + -- OpenTTD Sun, 01 Apr 2018 14:00:00 +0200 + +openttd (1.8.0~RC1-0) unstable; urgency=low + + * New upstream release 1.8.0-RC1 + + -- OpenTTD Wed, 21 Mar 2018 21:00:00 +0100 + openttd (1.7.2-0) unstable; urgency=low * New upstream release 1.7.2 @@ -1002,4 +1014,3 @@ openttd (0.3.5-1) unstable; urgency=low * Initial Release. -- Matthijs Kooijman Fri, 24 Dec 2004 02:58:47 +0100 - diff --git a/os/windows/installer/install.nsi b/os/windows/installer/install.nsi index cb93d4d04d..2c4c6f94b2 100644 --- a/os/windows/installer/install.nsi +++ b/os/windows/installer/install.nsi @@ -304,6 +304,7 @@ Section /o "Copy data from Transport Tycoon Deluxe CD-ROM" Section2 ; Let's copy the files with size approximation SetOutPath "$INSTDIR\baseset" CopyFiles "$CDDRIVE\gm\*.gm" "$INSTDIR\baseset\" 1028 + CopyFiles "$CDDRIVE\gm.cat" "$INSTDIR\baseset\gm.cat" 415 CopyFiles "$CDDRIVE\sample.cat" "$INSTDIR\baseset\sample.cat" 1566 ; Copy Windows files CopyFiles "$CDDRIVE\trg1r.grf" "$INSTDIR\baseset\trg1r.grf" 2365 @@ -426,6 +427,8 @@ Section "Uninstall" Delete "$INSTDIR\baseset\trgt.grf" Delete "$INSTDIR\baseset\trgc.grf" Delete "$INSTDIR\baseset\trgi.grf" + Delete "$INSTDIR\baseset\gm.cat" + Delete "$INSTDIR\baseset\gm-tto.cat" Delete "$INSTDIR\baseset\*.gm" Delete "$INSTDIR\data\sample.cat" @@ -467,8 +470,10 @@ Section "Uninstall" ; Base sets for music Delete "$INSTDIR\gm\orig_win.obm" + Delete "$INSTDIR\gm\orig_dos.obm" Delete "$INSTDIR\gm\no_music.obm" Delete "$INSTDIR\baseset\orig_win.obm" + Delete "$INSTDIR\baseset\orig_dos.obm" Delete "$INSTDIR\baseset\no_music.obm" ; Remove remaining directories diff --git a/projects/generate b/projects/generate index e82559a911..af59a83fb2 100755 --- a/projects/generate +++ b/projects/generate @@ -40,28 +40,6 @@ fi # generate_vs140.vcxproj is for MSVC 2015 # version_vs140.vcxproj is for MSVC 2015 -# openttd_vs100.sln is for MSVC 2010 -# openttd_vs100.vcxproj is for MSVC 2010 -# openttd_vs100.vcxproj.filters is for MSVC 2010 -# langs_vs100.vcxproj is for MSVC 2010 -# strgen_vs100.vcxproj is for MSVC 2010 -# strgen_vs100.vcxproj.filters is for MSVC 2010 -# generate_vs100.vcxproj is for MSVC 2010 -# version_vs100.vcxproj is for MSVC 2010 - -# openttd_vs90.sln is for MSVC 2008 -# openttd_vs90.vcproj is for MSVC 2008 -# langs_vs90.vcproj is for MSVC 2008 -# strgen_vs90.vcproj is for MSVC 2008 -# generate_vs90.vcproj is for MSVC 2008 -# version_vs90.vcproj is for MSVC 2008 - -# openttd_vs80.sln is for MSVC 2005 -# openttd_vs80.vcproj is for MSVC 2005 -# langs_vs80.vcproj is for MSVC 2005 -# strgen_vs80.vcproj is for MSVC 2005 -# generate_vs80.vcproj is for MSVC 2005 -# version_vs80.vcproj is for MSVC 2005 @@ -74,6 +52,7 @@ enable_dedicated="0" enable_ai="1" with_cocoa="0" enable_directmusic="1" +enable_fluidsynth="0" with_threads="1" file_prefix="..\\\\src\\\\" @@ -123,7 +102,6 @@ load_main_data() { if ($0 == "PNG" && "'$png_config'" == "") { next; } if ($0 == "OSX" && "'$os'" != "OSX") { next; } if ($0 == "OS2" && "'$os'" != "OS2") { next; } - if ($0 == "PSP" && "'$os'" != "PSP") { next; } if ($0 == "DOS" && "'$os'" != "DOS") { next; } if ($0 == "DEDICATED" && "'$enable_dedicated'" != "1") { next; } if ($0 == "AI" && "'$enable_ai'" == "0") { next; } @@ -131,9 +109,9 @@ load_main_data() { if ($0 == "BEOS" && "'$os'" != "BEOS") { next; } if ($0 == "WIN32" && "'$os'" != "MINGW" && "'$os'" != "CYGWIN" && "'$os'" != "MSVC" ) { next; } - if ($0 == "WINCE" && "'$os'" != "WINCE") { next; } if ($0 == "MSVC" && "'$os'" != "MSVC") { next; } if ($0 == "DIRECTMUSIC" && "'$enable_directmusic'" != "1") { next; } + if ($0 == "FLUIDSYNTH" && "'$enable_fluidsynth'" != "1") { next; } if ($0 == "LIBTIMIDITY" && "'$libtimidity'" == "" ) { next; } if ($0 == "HAVE_THREAD" && "'$with_threads'" == "0") { next; } @@ -192,9 +170,11 @@ load_main_data() { load_lang_data() { RES="" - for i in `ls $1` + # Windows Folder sort and Linux Folder sort are slightly different. + # By removing the extension and sorting it on Linux, they are the same. + for i in `ls $1 | sed s~.txt$~~g | sort` do - i=`basename $i | sed s~.txt$~~g` + i=`basename $i` if [ "$i" == "english" ] then continue @@ -320,26 +300,14 @@ settingscommand=`echo "$settings" | grep "^#3" | sed "s~#3~~g"` settingsvcxproj=`echo "$settings" | grep "^#2" | sed "s~#2~~g"` settings=`echo "$settings" | grep "^#1" | sed "s~#1~~g"` -generate "$openttd" "openttd_vs80.vcproj" -generate "$openttd" "openttd_vs90.vcproj" -generate "$openttdvcxproj" "openttd_vs100.vcxproj" -generate "$openttdfiles" "openttd_vs100.vcxproj.filters" "$openttdfilters" generate "$openttdvcxproj" "openttd_vs140.vcxproj" generate "$openttdfiles" "openttd_vs140.vcxproj.filters" "$openttdfilters" generate "$openttdvcxproj" "openttd_vs141.vcxproj" generate "$openttdfiles" "openttd_vs141.vcxproj.filters" "$openttdfilters" -generate "$lang" "langs_vs80.vcproj" -generate "$lang" "langs_vs90.vcproj" -generate "$langvcxproj" "langs_vs100.vcxproj" -generate "$langfiles" "langs_vs100.vcxproj.filters" generate "$langvcxproj" "langs_vs140.vcxproj" generate "$langfiles" "langs_vs140.vcxproj.filters" generate "$langvcxproj" "langs_vs141.vcxproj" generate "$langfiles" "langs_vs141.vcxproj.filters" -generate "$settings" "settings_vs80.vcproj" "$settingscommand" -generate "$settings" "settings_vs90.vcproj" "$settingscommand" -generate "$settingsvcxproj" "settings_vs100.vcxproj" "$settingscommand" -generate "$settingsfiles" "settings_vs100.vcxproj.filters" generate "$settingsvcxproj" "settings_vs140.vcxproj" "$settingscommand" generate "$settingsfiles" "settings_vs140.vcxproj.filters" generate "$settingsvcxproj" "settings_vs141.vcxproj" "$settingscommand" diff --git a/projects/generate.vbs b/projects/generate.vbs index a2f4679a69..5439ed7c0d 100755 --- a/projects/generate.vbs +++ b/projects/generate.vbs @@ -28,29 +28,6 @@ Set FSO = CreateObject("Scripting.FileSystemObject") ' generate_vs140.vcxproj is for MSVC 2015 ' version_vs140.vcxproj is for MSVC 2015 -' openttd_vs100.sln is for MSVC 2010 -' openttd_vs100.vcxproj is for MSVC 2010 -' openttd_vs100.vcxproj.filters is for MSVC 2010 -' langs_vs100.vcxproj is for MSVC 2010 -' strgen_vs100.vcxproj is for MSVC 2010 -' strgen_vs100.vcxproj.filters is for MSVC 2010 -' generate_vs100.vcxproj is for MSVC 2010 -' version_vs100.vcxproj is for MSVC 2010 - -' openttd_vs90.sln is for MSVC 2008 -' openttd_vs90.vcproj is for MSVC 2008 -' langs_vs90.vcproj is for MSVC 2008 -' strgen_vs90.vcproj is for MSVC 2008 -' generate_vs90.vcproj is for MSVC 2008 -' version_vs90.vcproj is for MSVC 2008 - -' openttd_vs80.sln is for MSVC 2005 -' openttd_vs80.vcproj is for MSVC 2005 -' langs_vs80.vcproj is for MSVC 2005 -' strgen_vs80.vcproj is for MSVC 2005 -' generate_vs80.vcproj is for MSVC 2005 -' version_vs80.vcproj is for MSVC 2005 - Sub safety_check(filename) Dim file, line, regexp, list @@ -383,10 +360,6 @@ headers_check ROOT_DIR & "/source.list", ROOT_DIR & "\src\" ' Backslashes needed Dim openttd, openttdvcxproj, openttdfilters, openttdfiles openttd = load_main_data(ROOT_DIR & "/source.list", openttdvcxproj, openttdfilters, openttdfiles) -generate openttd, ROOT_DIR & "/projects/openttd_vs80.vcproj", Null -generate openttd, ROOT_DIR & "/projects/openttd_vs90.vcproj", Null -generate openttdvcxproj, ROOT_DIR & "/projects/openttd_vs100.vcxproj", Null -generate openttdfiles, ROOT_DIR & "/projects/openttd_vs100.vcxproj.filters", openttdfilters generate openttdvcxproj, ROOT_DIR & "/projects/openttd_vs140.vcxproj", Null generate openttdfiles, ROOT_DIR & "/projects/openttd_vs140.vcxproj.filters", openttdfilters generate openttdvcxproj, ROOT_DIR & "/projects/openttd_vs141.vcxproj", Null @@ -394,10 +367,6 @@ generate openttdfiles, ROOT_DIR & "/projects/openttd_vs141.vcxproj.filters", ope Dim lang, langvcxproj, langfiles lang = load_lang_data(ROOT_DIR & "/src/lang", langvcxproj, langfiles) -generate lang, ROOT_DIR & "/projects/langs_vs80.vcproj", Null -generate lang, ROOT_DIR & "/projects/langs_vs90.vcproj", Null -generate langvcxproj, ROOT_DIR & "/projects/langs_vs100.vcxproj", Null -generate langfiles, ROOT_DIR & "/projects/langs_vs100.vcxproj.filters", Null generate langvcxproj, ROOT_DIR & "/projects/langs_vs140.vcxproj", Null generate langfiles, ROOT_DIR & "/projects/langs_vs140.vcxproj.filters", Null generate langvcxproj, ROOT_DIR & "/projects/langs_vs141.vcxproj", Null @@ -405,10 +374,6 @@ generate langfiles, ROOT_DIR & "/projects/langs_vs141.vcxproj.filters", Null Dim settings, settingsvcxproj, settingscommand, settingsfiles settings = load_settings_data(ROOT_DIR & "/src/table", settingsvcxproj, settingscommand, settingsfiles) -generate settings, ROOT_DIR & "/projects/settings_vs80.vcproj", settingscommand -generate settings, ROOT_DIR & "/projects/settings_vs90.vcproj", settingscommand -generate settingsvcxproj, ROOT_DIR & "/projects/settings_vs100.vcxproj", settingscommand -generate settingsfiles, ROOT_DIR & "/projects/settings_vs100.vcxproj.filters", Null generate settingsvcxproj, ROOT_DIR & "/projects/settings_vs140.vcxproj", settingscommand generate settingsfiles, ROOT_DIR & "/projects/settings_vs140.vcxproj.filters", Null generate settingsvcxproj, ROOT_DIR & "/projects/settings_vs141.vcxproj", settingscommand diff --git a/projects/generate_vs100.vcxproj b/projects/generate_vs100.vcxproj deleted file mode 100644 index 4417308e60..0000000000 --- a/projects/generate_vs100.vcxproj +++ /dev/null @@ -1,42 +0,0 @@ - - - - - Debug - Win32 - - - - generate - {2F31FD79-D1AC-43C4-89F3-B0D5E4E53E34} - generate - - - - Utility - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - - - - - - Document - Running %27generate.vbs%27 ... - cscript "$(ProjectDir)generate.vbs" - %(FullPath);%(AdditionalInputs) - $(SolutionDir)openttd_vs80.vcproj;$(SolutionDir)openttd_vs90.vcproj;$(SolutionDir)openttd_vs100.vcxproj;$(SolutionDir)openttd_vs100.vcxproj.filters;$(SolutionDir)langs_vs80.vcproj;$(SolutionDir)langs_vs90.vcproj;$(SolutionDir)langs_vs100.vcxproj;%(Outputs) - - - - - - diff --git a/projects/generate_vs140.vcxproj b/projects/generate_vs140.vcxproj index 67b1b7712c..e505315153 100644 --- a/projects/generate_vs140.vcxproj +++ b/projects/generate_vs140.vcxproj @@ -37,4 +37,4 @@ - \ No newline at end of file + diff --git a/projects/generate_vs80.vcproj b/projects/generate_vs80.vcproj deleted file mode 100644 index bc0b6c44c7..0000000000 --- a/projects/generate_vs80.vcproj +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/projects/generate_vs90.vcproj b/projects/generate_vs90.vcproj deleted file mode 100644 index dc7b3e2f56..0000000000 --- a/projects/generate_vs90.vcproj +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/projects/langs_vs100.vcxproj b/projects/langs_vs100.vcxproj deleted file mode 100644 index fc77e03bec..0000000000 --- a/projects/langs_vs100.vcxproj +++ /dev/null @@ -1,390 +0,0 @@ - - - - - Debug - Win32 - - - - langs - {0F066B23-18DF-4284-8265-F4A5E7E3B966} - langs - MakeFileProj - - - - Utility - false - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - ..\bin\lang\ - ..\objs\langs\ - - - - Generating strings.h - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\objs\langs\table - - - ./langs.tlb - - - - - - - Generating english language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\english.lng;%(Outputs) - - - Generating afrikaans language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\afrikaans.lng;%(Outputs) - - - Generating arabic_egypt language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\arabic_egypt.lng;%(Outputs) - - - Generating basque language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\basque.lng;%(Outputs) - - - Generating belarusian language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\belarusian.lng;%(Outputs) - - - Generating brazilian_portuguese language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\brazilian_portuguese.lng;%(Outputs) - - - Generating bulgarian language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\bulgarian.lng;%(Outputs) - - - Generating catalan language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\catalan.lng;%(Outputs) - - - Generating croatian language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\croatian.lng;%(Outputs) - - - Generating czech language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\czech.lng;%(Outputs) - - - Generating danish language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\danish.lng;%(Outputs) - - - Generating dutch language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\dutch.lng;%(Outputs) - - - Generating english_AU language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\english_AU.lng;%(Outputs) - - - Generating english_US language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\english_US.lng;%(Outputs) - - - Generating esperanto language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\esperanto.lng;%(Outputs) - - - Generating estonian language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\estonian.lng;%(Outputs) - - - Generating faroese language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\faroese.lng;%(Outputs) - - - Generating finnish language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\finnish.lng;%(Outputs) - - - Generating french language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\french.lng;%(Outputs) - - - Generating gaelic language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\gaelic.lng;%(Outputs) - - - Generating galician language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\galician.lng;%(Outputs) - - - Generating german language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\german.lng;%(Outputs) - - - Generating greek language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\greek.lng;%(Outputs) - - - Generating hebrew language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\hebrew.lng;%(Outputs) - - - Generating hungarian language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\hungarian.lng;%(Outputs) - - - Generating icelandic language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\icelandic.lng;%(Outputs) - - - Generating indonesian language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\indonesian.lng;%(Outputs) - - - Generating irish language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\irish.lng;%(Outputs) - - - Generating italian language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\italian.lng;%(Outputs) - - - Generating japanese language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\japanese.lng;%(Outputs) - - - Generating korean language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\korean.lng;%(Outputs) - - - Generating latin language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\latin.lng;%(Outputs) - - - Generating latvian language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\latvian.lng;%(Outputs) - - - Generating lithuanian language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\lithuanian.lng;%(Outputs) - - - Generating luxembourgish language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\luxembourgish.lng;%(Outputs) - - - Generating malay language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\malay.lng;%(Outputs) - - - Generating norwegian_bokmal language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\norwegian_bokmal.lng;%(Outputs) - - - Generating norwegian_nynorsk language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\norwegian_nynorsk.lng;%(Outputs) - - - Generating polish language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\polish.lng;%(Outputs) - - - Generating portuguese language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\portuguese.lng;%(Outputs) - - - Generating romanian language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\romanian.lng;%(Outputs) - - - Generating russian language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\russian.lng;%(Outputs) - - - Generating serbian language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\serbian.lng;%(Outputs) - - - Generating simplified_chinese language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\simplified_chinese.lng;%(Outputs) - - - Generating slovak language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\slovak.lng;%(Outputs) - - - Generating slovenian language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\slovenian.lng;%(Outputs) - - - Generating spanish_MX language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\spanish_MX.lng;%(Outputs) - - - Generating spanish language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\spanish.lng;%(Outputs) - - - Generating swedish language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\swedish.lng;%(Outputs) - - - Generating tamil language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\tamil.lng;%(Outputs) - - - Generating thai language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\thai.lng;%(Outputs) - - - Generating traditional_chinese language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\traditional_chinese.lng;%(Outputs) - - - Generating turkish language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\turkish.lng;%(Outputs) - - - Generating ukrainian language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\ukrainian.lng;%(Outputs) - - - Generating vietnamese language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\vietnamese.lng;%(Outputs) - - - Generating welsh language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\welsh.lng;%(Outputs) - - - - - {a133a442-bd0a-4ade-b117-ad7545e4bdd1} - false - - - - - - diff --git a/projects/langs_vs100.vcxproj.filters b/projects/langs_vs100.vcxproj.filters deleted file mode 100644 index 0afc8c969a..0000000000 --- a/projects/langs_vs100.vcxproj.filters +++ /dev/null @@ -1,176 +0,0 @@ - - - - - {2a164580-9033-4a01-974b-b21da507efda} - - - - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - Translations - - - diff --git a/projects/langs_vs100.vcxproj.filters.in b/projects/langs_vs100.vcxproj.filters.in deleted file mode 100644 index 0d60ee9595..0000000000 --- a/projects/langs_vs100.vcxproj.filters.in +++ /dev/null @@ -1,12 +0,0 @@ - - - - - {2a164580-9033-4a01-974b-b21da507efda} - - - - -!!FILES!! - - diff --git a/projects/langs_vs100.vcxproj.in b/projects/langs_vs100.vcxproj.in deleted file mode 100644 index 5bfec8bf0f..0000000000 --- a/projects/langs_vs100.vcxproj.in +++ /dev/null @@ -1,61 +0,0 @@ - - - - - Debug - Win32 - - - - langs - {0F066B23-18DF-4284-8265-F4A5E7E3B966} - langs - MakeFileProj - - - - Utility - false - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - ..\bin\lang\ - ..\objs\langs\ - - - - Generating strings.h - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\objs\langs\table - - - ./langs.tlb - - - - - - - Generating english language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\english.lng;%(Outputs) - -!!FILES!! - - - - {a133a442-bd0a-4ade-b117-ad7545e4bdd1} - false - - - - - - diff --git a/projects/langs_vs140.vcxproj b/projects/langs_vs140.vcxproj index 317fd34a11..25e7160bfb 100644 --- a/projects/langs_vs140.vcxproj +++ b/projects/langs_vs140.vcxproj @@ -317,18 +317,18 @@ ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) ..\bin\lang\slovenian.lng;%(Outputs) - - Generating spanish_MX language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\spanish_MX.lng;%(Outputs) - Generating spanish language file ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) ..\bin\lang\spanish.lng;%(Outputs) + + Generating spanish_MX language file + ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" + ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) + ..\bin\lang\spanish_MX.lng;%(Outputs) + Generating swedish language file ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" diff --git a/projects/langs_vs140.vcxproj.filters b/projects/langs_vs140.vcxproj.filters index 0afc8c969a..bf5257ec82 100644 --- a/projects/langs_vs140.vcxproj.filters +++ b/projects/langs_vs140.vcxproj.filters @@ -142,10 +142,10 @@ Translations - + Translations - + Translations diff --git a/projects/langs_vs141.vcxproj b/projects/langs_vs141.vcxproj index 2444b0e0e7..c554c6e378 100644 --- a/projects/langs_vs141.vcxproj +++ b/projects/langs_vs141.vcxproj @@ -317,18 +317,18 @@ ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) ..\bin\lang\slovenian.lng;%(Outputs) - - Generating spanish_MX language file - ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" - ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) - ..\bin\lang\spanish_MX.lng;%(Outputs) - Generating spanish language file ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) ..\bin\lang\spanish.lng;%(Outputs) + + Generating spanish_MX language file + ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" + ..\src\lang\english.txt;..\objs\strgen\strgen.exe;%(AdditionalInputs) + ..\bin\lang\spanish_MX.lng;%(Outputs) + Generating swedish language file ..\objs\strgen\strgen.exe -s ..\src\lang -d ..\bin\lang "%(FullPath)" diff --git a/projects/langs_vs141.vcxproj.filters b/projects/langs_vs141.vcxproj.filters index 0afc8c969a..bf5257ec82 100644 --- a/projects/langs_vs141.vcxproj.filters +++ b/projects/langs_vs141.vcxproj.filters @@ -142,10 +142,10 @@ Translations - + Translations - + Translations diff --git a/projects/langs_vs80.vcproj b/projects/langs_vs80.vcproj deleted file mode 100644 index e683d57353..0000000000 --- a/projects/langs_vs80.vcproj +++ /dev/null @@ -1,895 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/projects/langs_vs80.vcproj.in b/projects/langs_vs80.vcproj.in deleted file mode 100644 index 548a0b0179..0000000000 --- a/projects/langs_vs80.vcproj.in +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -!!FILES!! - - - - - diff --git a/projects/langs_vs90.vcproj b/projects/langs_vs90.vcproj deleted file mode 100644 index c1f028233e..0000000000 --- a/projects/langs_vs90.vcproj +++ /dev/null @@ -1,896 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/projects/langs_vs90.vcproj.in b/projects/langs_vs90.vcproj.in deleted file mode 100644 index f03b231fc3..0000000000 --- a/projects/langs_vs90.vcproj.in +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -!!FILES!! - - - - - diff --git a/projects/openttd_vs100.sln b/projects/openttd_vs100.sln deleted file mode 100644 index a2ec939d30..0000000000 --- a/projects/openttd_vs100.sln +++ /dev/null @@ -1,91 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual C++ Express 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openttd", "openttd_vs100.vcxproj", "{668328A0-B40E-4CDB-BD72-D0064424414A}" - ProjectSection(ProjectDependencies) = postProject - {0817F629-589E-4A3B-B81A-8647BC571E35} = {0817F629-589E-4A3B-B81A-8647BC571E35} - {E9548DE9-F089-49B7-93A6-30BE2CC311C7} = {E9548DE9-F089-49B7-93A6-30BE2CC311C7} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "strgen", "strgen_vs100.vcxproj", "{A133A442-BD0A-4ADE-B117-AD7545E4BDD1}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "langs", "langs_vs100.vcxproj", "{0F066B23-18DF-4284-8265-F4A5E7E3B966}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "version", "version_vs100.vcxproj", "{1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "generate", "generate_vs100.vcxproj", "{2F31FD79-D1AC-43C4-89F3-B0D5E4E53E34}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "settings", "settings_vs100.vcxproj", "{0817F629-589E-4A3B-B81A-8647BC571E35}" - ProjectSection(ProjectDependencies) = postProject - {E9548DE9-F089-49B7-93A6-30BE2CC311C7} = {E9548DE9-F089-49B7-93A6-30BE2CC311C7} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "settingsgen", "settingsgen_vs100.vcxproj", "{E9548DE9-F089-49B7-93A6-30BE2CC311C7}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {668328A0-B40E-4CDB-BD72-D0064424414A}.Debug|Win32.ActiveCfg = Debug|Win32 - {668328A0-B40E-4CDB-BD72-D0064424414A}.Debug|Win32.Build.0 = Debug|Win32 - {668328A0-B40E-4CDB-BD72-D0064424414A}.Debug|x64.ActiveCfg = Debug|x64 - {668328A0-B40E-4CDB-BD72-D0064424414A}.Debug|x64.Build.0 = Debug|x64 - {668328A0-B40E-4CDB-BD72-D0064424414A}.Release|Win32.ActiveCfg = Release|Win32 - {668328A0-B40E-4CDB-BD72-D0064424414A}.Release|Win32.Build.0 = Release|Win32 - {668328A0-B40E-4CDB-BD72-D0064424414A}.Release|x64.ActiveCfg = Release|x64 - {668328A0-B40E-4CDB-BD72-D0064424414A}.Release|x64.Build.0 = Release|x64 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Debug|Win32.ActiveCfg = Debug|Win32 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Debug|Win32.Build.0 = Debug|Win32 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Debug|x64.ActiveCfg = Debug|Win32 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Debug|x64.Build.0 = Debug|Win32 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Release|Win32.ActiveCfg = Debug|Win32 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Release|Win32.Build.0 = Debug|Win32 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Release|x64.ActiveCfg = Debug|Win32 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Release|x64.Build.0 = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Debug|Win32.ActiveCfg = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Debug|Win32.Build.0 = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Debug|x64.ActiveCfg = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Debug|x64.Build.0 = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Release|Win32.ActiveCfg = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Release|Win32.Build.0 = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Release|x64.ActiveCfg = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Release|x64.Build.0 = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Debug|Win32.ActiveCfg = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Debug|Win32.Build.0 = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Debug|x64.ActiveCfg = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Debug|x64.Build.0 = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Release|Win32.ActiveCfg = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Release|Win32.Build.0 = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Release|x64.ActiveCfg = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Release|x64.Build.0 = Debug|Win32 - {2F31FD79-D1AC-43C4-89F3-B0D5E4E53E34}.Debug|Win32.ActiveCfg = Debug|Win32 - {2F31FD79-D1AC-43C4-89F3-B0D5E4E53E34}.Debug|x64.ActiveCfg = Debug|Win32 - {2F31FD79-D1AC-43C4-89F3-B0D5E4E53E34}.Release|Win32.ActiveCfg = Debug|Win32 - {2F31FD79-D1AC-43C4-89F3-B0D5E4E53E34}.Release|x64.ActiveCfg = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Debug|Win32.ActiveCfg = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Debug|Win32.Build.0 = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Debug|x64.ActiveCfg = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Debug|x64.Build.0 = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Release|Win32.ActiveCfg = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Release|Win32.Build.0 = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Release|x64.ActiveCfg = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Release|x64.Build.0 = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Debug|Win32.ActiveCfg = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Debug|Win32.Build.0 = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Debug|x64.ActiveCfg = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Debug|x64.Build.0 = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Release|Win32.ActiveCfg = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Release|Win32.Build.0 = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Release|x64.ActiveCfg = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Release|x64.Build.0 = Debug|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(DPCodeReviewSolutionGUID) = preSolution - DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000} - EndGlobalSection -EndGlobal diff --git a/projects/openttd_vs100.vcxproj.filters.in b/projects/openttd_vs100.vcxproj.filters.in deleted file mode 100644 index 126bd61459..0000000000 --- a/projects/openttd_vs100.vcxproj.filters.in +++ /dev/null @@ -1,13 +0,0 @@ - - - -!!FILTERS!! - - -!!FILES!! - - - - - - diff --git a/projects/openttd_vs100.vcxproj.in b/projects/openttd_vs100.vcxproj.in deleted file mode 100644 index ab2ae133af..0000000000 --- a/projects/openttd_vs100.vcxproj.in +++ /dev/null @@ -1,339 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - openttd - {668328A0-B40E-4CDB-BD72-D0064424414A} - openttd - - - - Application - false - Unicode - - - Application - false - Unicode - true - - - Application - false - Unicode - - - Application - false - Unicode - true - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(SolutionDir)..\objs\$(Platform)\$(Configuration)\ - $(SolutionDir)..\objs\$(Platform)\$(Configuration)\ - false - $(SolutionDir)..\objs\$(Platform)\$(Configuration)\ - $(SolutionDir)..\objs\$(Platform)\$(Configuration)\ - - $(SolutionDir)..\objs\$(Platform)\$(Configuration)\ - false - $(SolutionDir)..\objs\$(Platform)\$(Configuration)\ - $(SolutionDir)..\objs\$(Platform)\$(Configuration)\ - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - $(SolutionDir)..\objs\$(Platform)\$(Configuration)\ - $(ProjectDir)..\bin - - - - .\Release/openttd.tlb - - - - - /MP /J %(AdditionalOptions) - Full - AnySuitable - true - Size - true - ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU_SORT;WITH_ICU_LAYOUT;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions) - true - Sync - MultiThreaded - 4Bytes - false - true - - - - - - - All - $(IntDir) - $(IntDir) - $(IntDir)$(TargetName).pdb - Level3 - false - true - ProgramDatabase - FastCall - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0809 - - - winmm.lib;ws2_32.lib;imm32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) - true - %(IgnoreSpecificDefaultLibraries) - true - Windows - 1048576 - 1048576 - true - false - - - MachineX86 - true - - - dpi_aware.manifest;os_versions.manifest - - - copy "$(OutDir)$(TargetName)$(TargetExt)" "$(SolutionDir)..\bin\$(TargetName)$(TargetExt)" - - - - - .\Debug/openttd.tlb - - - - - /MP %(AdditionalOptions) - Disabled - ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU_SORT;WITH_ICU_LAYOUT;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebug - - - $(IntDir) - $(IntDir) - $(IntDir)$(TargetName).pdb - Level3 - false - true - EditAndContinue - FastCall - Default - - - _DEBUG;%(PreprocessorDefinitions) - 0x0809 - - - winmm.lib;ws2_32.lib;imm32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) - true - LIBCMT.lib;%(IgnoreSpecificDefaultLibraries) - true - Windows - 1048576 - 1048576 - false - - - MachineX86 - - - dpi_aware.manifest;os_versions.manifest - - - copy "$(OutDir)$(TargetName)$(TargetExt)" "$(SolutionDir)..\bin\$(TargetName)$(TargetExt)" - - - - - X64 - .\Release/openttd.tlb - - - - - /MP /J %(AdditionalOptions) - Full - AnySuitable - true - Size - true - ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU_SORT;WITH_ICU_LAYOUT;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions) - true - Sync - MultiThreaded - Default - false - true - - - - - - - All - $(IntDir) - $(IntDir) - $(IntDir)$(TargetName).pdb - Level3 - false - true - ProgramDatabase - FastCall - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0809 - - - winmm.lib;ws2_32.lib;imm32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) - true - %(IgnoreSpecificDefaultLibraries) - true - Windows - 1048576 - 1048576 - true - MachineX64 - true - - - dpi_aware.manifest;os_versions.manifest - - - copy "$(OutDir)$(TargetName)$(TargetExt)" "$(SolutionDir)..\bin\$(TargetName)$(TargetExt)" - - - - - X64 - .\Debug/openttd.tlb - - - - - /MP %(AdditionalOptions) - Disabled - ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU_SORT;WITH_ICU_LAYOUT;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebug - - - - - - - $(IntDir) - $(IntDir) - $(IntDir)$(TargetName).pdb - Level3 - false - true - ProgramDatabase - Cdecl - Default - - - _DEBUG;%(PreprocessorDefinitions) - 0x0809 - - - winmm.lib;ws2_32.lib;imm32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) - true - LIBCMT.lib;%(IgnoreSpecificDefaultLibraries) - true - Windows - 1048576 - 1048576 - MachineX64 - - - dpi_aware.manifest;os_versions.manifest - - - copy "$(OutDir)$(TargetName)$(TargetExt)" "$(SolutionDir)..\bin\$(TargetName)$(TargetExt)" - - - -!!FILES!! - - - - - - - - {0f066b23-18df-4284-8265-f4a5e7e3b966} - false - - - {a133a442-bd0a-4ade-b117-ad7545e4bdd1} - false - - - {1a2b3c5e-1c23-41a5-9c9b-acba2aa75fec} - false - - - - diff --git a/projects/openttd_vs140.sln b/projects/openttd_vs140.sln index d256cfa495..32f3033fb2 100644 --- a/projects/openttd_vs140.sln +++ b/projects/openttd_vs140.sln @@ -24,6 +24,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "settings", "settings_vs140. EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "settingsgen", "settingsgen_vs140.vcxproj", "{E9548DE9-F089-49B7-93A6-30BE2CC311C7}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "regression", "regression_vs140.vcxproj", "{4712B013-437D-42CE-947F-DEBABA15261F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -84,6 +86,10 @@ Global {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Release|Win32.Build.0 = Debug|Win32 {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Release|x64.ActiveCfg = Debug|Win32 {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Release|x64.Build.0 = Debug|Win32 + {4712B013-437D-42CE-947F-DEBABA15261F}.Debug|Win32.ActiveCfg = Debug|Win32 + {4712B013-437D-42CE-947F-DEBABA15261F}.Debug|x64.ActiveCfg = Debug|Win32 + {4712B013-437D-42CE-947F-DEBABA15261F}.Release|Win32.ActiveCfg = Debug|Win32 + {4712B013-437D-42CE-947F-DEBABA15261F}.Release|x64.ActiveCfg = Debug|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/projects/openttd_vs140.vcxproj b/projects/openttd_vs140.vcxproj index e4380931a3..4a93a0440f 100644 --- a/projects/openttd_vs140.vcxproj +++ b/projects/openttd_vs140.vcxproj @@ -22,6 +22,8 @@ openttd {668328A0-B40E-4CDB-BD72-D0064424414A} openttd + x86-windows-static + x64-windows-static @@ -105,7 +107,7 @@ Size true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU_SORT;WITH_ICU_LAYOUT;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions) true Sync MultiThreaded @@ -136,7 +138,7 @@ 0x0809 - winmm.lib;ws2_32.lib;imm32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;imm32.lib;%(AdditionalDependencies) true %(IgnoreSpecificDefaultLibraries) true @@ -170,7 +172,7 @@ Disabled true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU_SORT;WITH_ICU_LAYOUT;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -192,7 +194,7 @@ 0x0809 - winmm.lib;ws2_32.lib;imm32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;imm32.lib;%(AdditionalDependencies) true LIBCMT.lib;%(IgnoreSpecificDefaultLibraries) true @@ -228,7 +230,7 @@ Size true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU_SORT;WITH_ICU_LAYOUT;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions) true Sync MultiThreaded @@ -259,7 +261,7 @@ 0x0809 - winmm.lib;ws2_32.lib;imm32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;imm32.lib;%(AdditionalDependencies) true %(IgnoreSpecificDefaultLibraries) true @@ -291,7 +293,7 @@ Disabled true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU_SORT;WITH_ICU_LAYOUT;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -317,7 +319,7 @@ 0x0809 - winmm.lib;ws2_32.lib;imm32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;imm32.lib;%(AdditionalDependencies) true LIBCMT.lib;%(IgnoreSpecificDefaultLibraries) true @@ -502,6 +504,7 @@ + @@ -590,6 +593,8 @@ + + @@ -651,6 +656,7 @@ + @@ -704,6 +710,7 @@ + @@ -751,6 +758,7 @@ + @@ -812,6 +820,7 @@ + @@ -1170,6 +1179,8 @@ + + @@ -1314,12 +1325,15 @@ + + + diff --git a/projects/openttd_vs140.vcxproj.filters b/projects/openttd_vs140.vcxproj.filters index ef11613ff8..911a53a864 100644 --- a/projects/openttd_vs140.vcxproj.filters +++ b/projects/openttd_vs140.vcxproj.filters @@ -600,6 +600,9 @@ Header Files + + Header Files + Header Files @@ -864,6 +867,12 @@ Header Files + + Header Files + + + Header Files + Header Files @@ -1047,6 +1056,9 @@ Header Files + + Header Files + Header Files @@ -1206,6 +1218,9 @@ Header Files + + Header Files + Header Files @@ -1347,6 +1362,9 @@ GUI Source Code + + GUI Source Code + GUI Source Code @@ -1530,6 +1548,9 @@ Widgets + + Widgets + Widgets @@ -2604,6 +2625,12 @@ Blitters + + Blitters + + + Blitters + Blitters @@ -3036,6 +3063,9 @@ Music + + Music + Music @@ -3048,12 +3078,18 @@ Sound + + Sound + Windows files Windows files + + Windows files + Windows files diff --git a/projects/openttd_vs140.vcxproj.in b/projects/openttd_vs140.vcxproj.in index 1e490d29e7..75aac94bab 100644 --- a/projects/openttd_vs140.vcxproj.in +++ b/projects/openttd_vs140.vcxproj.in @@ -22,6 +22,8 @@ openttd {668328A0-B40E-4CDB-BD72-D0064424414A} openttd + x86-windows-static + x64-windows-static @@ -105,7 +107,7 @@ Size true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU_SORT;WITH_ICU_LAYOUT;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions) true Sync MultiThreaded @@ -136,7 +138,7 @@ 0x0809 - winmm.lib;ws2_32.lib;imm32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;imm32.lib;%(AdditionalDependencies) true %(IgnoreSpecificDefaultLibraries) true @@ -170,7 +172,7 @@ Disabled true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU_SORT;WITH_ICU_LAYOUT;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -192,7 +194,7 @@ 0x0809 - winmm.lib;ws2_32.lib;imm32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;imm32.lib;%(AdditionalDependencies) true LIBCMT.lib;%(IgnoreSpecificDefaultLibraries) true @@ -228,7 +230,7 @@ Size true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU_SORT;WITH_ICU_LAYOUT;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions) true Sync MultiThreaded @@ -259,7 +261,7 @@ 0x0809 - winmm.lib;ws2_32.lib;imm32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;imm32.lib;%(AdditionalDependencies) true %(IgnoreSpecificDefaultLibraries) true @@ -291,7 +293,7 @@ Disabled true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU_SORT;WITH_ICU_LAYOUT;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -317,7 +319,7 @@ 0x0809 - winmm.lib;ws2_32.lib;imm32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;imm32.lib;%(AdditionalDependencies) true LIBCMT.lib;%(IgnoreSpecificDefaultLibraries) true diff --git a/projects/openttd_vs141.sln b/projects/openttd_vs141.sln index e314c628a7..86f2685cd9 100644 --- a/projects/openttd_vs141.sln +++ b/projects/openttd_vs141.sln @@ -24,6 +24,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "settings", "settings_vs141. EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "settingsgen", "settingsgen_vs141.vcxproj", "{E9548DE9-F089-49B7-93A6-30BE2CC311C7}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "regression", "regression_vs141.vcxproj", "{4712B013-437D-42CE-947F-DEBABA15261F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -84,6 +86,10 @@ Global {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Release|Win32.Build.0 = Debug|Win32 {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Release|x64.ActiveCfg = Debug|Win32 {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Release|x64.Build.0 = Debug|Win32 + {4712B013-437D-42CE-947F-DEBABA15261F}.Debug|Win32.ActiveCfg = Debug|Win32 + {4712B013-437D-42CE-947F-DEBABA15261F}.Debug|x64.ActiveCfg = Debug|Win32 + {4712B013-437D-42CE-947F-DEBABA15261F}.Release|Win32.ActiveCfg = Debug|Win32 + {4712B013-437D-42CE-947F-DEBABA15261F}.Release|x64.ActiveCfg = Debug|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/projects/openttd_vs141.vcxproj b/projects/openttd_vs141.vcxproj index bba72864b2..958f44227e 100644 --- a/projects/openttd_vs141.vcxproj +++ b/projects/openttd_vs141.vcxproj @@ -22,6 +22,8 @@ openttd {668328A0-B40E-4CDB-BD72-D0064424414A} openttd + x86-windows-static + x64-windows-static @@ -105,7 +107,7 @@ Size true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU_SORT;WITH_ICU_LAYOUT;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions) true Sync MultiThreaded @@ -136,7 +138,7 @@ 0x0809 - winmm.lib;ws2_32.lib;imm32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;imm32.lib;%(AdditionalDependencies) true %(IgnoreSpecificDefaultLibraries) true @@ -170,7 +172,7 @@ Disabled true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU_SORT;WITH_ICU_LAYOUT;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -192,7 +194,7 @@ 0x0809 - winmm.lib;ws2_32.lib;imm32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;imm32.lib;%(AdditionalDependencies) true LIBCMT.lib;%(IgnoreSpecificDefaultLibraries) true @@ -228,7 +230,7 @@ Size true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU_SORT;WITH_ICU_LAYOUT;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions) true Sync MultiThreaded @@ -259,7 +261,7 @@ 0x0809 - winmm.lib;ws2_32.lib;imm32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;imm32.lib;%(AdditionalDependencies) true %(IgnoreSpecificDefaultLibraries) true @@ -291,7 +293,7 @@ Disabled true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU_SORT;WITH_ICU_LAYOUT;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -317,7 +319,7 @@ 0x0809 - winmm.lib;ws2_32.lib;imm32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;imm32.lib;%(AdditionalDependencies) true LIBCMT.lib;%(IgnoreSpecificDefaultLibraries) true @@ -502,6 +504,7 @@ + @@ -590,6 +593,8 @@ + + @@ -616,6 +621,7 @@ + @@ -650,6 +656,7 @@ + @@ -703,6 +710,7 @@ + @@ -711,6 +719,8 @@ + + @@ -748,6 +758,7 @@ + @@ -809,6 +820,7 @@ + @@ -1167,6 +1179,8 @@ + + @@ -1311,12 +1325,15 @@ + + + diff --git a/projects/openttd_vs141.vcxproj.filters b/projects/openttd_vs141.vcxproj.filters index d502733796..911a53a864 100644 --- a/projects/openttd_vs141.vcxproj.filters +++ b/projects/openttd_vs141.vcxproj.filters @@ -600,6 +600,9 @@ Header Files + + Header Files + Header Files @@ -864,6 +867,12 @@ Header Files + + Header Files + + + Header Files + Header Files @@ -942,6 +951,9 @@ Header Files + + Header Files + Header Files @@ -1044,6 +1056,9 @@ Header Files + + Header Files + Header Files @@ -1203,6 +1218,9 @@ Header Files + + Header Files + Header Files @@ -1227,6 +1245,12 @@ Core Source Code + + Core Source Code + + + Core Source Code + Core Source Code @@ -1338,6 +1362,9 @@ GUI Source Code + + GUI Source Code + GUI Source Code @@ -1521,6 +1548,9 @@ Widgets + + Widgets + Widgets @@ -2595,6 +2625,12 @@ Blitters + + Blitters + + + Blitters + Blitters @@ -3027,6 +3063,9 @@ Music + + Music + Music @@ -3039,12 +3078,18 @@ Sound + + Sound + Windows files Windows files + + Windows files + Windows files diff --git a/projects/openttd_vs141.vcxproj.in b/projects/openttd_vs141.vcxproj.in index f4ec557c60..a054c2580e 100644 --- a/projects/openttd_vs141.vcxproj.in +++ b/projects/openttd_vs141.vcxproj.in @@ -22,6 +22,8 @@ openttd {668328A0-B40E-4CDB-BD72-D0064424414A} openttd + x86-windows-static + x64-windows-static @@ -105,7 +107,7 @@ Size true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU_SORT;WITH_ICU_LAYOUT;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions) true Sync MultiThreaded @@ -136,7 +138,7 @@ 0x0809 - winmm.lib;ws2_32.lib;imm32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;imm32.lib;%(AdditionalDependencies) true %(IgnoreSpecificDefaultLibraries) true @@ -170,7 +172,7 @@ Disabled true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU_SORT;WITH_ICU_LAYOUT;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -192,7 +194,7 @@ 0x0809 - winmm.lib;ws2_32.lib;imm32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;imm32.lib;%(AdditionalDependencies) true LIBCMT.lib;%(IgnoreSpecificDefaultLibraries) true @@ -228,7 +230,7 @@ Size true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU_SORT;WITH_ICU_LAYOUT;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions) true Sync MultiThreaded @@ -259,7 +261,7 @@ 0x0809 - winmm.lib;ws2_32.lib;imm32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;imm32.lib;%(AdditionalDependencies) true %(IgnoreSpecificDefaultLibraries) true @@ -291,7 +293,7 @@ Disabled true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU_SORT;WITH_ICU_LAYOUT;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -317,7 +319,7 @@ 0x0809 - winmm.lib;ws2_32.lib;imm32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;imm32.lib;%(AdditionalDependencies) true LIBCMT.lib;%(IgnoreSpecificDefaultLibraries) true diff --git a/projects/openttd_vs80.sln b/projects/openttd_vs80.sln deleted file mode 100644 index 9e6dd1219d..0000000000 --- a/projects/openttd_vs80.sln +++ /dev/null @@ -1,95 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual C++ Express 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openttd", "openttd_vs80.vcproj", "{668328A0-B40E-4CDB-BD72-D0064424414A}" - ProjectSection(ProjectDependencies) = postProject - {0F066B23-18DF-4284-8265-F4A5E7E3B966} = {0F066B23-18DF-4284-8265-F4A5E7E3B966} - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC} = {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC} - {0817F629-589E-4A3B-B81A-8647BC571E35} = {0817F629-589E-4A3B-B81A-8647BC571E35} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "strgen", "strgen_vs80.vcproj", "{A133A442-BD0A-4ADE-B117-AD7545E4BDD1}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "langs", "langs_vs80.vcproj", "{0F066B23-18DF-4284-8265-F4A5E7E3B966}" - ProjectSection(ProjectDependencies) = postProject - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1} = {A133A442-BD0A-4ADE-B117-AD7545E4BDD1} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "version", "version_vs80.vcproj", "{1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "generate", "generate_vs80.vcproj", "{2F31FD79-D1AC-43C4-89F3-B0D5E4E53E34}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "settings", "settings_vs80.vcproj", "{0817F629-589E-4A3B-B81A-8647BC571E35}" - ProjectSection(ProjectDependencies) = postProject - {E9548DE9-F089-49B7-93A6-30BE2CC311C7} = {E9548DE9-F089-49B7-93A6-30BE2CC311C7} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "settings_gen", "settingsgen_vs80.vcproj", "{E9548DE9-F089-49B7-93A6-30BE2CC311C7}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {668328A0-B40E-4CDB-BD72-D0064424414A}.Debug|Win32.ActiveCfg = Debug|Win32 - {668328A0-B40E-4CDB-BD72-D0064424414A}.Debug|Win32.Build.0 = Debug|Win32 - {668328A0-B40E-4CDB-BD72-D0064424414A}.Debug|x64.ActiveCfg = Debug|x64 - {668328A0-B40E-4CDB-BD72-D0064424414A}.Debug|x64.Build.0 = Debug|x64 - {668328A0-B40E-4CDB-BD72-D0064424414A}.Release|Win32.ActiveCfg = Release|Win32 - {668328A0-B40E-4CDB-BD72-D0064424414A}.Release|Win32.Build.0 = Release|Win32 - {668328A0-B40E-4CDB-BD72-D0064424414A}.Release|x64.ActiveCfg = Release|x64 - {668328A0-B40E-4CDB-BD72-D0064424414A}.Release|x64.Build.0 = Release|x64 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Debug|Win32.ActiveCfg = Debug|Win32 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Debug|Win32.Build.0 = Debug|Win32 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Debug|x64.ActiveCfg = Debug|Win32 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Debug|x64.Build.0 = Debug|Win32 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Release|Win32.ActiveCfg = Debug|Win32 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Release|Win32.Build.0 = Debug|Win32 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Release|x64.ActiveCfg = Debug|Win32 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Release|x64.Build.0 = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Debug|Win32.ActiveCfg = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Debug|Win32.Build.0 = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Debug|x64.ActiveCfg = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Debug|x64.Build.0 = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Release|Win32.ActiveCfg = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Release|Win32.Build.0 = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Release|x64.ActiveCfg = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Release|x64.Build.0 = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Debug|Win32.ActiveCfg = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Debug|Win32.Build.0 = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Debug|x64.ActiveCfg = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Debug|x64.Build.0 = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Release|Win32.ActiveCfg = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Release|Win32.Build.0 = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Release|x64.ActiveCfg = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Release|x64.Build.0 = Debug|Win32 - {2F31FD79-D1AC-43C4-89F3-B0D5E4E53E34}.Debug|Win32.ActiveCfg = Debug|Win32 - {2F31FD79-D1AC-43C4-89F3-B0D5E4E53E34}.Debug|x64.ActiveCfg = Debug|Win32 - {2F31FD79-D1AC-43C4-89F3-B0D5E4E53E34}.Release|Win32.ActiveCfg = Debug|Win32 - {2F31FD79-D1AC-43C4-89F3-B0D5E4E53E34}.Release|x64.ActiveCfg = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Debug|Win32.ActiveCfg = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Debug|Win32.Build.0 = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Debug|x64.ActiveCfg = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Debug|x64.Build.0 = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Release|Win32.ActiveCfg = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Release|Win32.Build.0 = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Release|x64.ActiveCfg = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Release|x64.Build.0 = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Debug|Win32.ActiveCfg = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Debug|Win32.Build.0 = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Debug|x64.ActiveCfg = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Debug|x64.Build.0 = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Release|Win32.ActiveCfg = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Release|Win32.Build.0 = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Release|x64.ActiveCfg = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Release|x64.Build.0 = Debug|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(DPCodeReviewSolutionGUID) = preSolution - DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000} - EndGlobalSection -EndGlobal diff --git a/projects/openttd_vs80.vcproj.in b/projects/openttd_vs80.vcproj.in deleted file mode 100644 index 00c330d22f..0000000000 --- a/projects/openttd_vs80.vcproj.in +++ /dev/null @@ -1,454 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -!!FILES!! - - - - - - - - diff --git a/projects/openttd_vs80.vcproj.user b/projects/openttd_vs80.vcproj.user deleted file mode 100644 index 2d523a7cef..0000000000 --- a/projects/openttd_vs80.vcproj.user +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/projects/openttd_vs90.sln b/projects/openttd_vs90.sln deleted file mode 100644 index a33f315d30..0000000000 --- a/projects/openttd_vs90.sln +++ /dev/null @@ -1,95 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual C++ Express 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openttd", "openttd_vs90.vcproj", "{668328A0-B40E-4CDB-BD72-D0064424414A}" - ProjectSection(ProjectDependencies) = postProject - {0F066B23-18DF-4284-8265-F4A5E7E3B966} = {0F066B23-18DF-4284-8265-F4A5E7E3B966} - {0817F629-589E-4A3B-B81A-8647BC571E35} = {0817F629-589E-4A3B-B81A-8647BC571E35} - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC} = {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "strgen", "strgen_vs90.vcproj", "{A133A442-BD0A-4ADE-B117-AD7545E4BDD1}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "langs", "langs_vs90.vcproj", "{0F066B23-18DF-4284-8265-F4A5E7E3B966}" - ProjectSection(ProjectDependencies) = postProject - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1} = {A133A442-BD0A-4ADE-B117-AD7545E4BDD1} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "version", "version_vs90.vcproj", "{1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "generate", "generate_vs90.vcproj", "{2F31FD79-D1AC-43C4-89F3-B0D5E4E53E34}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "settings", "settings_vs90.vcproj", "{0817F629-589E-4A3B-B81A-8647BC571E35}" - ProjectSection(ProjectDependencies) = postProject - {E9548DE9-F089-49B7-93A6-30BE2CC311C7} = {E9548DE9-F089-49B7-93A6-30BE2CC311C7} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "settingsgen", "settingsgen_vs90.vcproj", "{E9548DE9-F089-49B7-93A6-30BE2CC311C7}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {668328A0-B40E-4CDB-BD72-D0064424414A}.Debug|Win32.ActiveCfg = Debug|Win32 - {668328A0-B40E-4CDB-BD72-D0064424414A}.Debug|Win32.Build.0 = Debug|Win32 - {668328A0-B40E-4CDB-BD72-D0064424414A}.Debug|x64.ActiveCfg = Debug|x64 - {668328A0-B40E-4CDB-BD72-D0064424414A}.Debug|x64.Build.0 = Debug|x64 - {668328A0-B40E-4CDB-BD72-D0064424414A}.Release|Win32.ActiveCfg = Release|Win32 - {668328A0-B40E-4CDB-BD72-D0064424414A}.Release|Win32.Build.0 = Release|Win32 - {668328A0-B40E-4CDB-BD72-D0064424414A}.Release|x64.ActiveCfg = Release|x64 - {668328A0-B40E-4CDB-BD72-D0064424414A}.Release|x64.Build.0 = Release|x64 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Debug|Win32.ActiveCfg = Debug|Win32 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Debug|Win32.Build.0 = Debug|Win32 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Debug|x64.ActiveCfg = Debug|Win32 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Debug|x64.Build.0 = Debug|Win32 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Release|Win32.ActiveCfg = Debug|Win32 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Release|Win32.Build.0 = Debug|Win32 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Release|x64.ActiveCfg = Debug|Win32 - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1}.Release|x64.Build.0 = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Debug|Win32.ActiveCfg = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Debug|Win32.Build.0 = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Debug|x64.ActiveCfg = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Debug|x64.Build.0 = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Release|Win32.ActiveCfg = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Release|Win32.Build.0 = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Release|x64.ActiveCfg = Debug|Win32 - {0F066B23-18DF-4284-8265-F4A5E7E3B966}.Release|x64.Build.0 = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Debug|Win32.ActiveCfg = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Debug|Win32.Build.0 = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Debug|x64.ActiveCfg = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Debug|x64.Build.0 = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Release|Win32.ActiveCfg = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Release|Win32.Build.0 = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Release|x64.ActiveCfg = Debug|Win32 - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC}.Release|x64.Build.0 = Debug|Win32 - {2F31FD79-D1AC-43C4-89F3-B0D5E4E53E34}.Debug|Win32.ActiveCfg = Debug|Win32 - {2F31FD79-D1AC-43C4-89F3-B0D5E4E53E34}.Debug|x64.ActiveCfg = Debug|Win32 - {2F31FD79-D1AC-43C4-89F3-B0D5E4E53E34}.Release|Win32.ActiveCfg = Debug|Win32 - {2F31FD79-D1AC-43C4-89F3-B0D5E4E53E34}.Release|x64.ActiveCfg = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Debug|Win32.ActiveCfg = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Debug|Win32.Build.0 = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Debug|x64.ActiveCfg = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Debug|x64.Build.0 = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Release|Win32.ActiveCfg = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Release|Win32.Build.0 = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Release|x64.ActiveCfg = Debug|Win32 - {0817F629-589E-4A3B-B81A-8647BC571E35}.Release|x64.Build.0 = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Debug|Win32.ActiveCfg = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Debug|Win32.Build.0 = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Debug|x64.ActiveCfg = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Debug|x64.Build.0 = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Release|Win32.ActiveCfg = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Release|Win32.Build.0 = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Release|x64.ActiveCfg = Debug|Win32 - {E9548DE9-F089-49B7-93A6-30BE2CC311C7}.Release|x64.Build.0 = Debug|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(DPCodeReviewSolutionGUID) = preSolution - DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000} - EndGlobalSection -EndGlobal diff --git a/projects/openttd_vs90.vcproj.in b/projects/openttd_vs90.vcproj.in deleted file mode 100644 index 0ebf4fcbed..0000000000 --- a/projects/openttd_vs90.vcproj.in +++ /dev/null @@ -1,451 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -!!FILES!! - - - - - - - - diff --git a/projects/openttd_vs90.vcproj.user b/projects/openttd_vs90.vcproj.user deleted file mode 100644 index b49492a503..0000000000 --- a/projects/openttd_vs90.vcproj.user +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/projects/regression.bat b/projects/regression.bat new file mode 100644 index 0000000000..db373c371b --- /dev/null +++ b/projects/regression.bat @@ -0,0 +1,6 @@ +cd ..\bin +editbin /nologo /subsystem:console openttd.exe +cscript /nologo ai\regression\run.vbs +set RESULT=%ERRORLEVEL% +editbin /nologo /subsystem:windows openttd.exe +exit %RESULT% diff --git a/projects/regression_vs140.vcxproj b/projects/regression_vs140.vcxproj new file mode 100644 index 0000000000..b1c9f4930a --- /dev/null +++ b/projects/regression_vs140.vcxproj @@ -0,0 +1,41 @@ + + + + + Debug + Win32 + + + + {4712B013-437D-42CE-947F-DEBABA15261F} + regression + regression + + + + Makefile + v140 + + + + + + + + + + + + call regression.bat + call regression.bat + del ..\bin\tmp.regression + + + + {668328a0-b40e-4cdb-bd72-d0064424414a} + + + + + + diff --git a/projects/regression_vs141.vcxproj b/projects/regression_vs141.vcxproj new file mode 100644 index 0000000000..fda3f3312d --- /dev/null +++ b/projects/regression_vs141.vcxproj @@ -0,0 +1,41 @@ + + + + + Debug + Win32 + + + + {4712B013-437D-42CE-947F-DEBABA15261F} + regression + regression + + + + Makefile + v141 + + + + + + + + + + + + call regression.bat + call regression.bat + del ..\bin\tmp.regression + + + + {668328a0-b40e-4cdb-bd72-d0064424414a} + + + + + + diff --git a/projects/settings_vs100.vcxproj b/projects/settings_vs100.vcxproj deleted file mode 100644 index 61b289757a..0000000000 --- a/projects/settings_vs100.vcxproj +++ /dev/null @@ -1,54 +0,0 @@ - - - - - Debug - Win32 - - - - settings - {0817F629-589E-4A3B-B81A-8647BC571E35} - settings - - - - Makefile - - - - - - - - - -..\objs\settings\settings_gen.exe -o ..\objs\settings\table\settings.h -b ..\src\table\settings.h.preamble -a ..\src\table\settings.h.postamble ..\src\table\company_settings.ini ..\src\table\currency_settings.ini ..\src\table\gameopt_settings.ini ..\src\table\misc_settings.ini ..\src\table\settings.ini ..\src\table\win32_settings.ini ..\src\table\window_settings.ini - - - - <_ProjectFileVersion>10.0.30319.1 - ..\objs\settings\table\ - ..\objs\settings\table\ - $(SettingsCommandLine) - $(SettingsCommandLine) - del ..\objs\settings\table\settings.h - ..\objs\settings\table\settings.h - - - - - - - - - - - - - - - - - - diff --git a/projects/settings_vs100.vcxproj.filters b/projects/settings_vs100.vcxproj.filters deleted file mode 100644 index 8caf9fa0a6..0000000000 --- a/projects/settings_vs100.vcxproj.filters +++ /dev/null @@ -1,35 +0,0 @@ - - - - - {21deca6c-8df4-4f34-9dad-17d7781cd5a0} - - - - - INI - - - INI - - - INI - - - INI - - - INI - - - INI - - - INI - - - - - - - diff --git a/projects/settings_vs100.vcxproj.filters.in b/projects/settings_vs100.vcxproj.filters.in deleted file mode 100644 index 08f90670d2..0000000000 --- a/projects/settings_vs100.vcxproj.filters.in +++ /dev/null @@ -1,15 +0,0 @@ - - - - - {21deca6c-8df4-4f34-9dad-17d7781cd5a0} - - - -!!FILES!! - - - - - - diff --git a/projects/settings_vs100.vcxproj.in b/projects/settings_vs100.vcxproj.in deleted file mode 100644 index 46064b53cf..0000000000 --- a/projects/settings_vs100.vcxproj.in +++ /dev/null @@ -1,48 +0,0 @@ - - - - - Debug - Win32 - - - - settings - {0817F629-589E-4A3B-B81A-8647BC571E35} - settings - - - - Makefile - - - - - - - - - -!!FILTERS!! - - - - <_ProjectFileVersion>10.0.30319.1 - ..\objs\settings\table\ - ..\objs\settings\table\ - $(SettingsCommandLine) - $(SettingsCommandLine) - del ..\objs\settings\table\settings.h - ..\objs\settings\table\settings.h - - -!!FILES!! - - - - - - - - - diff --git a/projects/settings_vs80.vcproj b/projects/settings_vs80.vcproj deleted file mode 100644 index 0084dcbc57..0000000000 --- a/projects/settings_vs80.vcproj +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/projects/settings_vs80.vcproj.in b/projects/settings_vs80.vcproj.in deleted file mode 100644 index a0f10fb096..0000000000 --- a/projects/settings_vs80.vcproj.in +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - -!!FILES!! - - - - - - - - - diff --git a/projects/settings_vs90.vcproj b/projects/settings_vs90.vcproj deleted file mode 100644 index 4361e8df54..0000000000 --- a/projects/settings_vs90.vcproj +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/projects/settings_vs90.vcproj.in b/projects/settings_vs90.vcproj.in deleted file mode 100644 index a342e2b327..0000000000 --- a/projects/settings_vs90.vcproj.in +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - - - - - - - -!!FILES!! - - - - - - - - - diff --git a/projects/settingsgen_vs100.vcxproj b/projects/settingsgen_vs100.vcxproj deleted file mode 100644 index 30454d81f8..0000000000 --- a/projects/settingsgen_vs100.vcxproj +++ /dev/null @@ -1,81 +0,0 @@ - - - - - Debug - Win32 - - - - settingsgen - {E9548DE9-F089-49B7-93A6-30BE2CC311C7} - settings - - - - Application - MultiByte - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - ..\objs\settings\ - ..\objs\settings\ - settings_gen - - - - - - - - %(Inputs) - - - MinSpace - Size - SETTINGSGEN;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - All - $(IntDir)$(TargetName).pdb - Level3 - true - ProgramDatabase - MultiThreadedDebug - - - $(OutDir)settings_gen.exe - true - false - - - Console - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/projects/settingsgen_vs100.vcxproj.filters b/projects/settingsgen_vs100.vcxproj.filters deleted file mode 100644 index c8afe0c8ed..0000000000 --- a/projects/settingsgen_vs100.vcxproj.filters +++ /dev/null @@ -1,32 +0,0 @@ - - - - - {a4678737-b3b3-4be5-9db1-fa6ccd164c59} - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - - - - - - diff --git a/projects/settingsgen_vs140.vcxproj b/projects/settingsgen_vs140.vcxproj index fc6d079e8e..12ce280f3a 100644 --- a/projects/settingsgen_vs140.vcxproj +++ b/projects/settingsgen_vs140.vcxproj @@ -80,4 +80,4 @@ - \ No newline at end of file + diff --git a/projects/settingsgen_vs80.vcproj b/projects/settingsgen_vs80.vcproj deleted file mode 100644 index 7568ce9748..0000000000 --- a/projects/settingsgen_vs80.vcproj +++ /dev/null @@ -1,143 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/projects/settingsgen_vs90.vcproj b/projects/settingsgen_vs90.vcproj deleted file mode 100644 index 015ddd2af5..0000000000 --- a/projects/settingsgen_vs90.vcproj +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/projects/strgen_vs100.vcxproj b/projects/strgen_vs100.vcxproj deleted file mode 100644 index 7a43b4debb..0000000000 --- a/projects/strgen_vs100.vcxproj +++ /dev/null @@ -1,94 +0,0 @@ - - - - - Debug - Win32 - - - - strgen - {A133A442-BD0A-4ADE-B117-AD7545E4BDD1} - strgen - - - - Application - false - MultiByte - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(SolutionDir)..\objs\strgen\ - $(SolutionDir)..\objs\strgen\ - false - AllRules.ruleset - - - - - - .\Debug/strgen.tlb - - - - - /MP %(AdditionalOptions) - MinSpace - Size - STRGEN;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - Default - MultiThreadedDebug - - - All - $(IntDir) - $(IntDir) - $(IntDir)$(TargetName).pdb - Level3 - true - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x041d - - - true - true - $(IntDir)strgen.pdb - Console - false - - - MachineX86 - - - - - - - - - - - - - - - - - - - - - - diff --git a/projects/strgen_vs100.vcxproj.filters b/projects/strgen_vs100.vcxproj.filters deleted file mode 100644 index 58864ee691..0000000000 --- a/projects/strgen_vs100.vcxproj.filters +++ /dev/null @@ -1,35 +0,0 @@ - - - - - {5894294c-d4dc-41f0-be31-e56cff4e0405} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - - - - - - - - diff --git a/projects/strgen_vs140.vcxproj b/projects/strgen_vs140.vcxproj index ebf56a4daf..b972d873eb 100644 --- a/projects/strgen_vs140.vcxproj +++ b/projects/strgen_vs140.vcxproj @@ -92,4 +92,4 @@ - \ No newline at end of file + diff --git a/projects/strgen_vs80.vcproj b/projects/strgen_vs80.vcproj deleted file mode 100644 index 4450279303..0000000000 --- a/projects/strgen_vs80.vcproj +++ /dev/null @@ -1,168 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/projects/strgen_vs90.vcproj b/projects/strgen_vs90.vcproj deleted file mode 100644 index ca194e078f..0000000000 --- a/projects/strgen_vs90.vcproj +++ /dev/null @@ -1,168 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/projects/version_vs100.vcxproj b/projects/version_vs100.vcxproj deleted file mode 100644 index 008e6dd665..0000000000 --- a/projects/version_vs100.vcxproj +++ /dev/null @@ -1,42 +0,0 @@ - - - - - Debug - Win32 - - - - version - {1A2B3C5E-1C23-41A5-9C9B-ACBA2AA75FEC} - version - - - - Makefile - MultiByte - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(SolutionDir)..\objs\version\ - $(SolutionDir)..\objs\version\ - cscript "$(ProjectDir)/determineversion.vbs" - cscript "$(ProjectDir)/determineversion.vbs" - ..\src\rev.cpp - del ..\src\rev.cpp - - - - - - - - - \ No newline at end of file diff --git a/projects/version_vs140.vcxproj b/projects/version_vs140.vcxproj index baf374bca0..6e71a88201 100644 --- a/projects/version_vs140.vcxproj +++ b/projects/version_vs140.vcxproj @@ -39,4 +39,4 @@ - \ No newline at end of file + diff --git a/projects/version_vs80.vcproj b/projects/version_vs80.vcproj deleted file mode 100644 index 4b1660b69d..0000000000 --- a/projects/version_vs80.vcproj +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/projects/version_vs90.vcproj b/projects/version_vs90.vcproj deleted file mode 100644 index 3c3d58a692..0000000000 --- a/projects/version_vs90.vcproj +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/source.list b/source.list index 7ed1eb63b2..2e424764d7 100644 --- a/source.list +++ b/source.list @@ -95,22 +95,19 @@ tilearea.cpp townname.cpp #if WIN32 #else - #if WINCE + #if OS2 + os/os2/os2.cpp + 3rdparty/os2/getaddrinfo.c + 3rdparty/os2/getaddrinfo.h + 3rdparty/os2/getnameinfo.c + 3rdparty/os2/getnameinfo.h #else - #if OS2 - os/os2/os2.cpp - 3rdparty/os2/getaddrinfo.c - 3rdparty/os2/getaddrinfo.h - 3rdparty/os2/getnameinfo.c - 3rdparty/os2/getnameinfo.h + #if OSX + os/macosx/crashlog_osx.cpp #else - #if OSX - os/macosx/crashlog_osx.cpp - #else - os/unix/crashlog_unix.cpp - #end - os/unix/unix.cpp + os/unix/crashlog_unix.cpp #end + os/unix/unix.cpp #end #end vehicle.cpp @@ -196,6 +193,7 @@ fileio_type.h fios.h fontcache.h fontdetection.h +framerate_type.h base_consist.h gamelog.h gamelog_internal.h @@ -284,6 +282,8 @@ newgrf_townname.h news_func.h news_gui.h news_type.h +music/midi.h +music/midifile.hpp music/null_m.h sound/null_s.h video/null_v.h @@ -345,6 +345,7 @@ strgen/strgen.h string_base.h string_func.h string_type.h +os/windows/string_uniscribe.h stringfilter_type.h strings_func.h strings_type.h @@ -398,6 +399,7 @@ video/win32_v.h window_func.h window_gui.h window_type.h +sound/xaudio2_s.h zoom_func.h zoom_type.h #if WIN32 @@ -406,11 +408,13 @@ music/bemidi.h music/cocoa_m.h music/extmidi.h music/libtimidity.h +music/fluidsynth.h music/os2_m.h music/qtmidi.h os/macosx/macos.h os/macosx/osx_stdafx.h os/macosx/splash.h +os/macosx/string_osx.h sound/cocoa_s.h video/cocoa/cocoa_keys.h video/cocoa/cocoa_v.h @@ -464,6 +468,7 @@ dock_gui.cpp engine_gui.cpp error_gui.cpp fios_gui.cpp +framerate_gui.cpp genworld_gui.cpp goal_gui.cpp graph_gui.cpp @@ -527,6 +532,7 @@ widgets/dropdown_widget.h widgets/engine_widget.h widgets/error_widget.h widgets/fios_widget.h +widgets/framerate_widget.h widgets/genworld_widget.h widgets/goal_widget.h widgets/graph_widget.h @@ -916,6 +922,8 @@ script/api/script_window.cpp blitter/32bpp_anim.cpp blitter/32bpp_anim.hpp #if SSE +blitter/32bpp_anim_sse2.cpp +blitter/32bpp_anim_sse2.hpp blitter/32bpp_anim_sse4.cpp blitter/32bpp_anim_sse4.hpp #end @@ -1091,9 +1099,6 @@ video/null_v.cpp #if WIN32 video/win32_v.cpp #end -#if WINCE - video/win32_v.cpp -#end #end # Music @@ -1107,22 +1112,17 @@ video/null_v.cpp #end #end music/null_m.cpp +music/midifile.cpp #if DEDICATED #else #if WIN32 music/win32_m.cpp #else - #if WINCE + #if DOS #else - #if PSP + #if MORPHOS #else - #if DOS - #else - #if MORPHOS - #else - music/extmidi.cpp - #end - #end + music/extmidi.cpp #end #end #end @@ -1132,6 +1132,9 @@ music/null_m.cpp #if LIBTIMIDITY music/libtimidity.cpp #end +#if FLUIDSYNTH + music/fluidsynth.cpp +#end #end # Sound @@ -1146,6 +1149,7 @@ sound/null_s.cpp #end #if WIN32 sound/win32_s.cpp + sound/xaudio2_s.cpp #end #end @@ -1167,6 +1171,7 @@ sound/null_s.cpp music/cocoa_m.cpp sound/cocoa_s.cpp os/macosx/splash.cpp + os/macosx/string_osx.cpp #end #end @@ -1174,10 +1179,7 @@ sound/null_s.cpp #if WIN32 os/windows/crashlog_win.cpp os/windows/ottdres.rc - os/windows/win32.cpp -#end -#if WINCE - os/windows/ottdres.rc + os/windows/string_uniscribe.cpp os/windows/win32.cpp #end diff --git a/src/3rdparty/squirrel/squirrel/sqdebug.cpp b/src/3rdparty/squirrel/squirrel/sqdebug.cpp index b163fae52e..2f24e83b66 100644 --- a/src/3rdparty/squirrel/squirrel/sqdebug.cpp +++ b/src/3rdparty/squirrel/squirrel/sqdebug.cpp @@ -115,7 +115,7 @@ void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger ty SQInteger found = 0; for(SQInteger i=0; i<16; i++) { - SQInteger mask = 0x00000001 << i; + SQInteger mask = 0x00000001LL << i; if(typemask & (mask)) { if(found>0) StringCat(exptypes,SQString::Create(_ss(this), "|", -1), exptypes); found ++; diff --git a/src/3rdparty/squirrel/squirrel/squtils.h b/src/3rdparty/squirrel/squirrel/squtils.h index 28c6cbec2b..b1138dcb1a 100644 --- a/src/3rdparty/squirrel/squirrel/squtils.h +++ b/src/3rdparty/squirrel/squirrel/squtils.h @@ -90,7 +90,7 @@ public: { _vals[idx].~T(); if(idx < (_size - 1)) { - memmove(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - (size_t)idx - 1)); + memmove(static_cast(&_vals[idx]), &_vals[idx+1], sizeof(T) * (_size - (size_t)idx - 1)); } _size--; } diff --git a/src/3rdparty/squirrel/squirrel/sqvm.cpp b/src/3rdparty/squirrel/squirrel/sqvm.cpp index c66c4aca59..03ffea2303 100644 --- a/src/3rdparty/squirrel/squirrel/sqvm.cpp +++ b/src/3rdparty/squirrel/squirrel/sqvm.cpp @@ -378,8 +378,7 @@ bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger args,SQIntege } if (!tailcall) { - CallInfo lc; - memset(&lc, 0, sizeof(lc)); + CallInfo lc = {}; lc._generator = NULL; lc._etraps = 0; lc._prevstkbase = (SQInt32) ( stackbase - _stackbase ); @@ -1159,8 +1158,7 @@ bool SQVM::CallNative(SQNativeClosure *nclosure,SQInteger nargs,SQInteger stackb SQInteger oldtop = _top; SQInteger oldstackbase = _stackbase; _top = stackbase + nargs; - CallInfo lci; - memset(&lci, 0, sizeof(lci)); + CallInfo lci = {}; lci._closure = nclosure; lci._generator = NULL; lci._etraps = 0; diff --git a/src/ai/ai_info.cpp b/src/ai/ai_info.cpp index 9c27006c47..43a4345460 100644 --- a/src/ai/ai_info.cpp +++ b/src/ai/ai_info.cpp @@ -32,9 +32,9 @@ static bool CheckAPIVersion(const char *api_version) strcmp(api_version, "1.8") == 0 || strcmp(api_version, "1.9") == 0; } -#if defined(WIN32) +#if defined(_WIN32) #undef GetClassName -#endif /* WIN32 */ +#endif /* _WIN32 */ template <> const char *GetClassName() { return "AIInfo"; } /* static */ void AIInfo::RegisterAPI(Squirrel *engine) diff --git a/src/aircraft.h b/src/aircraft.h index f0ca1c4abb..f4fce09be1 100644 --- a/src/aircraft.h +++ b/src/aircraft.h @@ -45,6 +45,8 @@ enum AirVehicleFlags { * landscape at a fixed altitude. This only has effect when there are more than 15 height levels. */ VAF_IN_MAX_HEIGHT_CORRECTION = 1, ///< The vehicle is currently lowering its altitude because it hit the upper bound. VAF_IN_MIN_HEIGHT_CORRECTION = 2, ///< The vehicle is currently raising its altitude because it hit the lower bound. + + VAF_HELI_DIRECT_DESCENT = 3, ///< The helicopter is descending directly at its destination (helipad or in front of hangar) }; static const int ROTOR_Z_OFFSET = 5; ///< Z Offset between helicopter- and rotorsprite. @@ -90,7 +92,7 @@ struct Aircraft FINAL : public SpecializedVehicle { virtual ~Aircraft() { this->PreDestructor(); } void MarkDirty(); - void UpdateDeltaXY(Direction direction); + void UpdateDeltaXY(); ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_AIRCRAFT_INC : EXPENSES_AIRCRAFT_RUN; } bool IsPrimaryVehicle() const { return this->IsNormalAircraft(); } void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const; @@ -137,7 +139,7 @@ struct Aircraft FINAL : public SpecializedVehicle { }; /** - * Macro for iterating over all aircrafts. + * Macro for iterating over all aircraft. */ #define FOR_ALL_AIRCRAFT(var) FOR_ALL_VEHICLES_OF_TYPE(Aircraft, var) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index c9cddbf97d..b495a1dff5 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -37,12 +37,13 @@ #include "core/backup_type.hpp" #include "zoom_func.h" #include "disaster_vehicle.h" +#include "framerate_type.h" #include "table/strings.h" #include "safeguards.h" -void Aircraft::UpdateDeltaXY(Direction direction) +void Aircraft::UpdateDeltaXY() { this->x_offs = -1; this->y_offs = -1; @@ -247,7 +248,7 @@ void GetAircraftSpriteSize(EngineID engine, uint &width, uint &height, int &xoff * @param flags type of operation. * @param e the engine to build. * @param data unused. - * @param ret[out] the vehicle that has been built. + * @param[out] ret the vehicle that has been built. * @return the cost of this operation or an error. */ CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **ret) @@ -303,10 +304,10 @@ CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, const Engine * u->engine_type = e->index; v->subtype = (avi->subtype & AIR_CTOL ? AIR_AIRCRAFT : AIR_HELICOPTER); - v->UpdateDeltaXY(INVALID_DIR); + v->UpdateDeltaXY(); u->subtype = AIR_SHADOW; - u->UpdateDeltaXY(INVALID_DIR); + u->UpdateDeltaXY(); v->reliability = e->reliability; v->reliability_spd_dec = e->reliability_spd_dec; @@ -363,7 +364,7 @@ CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, const Engine * w->random_bits = VehicleRandomBits(); /* Use rotor's air.state to store the rotor animation frame */ w->state = HRS_ROTOR_STOPPED; - w->UpdateDeltaXY(INVALID_DIR); + w->UpdateDeltaXY(); u->SetNext(w); w->UpdatePosition(); @@ -634,6 +635,12 @@ static int UpdateAircraftSpeed(Aircraft *v, uint speed_limit = SPEED_LIMIT_NONE, * and take-off speeds being too low. */ speed_limit *= _settings_game.vehicle.plane_speed; + /* adjust speed for broken vehicles */ + if (v->vehstatus & VS_AIRCRAFT_BROKEN) { + if (SPEED_LIMIT_BROKEN < speed_limit) hard_limit = false; + speed_limit = min(speed_limit, SPEED_LIMIT_BROKEN); + } + if (v->vcache.cached_max_speed < speed_limit) { if (v->cur_speed < speed_limit) hard_limit = false; speed_limit = v->vcache.cached_max_speed; @@ -653,9 +660,6 @@ static int UpdateAircraftSpeed(Aircraft *v, uint speed_limit = SPEED_LIMIT_NONE, spd = min(v->cur_speed + (spd >> 8) + (v->subspeed < t), speed_limit); - /* adjust speed for broken vehicles */ - if (v->vehstatus & VS_AIRCRAFT_BROKEN) spd = min(spd, SPEED_LIMIT_BROKEN); - /* updates statusbar only if speed have changed to save CPU time */ if (spd != v->cur_speed) { v->cur_speed = spd; @@ -693,9 +697,9 @@ int GetTileHeightBelowAircraft(const Vehicle *v) * When the maximum is reached the vehicle should consider descending. * When the minimum is reached the vehicle should consider ascending. * - * @param v The vehicle to get the flight levels for. - * @param [out] min_level The minimum bounds for flight level. - * @param [out] max_level The maximum bounds for flight level. + * @param v The vehicle to get the flight levels for. + * @param[out] min_level The minimum bounds for flight level. + * @param[out] max_level The maximum bounds for flight level. */ void GetAircraftFlightLevelBounds(const Vehicle *v, int *min_level, int *max_level) { @@ -727,7 +731,7 @@ void GetAircraftFlightLevelBounds(const Vehicle *v, int *min_level, int *max_lev /** * Gets the maximum 'flight level' for the holding pattern of the aircraft, - * in pixels 'z_pos' 0, depending on terrain below.. + * in pixels 'z_pos' 0, depending on terrain below. * * @param v The aircraft that may or may not need to decrease its altitude. * @return Maximal aircraft holding altitude, while in normal flight, in pixels. @@ -749,7 +753,7 @@ int GetAircraftFlightLevel(T *v, bool takeoff) GetAircraftFlightLevelBounds(v, &aircraft_min_altitude, &aircraft_max_altitude); int aircraft_middle_altitude = (aircraft_min_altitude + aircraft_max_altitude) / 2; - /* If those assumptions would be violated, aircrafts would behave fairly strange. */ + /* If those assumptions would be violated, aircraft would behave fairly strange. */ assert(aircraft_min_altitude < aircraft_middle_altitude); assert(aircraft_middle_altitude < aircraft_max_altitude); @@ -914,6 +918,8 @@ static bool AircraftController(Aircraft *v) /* Helicopter landing. */ if (amd.flag & AMED_HELI_LOWER) { + SetBit(v->flags, VAF_HELI_DIRECT_DESCENT); + if (st == NULL) { /* FIXME - AircraftController -> if station no longer exists, do not land * helicopter will circle until sign disappears, then go to next order @@ -934,7 +940,10 @@ static bool AircraftController(Aircraft *v) Vehicle *u = v->Next()->Next(); /* Increase speed of rotors. When speed is 80, we've landed. */ - if (u->cur_speed >= 80) return true; + if (u->cur_speed >= 80) { + ClrBit(v->flags, VAF_HELI_DIRECT_DESCENT); + return true; + } u->cur_speed += 4; } else { count = UpdateAircraftSpeed(v); @@ -1361,7 +1370,7 @@ static void AircraftEntersTerminal(Aircraft *v) */ static void AircraftLandAirplane(Aircraft *v) { - v->UpdateDeltaXY(INVALID_DIR); + v->UpdateDeltaXY(); if (!PlayVehicleSound(v, VSE_TOUCHDOWN)) { SndPlayVehicleFx(SND_17_SKID_PLANE, v); @@ -1553,7 +1562,7 @@ static void AircraftEventHandler_TakeOff(Aircraft *v, const AirportFTAClass *apc static void AircraftEventHandler_StartTakeOff(Aircraft *v, const AirportFTAClass *apc) { v->state = ENDTAKEOFF; - v->UpdateDeltaXY(INVALID_DIR); + v->UpdateDeltaXY(); } static void AircraftEventHandler_EndTakeOff(Aircraft *v, const AirportFTAClass *apc) @@ -1566,7 +1575,7 @@ static void AircraftEventHandler_EndTakeOff(Aircraft *v, const AirportFTAClass * static void AircraftEventHandler_HeliTakeOff(Aircraft *v, const AirportFTAClass *apc) { v->state = FLYING; - v->UpdateDeltaXY(INVALID_DIR); + v->UpdateDeltaXY(); /* get the next position to go to, differs per airport */ AircraftNextAirportPos_and_Order(v); @@ -1599,6 +1608,7 @@ static void AircraftEventHandler_Flying(Aircraft *v, const AirportFTAClass *apc) uint16 tsubspeed = v->subspeed; if (!AirportHasBlock(v, current, apc)) { v->state = landingtype; // LANDING / HELILANDING + if (v->state == HELILANDING) SetBit(v->flags, VAF_HELI_DIRECT_DESCENT); /* it's a bit dirty, but I need to set position to next position, otherwise * if there are multiple runways, plane won't know which one it took (because * they all have heading LANDING). And also occupy that block! */ @@ -1632,7 +1642,7 @@ static void AircraftEventHandler_Landing(Aircraft *v, const AirportFTAClass *apc static void AircraftEventHandler_HeliLanding(Aircraft *v, const AirportFTAClass *apc) { v->state = HELIENDLANDING; - v->UpdateDeltaXY(INVALID_DIR); + v->UpdateDeltaXY(); } static void AircraftEventHandler_EndLanding(Aircraft *v, const AirportFTAClass *apc) @@ -1888,7 +1898,7 @@ static bool FreeTerminal(Aircraft *v, byte i, byte last_terminal) /** * Get the number of terminals at the airport. - * @param afc Airport description. + * @param apc Airport description. * @return Number of terminals. */ static uint GetNumTerminals(const AirportFTAClass *apc) @@ -2038,6 +2048,8 @@ bool Aircraft::Tick() { if (!this->IsNormalAircraft()) return true; + PerformanceAccumulator framerate(PFE_GL_AIRCRAFT); + this->tick_counter++; if (!(this->vehstatus & VS_STOPPED)) this->running_ticks++; diff --git a/src/animated_tile.cpp b/src/animated_tile.cpp index 796c5f5e09..2a4cd89583 100644 --- a/src/animated_tile.cpp +++ b/src/animated_tile.cpp @@ -14,6 +14,7 @@ #include "core/smallvec_type.hpp" #include "tile_cmd.h" #include "viewport_func.h" +#include "framerate_type.h" #include "safeguards.h" @@ -50,6 +51,8 @@ void AddAnimatedTile(TileIndex tile) */ void AnimateAnimatedTiles() { + PerformanceAccumulator framerate(PFE_GL_LANDSCAPE); + const TileIndex *ti = _animated_tiles.Begin(); while (ti < _animated_tiles.End()) { const TileIndex curr = *ti; diff --git a/src/articulated_vehicles.cpp b/src/articulated_vehicles.cpp index 04c9f95a97..44ad587895 100644 --- a/src/articulated_vehicles.cpp +++ b/src/articulated_vehicles.cpp @@ -119,12 +119,12 @@ static inline uint16 GetVehicleDefaultCapacity(EngineID engine, CargoID *cargo_t * @param include_initial_cargo_type if true the default cargo type of the vehicle is included; if false only the refit_mask * @return bit set of CargoIDs */ -static inline uint32 GetAvailableVehicleCargoTypes(EngineID engine, bool include_initial_cargo_type) +static inline CargoTypes GetAvailableVehicleCargoTypes(EngineID engine, bool include_initial_cargo_type) { const Engine *e = Engine::Get(engine); if (!e->CanCarryCargo()) return 0; - uint32 cargoes = e->info.refit_mask; + CargoTypes cargoes = e->info.refit_mask; if (include_initial_cargo_type) { SetBit(cargoes, e->GetDefaultCargoType()); @@ -169,7 +169,7 @@ CargoArray GetCapacityOfArticulatedParts(EngineID engine) * @param[out] cargoes Total amount of units that can be transported, summed by cargo. * @param[out] refits Whether a (possibly partial) refit for each cargo is possible. */ -void GetArticulatedVehicleCargoesAndRefits(EngineID engine, CargoArray *cargoes, uint32 *refits) +void GetArticulatedVehicleCargoesAndRefits(EngineID engine, CargoArray *cargoes, CargoTypes *refits) { cargoes->Clear(); *refits = 0; @@ -228,12 +228,12 @@ bool IsArticulatedVehicleRefittable(EngineID engine) * @param union_mask returns bit mask of CargoIDs which are a refit option for at least one articulated part * @param intersection_mask returns bit mask of CargoIDs which are a refit option for every articulated part (with default capacity > 0) */ -void GetArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type, uint32 *union_mask, uint32 *intersection_mask) +void GetArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type, CargoTypes *union_mask, CargoTypes *intersection_mask) { const Engine *e = Engine::Get(engine); - uint32 veh_cargoes = GetAvailableVehicleCargoTypes(engine, include_initial_cargo_type); + CargoTypes veh_cargoes = GetAvailableVehicleCargoTypes(engine, include_initial_cargo_type); *union_mask = veh_cargoes; - *intersection_mask = (veh_cargoes != 0) ? veh_cargoes : UINT32_MAX; + *intersection_mask = (veh_cargoes != 0) ? veh_cargoes : ALL_CARGOTYPES; if (!e->IsGroundVehicle()) return; if (!HasBit(e->info.callback_mask, CBM_VEHICLE_ARTIC_ENGINE)) return; @@ -254,9 +254,9 @@ void GetArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type, * @param include_initial_cargo_type if true the default cargo type of the vehicle is included; if false only the refit_mask * @return bit mask of CargoIDs which are a refit option for at least one articulated part */ -uint32 GetUnionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type) +CargoTypes GetUnionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type) { - uint32 union_mask, intersection_mask; + CargoTypes union_mask, intersection_mask; GetArticulatedRefitMasks(engine, include_initial_cargo_type, &union_mask, &intersection_mask); return union_mask; } @@ -267,9 +267,9 @@ uint32 GetUnionOfArticulatedRefitMasks(EngineID engine, bool include_initial_car * @param include_initial_cargo_type if true the default cargo type of the vehicle is included; if false only the refit_mask * @return bit mask of CargoIDs which are a refit option for every articulated part (with default capacity > 0) */ -uint32 GetIntersectionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type) +CargoTypes GetIntersectionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type) { - uint32 union_mask, intersection_mask; + CargoTypes union_mask, intersection_mask; GetArticulatedRefitMasks(engine, include_initial_cargo_type, &union_mask, &intersection_mask); return intersection_mask; } @@ -314,16 +314,16 @@ void CheckConsistencyOfArticulatedVehicle(const Vehicle *v) { const Engine *engine = v->GetEngine(); - uint32 purchase_refit_union, purchase_refit_intersection; + CargoTypes purchase_refit_union, purchase_refit_intersection; GetArticulatedRefitMasks(v->engine_type, true, &purchase_refit_union, &purchase_refit_intersection); CargoArray purchase_default_capacity = GetCapacityOfArticulatedParts(v->engine_type); - uint32 real_refit_union = 0; - uint32 real_refit_intersection = UINT_MAX; + CargoTypes real_refit_union = 0; + CargoTypes real_refit_intersection = ALL_CARGOTYPES; CargoArray real_default_capacity; do { - uint32 refit_mask = GetAvailableVehicleCargoTypes(v->engine_type, true); + CargoTypes refit_mask = GetAvailableVehicleCargoTypes(v->engine_type, true); real_refit_union |= refit_mask; if (refit_mask != 0) real_refit_intersection &= refit_mask; diff --git a/src/articulated_vehicles.h b/src/articulated_vehicles.h index 46b4da3744..77322fb4c7 100644 --- a/src/articulated_vehicles.h +++ b/src/articulated_vehicles.h @@ -18,9 +18,9 @@ uint CountArticulatedParts(EngineID engine_type, bool purchase_window); CargoArray GetCapacityOfArticulatedParts(EngineID engine); void AddArticulatedParts(Vehicle *first); -void GetArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type, uint32 *union_mask, uint32 *intersection_mask); -uint32 GetUnionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type); -uint32 GetIntersectionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type); +void GetArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type, CargoTypes *union_mask, CargoTypes *intersection_mask); +CargoTypes GetUnionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type); +CargoTypes GetIntersectionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type); bool IsArticulatedVehicleCarryingDifferentCargoes(const Vehicle *v, CargoID *cargo_type); bool IsArticulatedVehicleRefittable(EngineID engine); bool IsArticulatedEngine(EngineID engine_type); diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index e69ac66eb2..48f818c947 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -32,13 +32,12 @@ extern void ChangeVehicleViewWindow(VehicleID from_index, VehicleID to_index); * Figure out if two engines got at least one type of cargo in common (refitting if needed) * @param engine_a one of the EngineIDs * @param engine_b the other EngineID - * @param type the type of the engines * @return true if they can both carry the same type of cargo (or at least one of them got no capacity at all) */ static bool EnginesHaveCargoInCommon(EngineID engine_a, EngineID engine_b) { - uint32 available_cargoes_a = GetUnionOfArticulatedRefitMasks(engine_a, true); - uint32 available_cargoes_b = GetUnionOfArticulatedRefitMasks(engine_b, true); + CargoTypes available_cargoes_a = GetUnionOfArticulatedRefitMasks(engine_a, true); + CargoTypes available_cargoes_b = GetUnionOfArticulatedRefitMasks(engine_b, true); return (available_cargoes_a == 0 || available_cargoes_b == 0 || (available_cargoes_a & available_cargoes_b) != 0); } @@ -173,9 +172,8 @@ static void TransferCargo(Vehicle *old_veh, Vehicle *new_head, bool part_of_chai */ static bool VerifyAutoreplaceRefitForOrders(const Vehicle *v, EngineID engine_type) { - - uint32 union_refit_mask_a = GetUnionOfArticulatedRefitMasks(v->engine_type, false); - uint32 union_refit_mask_b = GetUnionOfArticulatedRefitMasks(engine_type, false); + CargoTypes union_refit_mask_a = GetUnionOfArticulatedRefitMasks(v->engine_type, false); + CargoTypes union_refit_mask_b = GetUnionOfArticulatedRefitMasks(engine_type, false); const Order *o; const Vehicle *u = (v->type == VEH_TRAIN) ? v->First() : v; @@ -201,7 +199,7 @@ static bool VerifyAutoreplaceRefitForOrders(const Vehicle *v, EngineID engine_ty */ static CargoID GetNewCargoTypeForReplace(Vehicle *v, EngineID engine_type, bool part_of_chain) { - uint32 available_cargo_types, union_mask; + CargoTypes available_cargo_types, union_mask; GetArticulatedRefitMasks(engine_type, true, &union_mask, &available_cargo_types); if (union_mask == 0) return CT_NO_REFIT; // Don't try to refit an engine with no cargo capacity @@ -238,7 +236,7 @@ static CargoID GetNewCargoTypeForReplace(Vehicle *v, EngineID engine_type, bool * @param v The vehicle to find a replacement for * @param c The vehicle's owner (it's faster to forward the pointer than refinding it) * @param always_replace Always replace, even if not old. - * @param [out] e the EngineID of the replacement. INVALID_ENGINE if no replacement is found + * @param[out] e the EngineID of the replacement. INVALID_ENGINE if no replacement is found * @return Error if the engine to build is not available */ static CommandCost GetNewEngineType(const Vehicle *v, const Company *c, bool always_replace, EngineID &e) diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index 1074d1dd78..eae0a378eb 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -81,7 +81,7 @@ class ReplaceVehicleWindow : public Window { EngineID sel_engine[2]; ///< Selected engine left and right. GUIEngineList engines[2]; ///< Left and right list of engines. bool replace_engines; ///< If \c true, engines are replaced, if \c false, wagons are replaced (only for trains). - bool reset_sel_engine; ///< Also reset #sel_engine while updating left and/or right (#update_left and/or #update_right) and no valid engine selected. + bool reset_sel_engine; ///< Also reset #sel_engine while updating left and/or right and no valid engine selected. GroupID sel_group; ///< Group selected to replace. int details_height; ///< Minimal needed height of the details panels (found so far). byte sort_criteria; ///< Criteria of sorting vehicles. diff --git a/src/base_media_base.h b/src/base_media_base.h index 7614118b7f..b040abcf9d 100644 --- a/src/base_media_base.h +++ b/src/base_media_base.h @@ -26,6 +26,7 @@ struct ContentInfo; struct MD5File { /** The result of a checksum check */ enum ChecksumResult { + CR_UNKNOWN, ///< The file has not been checked yet CR_MATCH, ///< The file did exist and the md5 checksum did match CR_MISMATCH, ///< The file did exist, just the md5 checksum did not match CR_NO_FILE, ///< The file did not exist @@ -34,6 +35,7 @@ struct MD5File { const char *filename; ///< filename uint8 hash[16]; ///< md5 sum of the file const char *missing_warning; ///< warning when this file is missing + ChecksumResult check_result; ///< cached result of md5 check ChecksumResult CheckMD5(Subdirectory subdir, size_t max_size) const; }; @@ -285,11 +287,32 @@ static const uint NUM_SONGS_AVAILABLE = 1 + NUM_SONG_CLASSES * NUM_SONGS_CLASS; /** Maximum number of songs in the (custom) playlist */ static const uint NUM_SONGS_PLAYLIST = 32; +/* Functions to read DOS music CAT files, similar to but not quite the same as sound effect CAT files */ +char *GetMusicCatEntryName(const char *filename, size_t entrynum); +byte *GetMusicCatEntryData(const char *filename, size_t entrynum, size_t &entrylen); + +enum MusicTrackType { + MTT_STANDARDMIDI, ///< Standard MIDI file + MTT_MPSMIDI, ///< MPS GM driver MIDI format (contained in a CAT file) +}; + +/** Metadata about a music track. */ +struct MusicSongInfo { + char songname[32]; ///< name of song displayed in UI + byte tracknr; ///< track number of song displayed in UI + const char *filename; ///< file on disk containing song (when used in MusicSet class, this pointer is owned by MD5File object for the file) + MusicTrackType filetype; ///< decoder required for song file + int cat_index; ///< entry index in CAT file, for filetype==MTT_MPSMIDI + bool loop; ///< song should play in a tight loop if possible, never ending + int override_start; ///< MIDI ticks to skip over in beginning + int override_end; ///< MIDI tick to end the song at (0 if no override) +}; + /** All data of a music set. */ struct MusicSet : BaseSet { - /** The name of the different songs. */ - char song_name[NUM_SONGS_AVAILABLE][32]; - byte track_nr[NUM_SONGS_AVAILABLE]; + /** Data about individual songs in set. */ + MusicSongInfo songinfo[NUM_SONGS_AVAILABLE]; + /** Number of valid songs in set. */ byte num_available; bool FillSetDetails(struct IniFile *ini, const char *path, const char *full_filename); diff --git a/src/base_media_func.h b/src/base_media_func.h index f45956f765..f7afca0edb 100644 --- a/src/base_media_func.h +++ b/src/base_media_func.h @@ -40,8 +40,6 @@ template bool BaseSet::FillSetDetails(IniFile *ini, const char *path, const char *full_filename, bool allow_empty_filename) { - memset(this, 0, sizeof(*this)); - IniGroup *metadata = ini->GetGroup("metadata"); IniItem *item; @@ -129,7 +127,11 @@ bool BaseSet::FillSetDetails(IniFile *ini, const file->missing_warning = stredup(item->value); } - switch (T::CheckMD5(file, BASESET_DIR)) { + file->check_result = T::CheckMD5(file, BASESET_DIR); + switch (file->check_result) { + case MD5File::CR_UNKNOWN: + break; + case MD5File::CR_MATCH: this->valid_files++; this->found_files++; diff --git a/src/base_station_base.h b/src/base_station_base.h index 53e104a826..cd512c5177 100644 --- a/src/base_station_base.h +++ b/src/base_station_base.h @@ -71,7 +71,7 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> { uint16 random_bits; ///< Random bits assigned to this station byte waiting_triggers; ///< Waiting triggers (NewGRF) for this station uint8 cached_anim_triggers; ///< NOSAVE: Combined animation trigger bitmask, used to determine if trigger processing should happen. - uint32 cached_cargo_triggers; ///< NOSAVE: Combined cargo trigger bitmask + CargoTypes cached_cargo_triggers; ///< NOSAVE: Combined cargo trigger bitmask TileArea train_station; ///< Tile area the train 'station' part covers StationRect rect; ///< NOSAVE: Station spread out rectangle maintained by StationRect::xxx() functions diff --git a/src/blitter/32bpp_anim.cpp b/src/blitter/32bpp_anim.cpp index 532ad23cc7..98ae22b00c 100644 --- a/src/blitter/32bpp_anim.cpp +++ b/src/blitter/32bpp_anim.cpp @@ -22,7 +22,7 @@ static FBlitter_32bppAnim iFBlitter_32bppAnim; Blitter_32bppAnim::~Blitter_32bppAnim() { - free(this->anim_buf); + free(this->anim_alloc); } template @@ -39,8 +39,7 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel } Colour *dst = (Colour *)bp->dst + bp->top * bp->pitch + bp->left; - assert(_screen.pitch == this->anim_buf_pitch); // precondition for translating 'bp->dst' into an 'anim_buf' offset below. - uint16 *anim = this->anim_buf + ((uint32 *)bp->dst - (uint32 *)_screen.dst_ptr) + bp->top * this->anim_buf_pitch + bp->left; + uint16 *anim = this->anim_buf + this->ScreenToAnimOffset((uint32 *)bp->dst) + bp->top * this->anim_buf_pitch + bp->left; const byte *remap = bp->remap; // store so we don't have to access it via bp everytime @@ -280,8 +279,7 @@ void Blitter_32bppAnim::DrawColourMappingRect(void *dst, int width, int height, } Colour *udst = (Colour *)dst; - assert(_screen.pitch == this->anim_buf_pitch); // precondition for translating 'dst' into an 'anim_buf' offset below. - uint16 *anim = this->anim_buf + ((uint32 *)dst - (uint32 *)_screen.dst_ptr); + uint16 *anim = this->anim_buf + this->ScreenToAnimOffset((uint32 *)dst); if (pal == PALETTE_TO_TRANSPARENT) { do { @@ -319,8 +317,8 @@ void Blitter_32bppAnim::SetPixel(void *video, int x, int y, uint8 colour) /* Set the colour in the anim-buffer too, if we are rendering to the screen */ if (_screen_disable_anim) return; - assert(_screen.pitch == this->anim_buf_pitch); // precondition for translating 'video' into an 'anim_buf' offset below. - this->anim_buf[((uint32 *)video - (uint32 *)_screen.dst_ptr) + x + y * this->anim_buf_pitch] = colour | (DEFAULT_BRIGHTNESS << 8); + + this->anim_buf[this->ScreenToAnimOffset((uint32 *)video) + x + y * this->anim_buf_pitch] = colour | (DEFAULT_BRIGHTNESS << 8); } void Blitter_32bppAnim::DrawRect(void *video, int width, int height, uint8 colour) @@ -332,8 +330,7 @@ void Blitter_32bppAnim::DrawRect(void *video, int width, int height, uint8 colou } Colour colour32 = LookupColourInPalette(colour); - assert(_screen.pitch == this->anim_buf_pitch); // precondition for translating 'video' into an 'anim_buf' offset below. - uint16 *anim_line = ((uint32 *)video - (uint32 *)_screen.dst_ptr) + this->anim_buf; + uint16 *anim_line = this->ScreenToAnimOffset((uint32 *)video) + this->anim_buf; do { Colour *dst = (Colour *)video; @@ -357,15 +354,14 @@ void Blitter_32bppAnim::CopyFromBuffer(void *video, const void *src, int width, assert(video >= _screen.dst_ptr && video <= (uint32 *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch); Colour *dst = (Colour *)video; const uint32 *usrc = (const uint32 *)src; - assert(_screen.pitch == this->anim_buf_pitch); // precondition for translating 'video' into an 'anim_buf' offset below. - uint16 *anim_line = ((uint32 *)video - (uint32 *)_screen.dst_ptr) + this->anim_buf; + uint16 *anim_line = this->ScreenToAnimOffset((uint32 *)video) + this->anim_buf; for (; height > 0; height--) { /* We need to keep those for palette animation. */ Colour *dst_pal = dst; uint16 *anim_pal = anim_line; - memcpy(dst, usrc, width * sizeof(uint32)); + memcpy(static_cast(dst), usrc, width * sizeof(uint32)); usrc += width; dst += _screen.pitch; /* Copy back the anim-buffer */ @@ -401,8 +397,7 @@ void Blitter_32bppAnim::CopyToBuffer(const void *video, void *dst, int width, in if (this->anim_buf == NULL) return; - assert(_screen.pitch == this->anim_buf_pitch); // precondition for translating 'video' into an 'anim_buf' offset below. - const uint16 *anim_line = ((const uint32 *)video - (uint32 *)_screen.dst_ptr) + this->anim_buf; + const uint16 *anim_line = this->ScreenToAnimOffset((const uint32 *)video) + this->anim_buf; for (; height > 0; height--) { memcpy(udst, src, width * sizeof(uint32)); @@ -485,18 +480,22 @@ void Blitter_32bppAnim::PaletteAnimate(const Palette &palette) Colour *dst = (Colour *)_screen.dst_ptr; /* Let's walk the anim buffer and try to find the pixels */ + const int width = this->anim_buf_width; + const int pitch_offset = _screen.pitch - width; + const int anim_pitch_offset = this->anim_buf_pitch - width; for (int y = this->anim_buf_height; y != 0 ; y--) { - for (int x = this->anim_buf_width; x != 0 ; x--) { - uint colour = GB(*anim, 0, 8); + for (int x = width; x != 0 ; x--) { + uint16 value = *anim; + uint8 colour = GB(value, 0, 8); if (colour >= PALETTE_ANIM_START) { /* Update this pixel */ - *dst = this->AdjustBrightness(LookupColourInPalette(colour), GB(*anim, 8, 8)); + *dst = this->AdjustBrightness(LookupColourInPalette(colour), GB(value, 8, 8)); } dst++; anim++; } - dst += _screen.pitch - this->anim_buf_width; - anim += this->anim_buf_pitch - this->anim_buf_width; + dst += pitch_offset; + anim += anim_pitch_offset; } /* Make sure the backend redraws the whole screen */ @@ -513,10 +512,13 @@ void Blitter_32bppAnim::PostResize() if (_screen.width != this->anim_buf_width || _screen.height != this->anim_buf_height || _screen.pitch != this->anim_buf_pitch) { /* The size of the screen changed; we can assume we can wipe all data from our buffer */ - free(this->anim_buf); + free(this->anim_alloc); this->anim_buf_width = _screen.width; this->anim_buf_height = _screen.height; - this->anim_buf_pitch = _screen.pitch; - this->anim_buf = CallocT(this->anim_buf_height * this->anim_buf_pitch); + this->anim_buf_pitch = (_screen.width + 7) & ~7; + this->anim_alloc = CallocT(this->anim_buf_pitch * this->anim_buf_height + 8); + + /* align buffer to next 16 byte boundary */ + this->anim_buf = reinterpret_cast((reinterpret_cast(this->anim_alloc) + 0xF) & (~0xF)); } } diff --git a/src/blitter/32bpp_anim.hpp b/src/blitter/32bpp_anim.hpp index 1b35c17663..da33ec95bb 100644 --- a/src/blitter/32bpp_anim.hpp +++ b/src/blitter/32bpp_anim.hpp @@ -18,14 +18,16 @@ class Blitter_32bppAnim : public Blitter_32bppOptimized { protected: uint16 *anim_buf; ///< In this buffer we keep track of the 8bpp indexes so we can do palette animation + void *anim_alloc; ///< The raw allocated buffer, not necessarily aligned correctly int anim_buf_width; ///< The width of the animation buffer. int anim_buf_height; ///< The height of the animation buffer. - int anim_buf_pitch; ///< The pitch of the animation buffer. + int anim_buf_pitch; ///< The pitch of the animation buffer (width rounded up to 16 byte boundary). Palette palette; ///< The current palette. public: Blitter_32bppAnim() : anim_buf(NULL), + anim_alloc(NULL), anim_buf_width(0), anim_buf_height(0), anim_buf_pitch(0) @@ -58,6 +60,15 @@ public: return this->palette.palette[index]; } + inline int ScreenToAnimOffset(const uint32 *video) + { + int raw_offset = video - (const uint32 *)_screen.dst_ptr; + if (_screen.pitch == this->anim_buf_pitch) return raw_offset; + int lines = raw_offset / _screen.pitch; + int across = raw_offset % _screen.pitch; + return across + (lines * this->anim_buf_pitch); + } + template void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom); }; diff --git a/src/blitter/32bpp_anim_sse2.cpp b/src/blitter/32bpp_anim_sse2.cpp new file mode 100644 index 0000000000..d5fa4268a8 --- /dev/null +++ b/src/blitter/32bpp_anim_sse2.cpp @@ -0,0 +1,100 @@ +/* $Id$ */ + +/* + * 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 . + */ + +/** @file 32bpp_anim.cpp Implementation of a partially SSSE2 32bpp blitter with animation support. */ + +#ifdef WITH_SSE + +#include "../stdafx.h" +#include "../video/video_driver.hpp" +#include "32bpp_anim_sse2.hpp" +#include "32bpp_sse_func.hpp" + +#include "../safeguards.h" + +/** Instantiation of the partially SSSE2 32bpp with animation blitter factory. */ +static FBlitter_32bppSSE2_Anim iFBlitter_32bppSSE2_Anim; + +void Blitter_32bppSSE2_Anim::PaletteAnimate(const Palette &palette) +{ + assert(!_screen_disable_anim); + + this->palette = palette; + /* If first_dirty is 0, it is for 8bpp indication to send the new + * palette. However, only the animation colours might possibly change. + * Especially when going between toyland and non-toyland. */ + assert(this->palette.first_dirty == PALETTE_ANIM_START || this->palette.first_dirty == 0); + + const uint16 *anim = this->anim_buf; + Colour *dst = (Colour *)_screen.dst_ptr; + + bool screen_dirty = false; + + /* Let's walk the anim buffer and try to find the pixels */ + const int width = this->anim_buf_width; + const int screen_pitch = _screen.pitch; + const int anim_pitch = this->anim_buf_pitch; + __m128i anim_cmp = _mm_set1_epi16(PALETTE_ANIM_START - 1); + __m128i brightness_cmp = _mm_set1_epi16(Blitter_32bppBase::DEFAULT_BRIGHTNESS); + __m128i colour_mask = _mm_set1_epi16(0xFF); + for (int y = this->anim_buf_height; y != 0 ; y--) { + Colour *next_dst_ln = dst + screen_pitch; + const uint16 *next_anim_ln = anim + anim_pitch; + int x = width; + while (x > 0) { + __m128i data = _mm_load_si128((const __m128i *) anim); + + /* low bytes only, shifted into high positions */ + __m128i colour_data = _mm_and_si128(data, colour_mask); + + /* test if any colour >= PALETTE_ANIM_START */ + int colour_cmp_result = _mm_movemask_epi8(_mm_cmpgt_epi16(colour_data, anim_cmp)); + if (colour_cmp_result) { + /* test if any brightness is unexpected */ + if (x < 8 || colour_cmp_result != 0xFFFF || + _mm_movemask_epi8(_mm_cmpeq_epi16(_mm_srli_epi16(data, 8), brightness_cmp)) != 0xFFFF) { + /* slow path: < 8 pixels left or unexpected brightnesses */ + for (int z = min(x, 8); z != 0 ; z--) { + int value = _mm_extract_epi16(data, 0); + uint8 colour = GB(value, 0, 8); + if (colour >= PALETTE_ANIM_START) { + /* Update this pixel */ + *dst = AdjustBrightneSSE(LookupColourInPalette(colour), GB(value, 8, 8)); + screen_dirty = true; + } + data = _mm_srli_si128(data, 2); + dst++; + } + } else { + /* medium path: 8 pixels to animate all of expected brightnesses */ + for (int z = 0; z < 8; z++) { + *dst = LookupColourInPalette(_mm_extract_epi16(colour_data, 0)); + colour_data = _mm_srli_si128(colour_data, 2); + dst++; + } + screen_dirty = true; + } + } else { + /* fast path, no animation */ + dst += 8; + } + anim += 8; + x -= 8; + } + dst = next_dst_ln; + anim = next_anim_ln; + } + + if (screen_dirty) { + /* Make sure the backend redraws the whole screen */ + VideoDriver::GetInstance()->MakeDirty(0, 0, _screen.width, _screen.height); + } +} + +#endif /* WITH_SSE */ diff --git a/src/blitter/32bpp_anim_sse2.hpp b/src/blitter/32bpp_anim_sse2.hpp new file mode 100644 index 0000000000..0d4a5f1e65 --- /dev/null +++ b/src/blitter/32bpp_anim_sse2.hpp @@ -0,0 +1,43 @@ +/* $Id$ */ + +/* + * 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 . + */ + +/** @file 32bpp_anim.hpp A partially SSE2 32 bpp blitter with animation support. */ + +#ifndef BLITTER_32BPP_SSE2_ANIM_HPP +#define BLITTER_32BPP_SSE2_ANIM_HPP + +#ifdef WITH_SSE + +#ifndef SSE_VERSION +#define SSE_VERSION 2 +#endif + +#ifndef FULL_ANIMATION +#define FULL_ANIMATION 1 +#endif + +#include "32bpp_anim.hpp" +#include "32bpp_sse2.hpp" + +/** A partially 32 bpp blitter with palette animation. */ +class Blitter_32bppSSE2_Anim : public Blitter_32bppAnim { +public: + /* virtual */ void PaletteAnimate(const Palette &palette); + /* virtual */ const char *GetName() { return "32bpp-sse2-anim"; } +}; + +/** Factory for the partially 32bpp blitter with animation. */ +class FBlitter_32bppSSE2_Anim : public BlitterFactory { +public: + FBlitter_32bppSSE2_Anim() : BlitterFactory("32bpp-sse2-anim", "32bpp partially SSE2 Animation Blitter (palette animation)", HasCPUIDFlag(1, 3, 26)) {} + /* virtual */ Blitter *CreateInstance() { return new Blitter_32bppSSE2_Anim(); } +}; + +#endif /* WITH_SSE */ +#endif /* BLITTER_32BPP_ANIM_HPP */ diff --git a/src/blitter/32bpp_anim_sse4.cpp b/src/blitter/32bpp_anim_sse4.cpp index 987cb0c6ac..24d1d7531f 100644 --- a/src/blitter/32bpp_anim_sse4.cpp +++ b/src/blitter/32bpp_anim_sse4.cpp @@ -7,7 +7,7 @@ * 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 . */ -/** @file 32bpp_sse4_anim.cpp Implementation of the SSE4 32 bpp blitter with animation support. */ +/** @file 32bpp_anim_sse4.cpp Implementation of the SSE4 32 bpp blitter with animation support. */ #ifdef WITH_SSE @@ -35,8 +35,7 @@ inline void Blitter_32bppSSE4_Anim::Draw(const Blitter::BlitterParams *bp, ZoomL { const byte * const remap = bp->remap; Colour *dst_line = (Colour *) bp->dst + bp->top * bp->pitch + bp->left; - assert(_screen.pitch == this->anim_buf_pitch); // precondition for translating 'bp->dst' into an 'anim_buf' offset below. - uint16 *anim_line = this->anim_buf + ((uint32 *)bp->dst - (uint32 *)_screen.dst_ptr) + bp->top * this->anim_buf_pitch + bp->left; + uint16 *anim_line = this->anim_buf + this->ScreenToAnimOffset((uint32 *)bp->dst) + bp->top * this->anim_buf_pitch + bp->left; int effective_width = bp->width; /* Find where to start reading in the source sprite. */ diff --git a/src/blitter/32bpp_anim_sse4.hpp b/src/blitter/32bpp_anim_sse4.hpp index e2d4cfc231..5ff1fb01be 100644 --- a/src/blitter/32bpp_anim_sse4.hpp +++ b/src/blitter/32bpp_anim_sse4.hpp @@ -7,7 +7,7 @@ * 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 . */ -/** @file 32bpp_sse4_anim.hpp A SSE4 32 bpp blitter with animation support. */ +/** @file 32bpp_anim_sse4.hpp A SSE4 32 bpp blitter with animation support. */ #ifndef BLITTER_32BPP_SSE4_ANIM_HPP #define BLITTER_32BPP_SSE4_ANIM_HPP @@ -23,13 +23,14 @@ #endif #include "32bpp_anim.hpp" +#include "32bpp_anim_sse2.hpp" #include "32bpp_sse4.hpp" #undef MARGIN_NORMAL_THRESHOLD #define MARGIN_NORMAL_THRESHOLD 4 /** The SSE4 32 bpp blitter with palette animation. */ -class Blitter_32bppSSE4_Anim FINAL : public Blitter_32bppAnim, public Blitter_32bppSSE_Base { +class Blitter_32bppSSE4_Anim FINAL : public Blitter_32bppSSE2_Anim, public Blitter_32bppSSE_Base { private: public: diff --git a/src/blitter/32bpp_base.cpp b/src/blitter/32bpp_base.cpp index 26dd2f037e..c396e45410 100644 --- a/src/blitter/32bpp_base.cpp +++ b/src/blitter/32bpp_base.cpp @@ -143,6 +143,36 @@ void Blitter_32bppBase::PaletteAnimate(const Palette &palette) /* By default, 32bpp doesn't have palette animation */ } +Colour Blitter_32bppBase::ReallyAdjustBrightness(Colour colour, uint8 brightness) +{ + assert(DEFAULT_BRIGHTNESS == 1 << 7); + + uint64 combined = (((uint64) colour.r) << 32) | (((uint64) colour.g) << 16) | ((uint64) colour.b); + combined *= brightness; + + uint16 r = GB(combined, 39, 9); + uint16 g = GB(combined, 23, 9); + uint16 b = GB(combined, 7, 9); + + if ((combined & 0x800080008000L) == 0L) { + return Colour(r, g, b, colour.a); + } + + uint16 ob = 0; + /* Sum overbright */ + if (r > 255) ob += r - 255; + if (g > 255) ob += g - 255; + if (b > 255) ob += b - 255; + + /* Reduce overbright strength */ + ob /= 2; + return Colour( + r >= 255 ? 255 : min(r + ob * (255 - r) / 256, 255), + g >= 255 ? 255 : min(g + ob * (255 - g) / 256, 255), + b >= 255 ? 255 : min(b + ob * (255 - b) / 256, 255), + colour.a); +} + Blitter::PaletteAnimation Blitter_32bppBase::UsePaletteAnimation() { return Blitter::PALETTE_ANIMATION_NONE; diff --git a/src/blitter/32bpp_base.hpp b/src/blitter/32bpp_base.hpp index 26c3dee3fd..9b76271704 100644 --- a/src/blitter/32bpp_base.hpp +++ b/src/blitter/32bpp_base.hpp @@ -146,30 +146,14 @@ public: static const int DEFAULT_BRIGHTNESS = 128; + static Colour ReallyAdjustBrightness(Colour colour, uint8 brightness); + static inline Colour AdjustBrightness(Colour colour, uint8 brightness) { /* Shortcut for normal brightness */ if (brightness == DEFAULT_BRIGHTNESS) return colour; - uint16 ob = 0; - uint16 r = colour.r * brightness / DEFAULT_BRIGHTNESS; - uint16 g = colour.g * brightness / DEFAULT_BRIGHTNESS; - uint16 b = colour.b * brightness / DEFAULT_BRIGHTNESS; - - /* Sum overbright */ - if (r > 255) ob += r - 255; - if (g > 255) ob += g - 255; - if (b > 255) ob += b - 255; - - if (ob == 0) return Colour(r, g, b, colour.a); - - /* Reduce overbright strength */ - ob /= 2; - return Colour( - r >= 255 ? 255 : min(r + ob * (255 - r) / 256, 255), - g >= 255 ? 255 : min(g + ob * (255 - g) / 256, 255), - b >= 255 ? 255 : min(b + ob * (255 - b) / 256, 255), - colour.a); + return ReallyAdjustBrightness(colour, brightness); } }; diff --git a/src/blitter/32bpp_sse_type.h b/src/blitter/32bpp_sse_type.h index b32d3c5abd..49c7a68c20 100644 --- a/src/blitter/32bpp_sse_type.h +++ b/src/blitter/32bpp_sse_type.h @@ -7,10 +7,10 @@ * 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 . */ -/** @file 32bpp_sse_type.hpp Types related to SSE 32 bpp blitter. */ +/** @file 32bpp_sse_type.h Types related to SSE 32 bpp blitter. */ -#ifndef BLITTER_32BPP_SSE_TYPE_HPP -#define BLITTER_32BPP_SSE_TYPE_HPP +#ifndef BLITTER_32BPP_SSE_TYPE_H +#define BLITTER_32BPP_SSE_TYPE_H #ifdef WITH_SSE @@ -55,4 +55,4 @@ typedef union ALIGN(16) um128i { #define TRANSPARENT_NOM_BASE _mm_setr_epi16(256, 256, 256, 256, 256, 256, 256, 256) #endif /* WITH_SSE */ -#endif /* BLITTER_32BPP_SSE_TYPE_HPP */ +#endif /* BLITTER_32BPP_SSE_TYPE_H */ diff --git a/src/bootstrap_gui.cpp b/src/bootstrap_gui.cpp index 62f5450c5b..3fb52a1f9e 100644 --- a/src/bootstrap_gui.cpp +++ b/src/bootstrap_gui.cpp @@ -220,7 +220,7 @@ bool HandleBootstrap() if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 0) goto failure; /* If there is no network or no freetype, then there is nothing we can do. Go straight to failure. */ -#if defined(ENABLE_NETWORK) && defined(WITH_FREETYPE) && (defined(WITH_FONTCONFIG) || defined(WIN32) || defined(__APPLE__)) +#if defined(ENABLE_NETWORK) && defined(WITH_FREETYPE) && (defined(WITH_FONTCONFIG) || defined(_WIN32) || defined(__APPLE__)) if (!_network_available) goto failure; /* First tell the game we're bootstrapping. */ diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp index 797ead1f51..768691f080 100644 --- a/src/bridge_gui.cpp +++ b/src/bridge_gui.cpp @@ -55,7 +55,7 @@ typedef GUIList GUIBridgeList; ///< List of bridges, used in #B * @param p1 packed start tile coords (~ dx) * @param p2 various bitstuffed elements * - p2 = (bit 0- 7) - bridge type (hi bh) - * - p2 = (bit 8-11) - rail type or road types. + * - p2 = (bit 8-13) - rail type or road types. * - p2 = (bit 15-16) - transport type. */ void CcBuildBridge(const CommandCost &result, TileIndex end_tile, uint32 p1, uint32 p2) diff --git a/src/bridge_map.cpp b/src/bridge_map.cpp index d1e0d6024a..b738895065 100644 --- a/src/bridge_map.cpp +++ b/src/bridge_map.cpp @@ -56,7 +56,7 @@ TileIndex GetSouthernBridgeEnd(TileIndex t) /** * Starting at one bridge end finds the other bridge end - * @param t the bridge ramp tile to find the other bridge ramp for + * @param tile the bridge ramp tile to find the other bridge ramp for */ TileIndex GetOtherBridgeEnd(TileIndex tile) { @@ -66,7 +66,7 @@ TileIndex GetOtherBridgeEnd(TileIndex tile) /** * Get the height ('z') of a bridge. - * @param tile the bridge ramp tile to get the bridge height from + * @param t the bridge ramp tile to get the bridge height from * @return the height of the bridge. */ int GetBridgeHeight(TileIndex t) diff --git a/src/bridge_map.h b/src/bridge_map.h index 74c6974db2..75b20498d1 100644 --- a/src/bridge_map.h +++ b/src/bridge_map.h @@ -131,11 +131,12 @@ static inline void MakeBridgeRamp(TileIndex t, Owner o, BridgeType bridgetype, D SetTileType(t, MP_TUNNELBRIDGE); SetTileOwner(t, o); _m[t].m2 = 0; - _m[t].m3 = rt; + _m[t].m3 = 0; _m[t].m4 = 0; _m[t].m5 = 1 << 7 | tt << 2 | d; SB(_me[t].m6, 2, 4, bridgetype); _me[t].m7 = 0; + _me[t].m8 = rt; } /** diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 655a18d7f8..51247e84ba 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -524,7 +524,7 @@ const StringID _engine_sort_listing[][12] = {{ static bool CDECL CargoFilter(const EngineID *eid, const CargoID cid) { if (cid == CF_ANY) return true; - uint32 refit_mask = GetUnionOfArticulatedRefitMasks(*eid, true) & _standard_cargo_mask; + CargoTypes refit_mask = GetUnionOfArticulatedRefitMasks(*eid, true) & _standard_cargo_mask; return (cid == CF_NONE ? refit_mask == 0 : HasBit(refit_mask, cid)); } @@ -535,7 +535,7 @@ static GUIEngineList::FilterFunction * const _filter_funcs[] = { static int DrawCargoCapacityInfo(int left, int right, int y, EngineID engine) { CargoArray cap; - uint32 refits; + CargoTypes refits; GetArticulatedVehicleCargoesAndRefits(engine, &cap, &refits); for (CargoID c = 0; c < NUM_CARGO; c++) { diff --git a/src/cargo_type.h b/src/cargo_type.h index 7b7168a102..79d1c84f46 100644 --- a/src/cargo_type.h +++ b/src/cargo_type.h @@ -22,7 +22,7 @@ typedef byte CargoID; /** Available types of cargo */ -enum CargoTypes { +enum CargoType { /* Temperate */ CT_PASSENGERS = 0, CT_COAL = 1, @@ -63,13 +63,22 @@ enum CargoTypes { CT_PLASTIC = 10, CT_FIZZY_DRINKS = 11, - NUM_CARGO = 32, ///< 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_NO_REFIT = 0xFE, ///< Do not refit cargo of a vehicle (used in vehicle orders and auto-replace/auto-new). CT_INVALID = 0xFF, ///< Invalid cargo type. }; +/** Test whether cargo type is not CT_INVALID */ +inline bool IsCargoTypeValid(CargoType t) { return t != CT_INVALID; } +/** Test whether cargo type is not CT_INVALID */ +inline bool IsCargoIDValid(CargoID t) { return t != CT_INVALID; } + +typedef uint64 CargoTypes; + +static const CargoTypes ALL_CARGOTYPES = (CargoTypes)UINT64_MAX; + /** Class for storing amounts of cargo */ struct CargoArray { private: diff --git a/src/cargopacket.cpp b/src/cargopacket.cpp index 9b96be62eb..9e699d6f42 100644 --- a/src/cargopacket.cpp +++ b/src/cargopacket.cpp @@ -602,7 +602,7 @@ uint VehicleCargoList::ReassignIsValid()) #define FOR_ALL_CARGOSPECS(var) FOR_ALL_CARGOSPECS_FROM(var, 0) -#define FOR_EACH_SET_CARGO_ID(var, cargo_bits) FOR_EACH_SET_BIT_EX(CargoID, var, uint, cargo_bits) +#define FOR_EACH_SET_CARGO_ID(var, cargo_bits) FOR_EACH_SET_BIT_EX(CargoID, var, CargoTypes, cargo_bits) /** * Loop header for iterating over cargoes, sorted by name. This includes phony cargoes like regearing cargoes. diff --git a/src/clear_map.h b/src/clear_map.h index 76b1e82d04..d24916de35 100644 --- a/src/clear_map.h +++ b/src/clear_map.h @@ -269,6 +269,7 @@ static inline void MakeClear(TileIndex t, ClearGround g, uint density) SetClearGroundDensity(t, g, density); // Sets m5 _me[t].m6 = 0; _me[t].m7 = 0; + _me[t].m8 = 0; } @@ -289,6 +290,7 @@ static inline void MakeField(TileIndex t, uint field_type, IndustryID industry) SetClearGroundDensity(t, CLEAR_FIELDS, 3); SB(_me[t].m6, 2, 4, 0); _me[t].m7 = 0; + _me[t].m8 = 0; } /** diff --git a/src/command.cpp b/src/command.cpp index df0cd004c3..e7a5a3c36b 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -605,7 +605,6 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallbac /** * Helper to deduplicate the code for returning. * @param cmd the command cost to return. - * @param clear whether to keep the storage changes or not. */ #define return_dcpi(cmd) { _docommand_recursive = 0; return cmd; } diff --git a/src/company_base.h b/src/company_base.h index 4d76e6251a..9d2bc90009 100644 --- a/src/company_base.h +++ b/src/company_base.h @@ -67,8 +67,6 @@ struct CompanyProperties { byte colour; ///< Company colour. - RailTypes avail_railtypes; ///< Rail types available to the company. - byte block_preview; ///< Number of quarters that the company is not allowed to get new exclusive engine previews (see CompaniesGenStatistics). TileIndex location_of_HQ; ///< Northern tile of HQ; #INVALID_TILE when there is none. @@ -93,12 +91,18 @@ struct CompanyProperties { */ bool is_ai; - Money yearly_expenses[3][EXPENSES_END]; ///< Expenses of the company for the last three years, in every #Expenses category. + Money yearly_expenses[3][EXPENSES_END]; ///< Expenses of the company for the last three years, in every #ExpensesType category. CompanyEconomyEntry cur_economy; ///< Economic data of the company of this quarter. CompanyEconomyEntry old_economy[MAX_HISTORY_QUARTERS]; ///< Economic data of the company of the last #MAX_HISTORY_QUARTERS quarters. byte num_valid_stat_ent; ///< Number of valid statistical entries in #old_economy. - CompanyProperties() : name(NULL), president_name(NULL) {} + // TODO: Change some of these member variables to use relevant INVALID_xxx constants + CompanyProperties() + : name_2(0), name_1(0), name(NULL), president_name_1(0), president_name_2(0), president_name(NULL), + 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), + months_of_bankruptcy(0), bankrupt_asked(0), bankrupt_timeout(0), bankrupt_value(0), + terraform_limit(0), clear_limit(0), tree_limit(0), is_ai(false) {} ~CompanyProperties() { @@ -112,6 +116,7 @@ struct Company : CompanyPool::PoolItem<&_company_pool>, CompanyProperties { ~Company(); Livery livery[LS_END]; + RailTypes avail_railtypes; ///< Rail types available to this company. RoadTypes avail_roadtypes; ///< Road types available to this company. class AIInstance *ai_instance; diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index ee2ed13355..c4e1a89d72 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -188,7 +188,7 @@ void InvalidateCompanyWindows(const Company *company) /** * Verify whether the company can pay the bill. - * @param cost [inout] Money to pay, is changed to an error if the company does not have enough money. + * @param[in,out] cost Money to pay, is changed to an error if the company does not have enough money. * @return Function returns \c true if the company has enough money, else it returns \c false. */ bool CheckCompanyHasMoney(CommandCost &cost) diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 31d4fdd1f0..ac9ca9bda9 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -268,10 +268,7 @@ static const NWidgetPart _nested_company_finances_widgets[] = { EndContainer(), }; -/** - * Window class displaying the company finances. - * @todo #money_width should be calculated dynamically. - */ +/** Window class displaying the company finances. */ struct CompanyFinancesWindow : Window { static Money max_money; ///< The maximum amount of money a company has had this 'run' bool small; ///< Window is toggled to 'small'. @@ -1509,9 +1506,6 @@ static WindowDesc _select_company_manager_face_desc( * Open the simple/advanced company manager face selection window * * @param parent the parent company window - * @param adv simple or advanced face selection window - * @param top previous top position of the window - * @param left previous left position of the window */ static void DoSelectCompanyManagerFace(Window *parent) { diff --git a/src/console.cpp b/src/console.cpp index 6e9b46f6b0..2cf9d96958 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -235,8 +235,8 @@ void IConsoleAddSorted(T **base, T *item_new) /** * Remove underscores from a string; the string will be modified! - * @param name The string to remove the underscores from. - * @return #name. + * @param[in,out] name String to remove the underscores from. + * @return \a name, with its contents modified. */ char *RemoveUnderscores(char *name) { diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 3b65224de8..d9155a97db 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -62,7 +62,7 @@ public: /** * (Re-)validate the file storage cache. Only makes a change if the storage was invalid, or if \a force_reload. - * @param Always reload the file storage cache. + * @param force_reload Always reload the file storage cache. */ void ValidateFileList(bool force_reload = false) { @@ -256,8 +256,8 @@ DEF_CONSOLE_CMD(ConResetTile) /** * Scroll to a tile on the map. - * @param arg1 tile tile number or tile x coordinate. - * @param arg2 optionally tile y coordinate. + * param x tile number or tile x coordinate. + * param y optional y coordinate. * @note When only one argument is given it is intepreted as the tile number. * When two arguments are given, they are interpreted as the tile's x * and y coordinates. @@ -304,7 +304,7 @@ DEF_CONSOLE_CMD(ConScrollToTile) /** * Save the map to a file. - * @param filename the filename to save the map to. + * param filename the filename to save the map to. * @return True when help was displayed or the file attempted to be saved. */ DEF_CONSOLE_CMD(ConSave) @@ -1895,6 +1895,37 @@ static void IConsoleDebugLibRegister() } #endif +DEF_CONSOLE_CMD(ConFramerate) +{ + extern void ConPrintFramerate(); // framerate_gui.cpp + + if (argc == 0) { + IConsoleHelp("Show frame rate and game speed information"); + return true; + } + + ConPrintFramerate(); + return true; +} + +DEF_CONSOLE_CMD(ConFramerateWindow) +{ + extern void ShowFramerateWindow(); + + if (argc == 0) { + IConsoleHelp("Open the frame rate window"); + return true; + } + + if (_network_dedicated) { + IConsoleError("Can not open frame rate window on a dedicated server"); + return false; + } + + ShowFramerateWindow(); + return true; +} + /******************************* * console command registration *******************************/ @@ -2025,6 +2056,8 @@ void IConsoleStdLibRegister() #ifdef _DEBUG IConsoleDebugLibRegister(); #endif + IConsoleCmdRegister("fps", ConFramerate); + IConsoleCmdRegister("fps_wnd", ConFramerateWindow); /* NewGRF development stuff */ IConsoleCmdRegister("reload_newgrfs", ConNewGRFReload, ConHookNewGRFDeveloperTool); diff --git a/src/core/alloc_func.hpp b/src/core/alloc_func.hpp index c7e17421f7..c33e733016 100644 --- a/src/core/alloc_func.hpp +++ b/src/core/alloc_func.hpp @@ -125,7 +125,7 @@ static inline T *ReallocT(T *t_ptr, size_t num_elements) /* Ensure the size does not overflow. */ CheckAllocationConstraints(num_elements); - t_ptr = (T*)realloc(t_ptr, num_elements * sizeof(T)); + t_ptr = (T*)realloc(static_cast(t_ptr), num_elements * sizeof(T)); if (t_ptr == NULL) ReallocError(num_elements * sizeof(T)); return t_ptr; } diff --git a/src/core/backup_type.hpp b/src/core/backup_type.hpp index 60799170f7..7e3771b70f 100644 --- a/src/core/backup_type.hpp +++ b/src/core/backup_type.hpp @@ -53,7 +53,7 @@ struct Backup { { /* We cannot assert here, as missing restoration is 'normal' when exceptions are thrown. * Exceptions are especially used to abort world generation. */ - DEBUG(misc, 0, "%s:%d: Backupped value was not restored!", this->file, this->line); + DEBUG(misc, 0, "%s:%d: Backed-up value was not restored!", this->file, this->line); this->Restore(); } } diff --git a/src/core/bitmath_func.hpp b/src/core/bitmath_func.hpp index a40c7dba6e..18c3f91b53 100644 --- a/src/core/bitmath_func.hpp +++ b/src/core/bitmath_func.hpp @@ -302,6 +302,7 @@ static inline bool HasAtMostOneBit(T value) template static inline T ROL(const T x, const uint8 n) { + if (n == 0) return x; return (T)(x << n | x >> (sizeof(x) * 8 - n)); } @@ -317,6 +318,7 @@ static inline T ROL(const T x, const uint8 n) template static inline T ROR(const T x, const uint8 n) { + if (n == 0) return x; return (T)(x >> n | x << (sizeof(x) * 8 - n)); } diff --git a/src/core/endian_type.hpp b/src/core/endian_type.hpp index dbb7faec66..4058c5c19a 100644 --- a/src/core/endian_type.hpp +++ b/src/core/endian_type.hpp @@ -26,15 +26,22 @@ #define TTD_BIG_ENDIAN 1 /* Windows has always LITTLE_ENDIAN */ -#if defined(WIN32) || defined(__OS2__) || defined(WIN64) - #define TTD_ENDIAN TTD_LITTLE_ENDIAN +#if defined(_WIN32) || defined(__OS2__) +# define TTD_ENDIAN TTD_LITTLE_ENDIAN +#elif defined(OSX) +# include +# if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN +# define TTD_ENDIAN TTD_LITTLE_ENDIAN +# else +# define TTD_ENDIAN TTD_BIG_ENDIAN +# endif #elif !defined(TESTING) - /* Else include endian[target/host].h, which has the endian-type, autodetected by the Makefile */ - #if defined(STRGEN) || defined(SETTINGSGEN) - #include "endian_host.h" - #else - #include "endian_target.h" - #endif -#endif /* WIN32 || __OS2__ || WIN64 */ +# include +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define TTD_ENDIAN TTD_LITTLE_ENDIAN +# else +# define TTD_ENDIAN TTD_BIG_ENDIAN +# endif +#endif /* _WIN32 || __OS2__ */ #endif /* ENDIAN_TYPE_HPP */ diff --git a/src/core/smallmatrix_type.hpp b/src/core/smallmatrix_type.hpp index 9ebf0372c2..cd4dee4e3a 100644 --- a/src/core/smallmatrix_type.hpp +++ b/src/core/smallmatrix_type.hpp @@ -159,7 +159,7 @@ public: /** * Erase a row, replacing it with the last one. - * @param x Position of the row. + * @param y Position of the row. */ void EraseRow(uint y) { @@ -174,7 +174,7 @@ public: /** * Remove columns from the matrix while preserving the order of other columns. - * @param x First column to remove. + * @param y First column to remove. * @param count Number of consecutive columns to remove. */ void EraseRowPreservingOrder(uint y, uint count = 1) @@ -210,8 +210,8 @@ public: /** * Set the size to a specific width and height, preserving item positions * as far as possible in the process. - * @param width Target width. - * @param height Target height. + * @param new_width Target width. + * @param new_height Target height. */ inline void Resize(uint new_width, uint new_height) { @@ -297,7 +297,7 @@ public: /** * Get column "number" (const) * - * @param X Position of the column. + * @param x Position of the column. * @return Column at "number". */ inline const T *operator[](uint x) const @@ -309,7 +309,7 @@ public: /** * Get column "number" (const) * - * @param X Position of the column. + * @param x Position of the column. * @return Column at "number". */ inline T *operator[](uint x) diff --git a/src/cpu.cpp b/src/cpu.cpp index c48b8cbd4d..9393ea0613 100644 --- a/src/cpu.cpp +++ b/src/cpu.cpp @@ -18,7 +18,7 @@ /* rdtsc for MSC_VER, uses simple inline assembly, or _rdtsc * from external win64.asm because VS2005 does not support inline assembly */ -#if defined(_MSC_VER) && !defined(RDTSC_AVAILABLE) && !defined(WINCE) +#if defined(_MSC_VER) && !defined(RDTSC_AVAILABLE) #include uint64 ottd_rdtsc() { @@ -71,10 +71,7 @@ uint64 ottd_rdtsc() /* In all other cases we have no support for rdtsc. No major issue, * you just won't be able to profile your code with TIC()/TOC() */ #if !defined(RDTSC_AVAILABLE) -/* MSVC (in case of WinCE) can't handle #warning */ -# if !defined(_MSC_VER) #warning "(non-fatal) No support for rdtsc(), you won't be able to profile with TIC/TOC" -# endif uint64 ottd_rdtsc() {return 0;} #endif diff --git a/src/currency.cpp b/src/currency.cpp index 8cc385fc04..615c5113bb 100644 --- a/src/currency.cpp +++ b/src/currency.cpp @@ -62,6 +62,7 @@ static const CurrencySpec origin_currency_specs[CURRENCY_END] = { { 1, "", CF_NOEURO, "", "", 2, STR_GAME_OPTIONS_CURRENCY_CUSTOM }, ///< custom currency (add further languages below) { 3, "", CF_NOEURO, "", NBSP "GEL", 1, STR_GAME_OPTIONS_CURRENCY_GEL }, ///< Georgian Lari { 4901, "", CF_NOEURO, "", NBSP "Rls", 1, STR_GAME_OPTIONS_CURRENCY_IRR }, ///< Iranian Rial + { 80, "", CF_NOEURO, "", NBSP "rub", 1, STR_GAME_OPTIONS_CURRENCY_RUB }, ///< New Russian Ruble }; /** Array of currencies used by the system */ diff --git a/src/currency.h b/src/currency.h index ab8026002d..2529aca11f 100644 --- a/src/currency.h +++ b/src/currency.h @@ -58,6 +58,7 @@ enum Currencies { CURRENCY_CUSTOM, ///< Custom currency CURRENCY_GEL, ///< Georgian Lari CURRENCY_IRR, ///< Iranian Rial + CURRENCY_RUB, ///< New Russian Ruble CURRENCY_END, ///< always the last item }; diff --git a/src/debug.cpp b/src/debug.cpp index 1846152254..13df98db34 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -17,6 +17,10 @@ #include "fileio_func.h" #include "settings_type.h" +#if defined(_WIN32) +#include "os/windows/win32.h" +#endif + #include #if defined(ENABLE_NETWORK) @@ -135,10 +139,10 @@ static void debug_print(const char *dbg, const char *buf) } else { char buffer[512]; seprintf(buffer, lastof(buffer), "%sdbg: [%s] %s\n", GetLogPrefix(), dbg, buf); -#if defined(WINCE) - NKDbgPrintfW(OTTD2FS(buffer)); -#elif defined(WIN32) || defined(WIN64) - _fputts(OTTD2FS(buffer, true), stderr); +#if defined(_WIN32) + TCHAR system_buf[512]; + convert_to_fs(buffer, system_buf, lengthof(system_buf), true); + _fputts(system_buf, stderr); #else fputs(buffer, stderr); #endif diff --git a/src/depend/depend.cpp b/src/depend/depend.cpp index d4b102ddcf..f57acba25c 100644 --- a/src/depend/depend.cpp +++ b/src/depend/depend.cpp @@ -217,22 +217,22 @@ enum Token { TOKEN_LOCAL, ///< Read a local include TOKEN_GLOBAL, ///< Read a global include TOKEN_IDENTIFIER, ///< Identifier within the data. - TOKEN_DEFINE, ///< (#)define in code - TOKEN_IF, ///< (#)if in code - TOKEN_IFDEF, ///< (#)ifdef in code - TOKEN_IFNDEF, ///< (#)ifndef in code - TOKEN_ELIF, ///< (#)elif in code - TOKEN_ELSE, ///< (#)else in code - TOKEN_ENDIF, ///< (#)endif in code - TOKEN_UNDEF, ///< (#)undef in code - TOKEN_OR, ///< '||' within #if expression - TOKEN_AND, ///< '&&' within #if expression - TOKEN_DEFINED, ///< 'defined' within #if expression - TOKEN_OPEN, ///< '(' within #if expression - TOKEN_CLOSE, ///< ')' within #if expression - TOKEN_NOT, ///< '!' within #if expression - TOKEN_ZERO, ///< '0' within #if expression - TOKEN_INCLUDE, ///< (#)include in code + TOKEN_DEFINE, ///< \c \#define in code + TOKEN_IF, ///< \c \#if in code + TOKEN_IFDEF, ///< \c \#ifdef in code + TOKEN_IFNDEF, ///< \c \#ifndef in code + TOKEN_ELIF, ///< \c \#elif in code + TOKEN_ELSE, ///< \c \#else in code + TOKEN_ENDIF, ///< \c \#endif in code + TOKEN_UNDEF, ///< \c \#undef in code + TOKEN_OR, ///< '||' within \c \#if expression + TOKEN_AND, ///< '&&' within \c \#if expression + TOKEN_DEFINED, ///< 'defined' within \c \#if expression + TOKEN_OPEN, ///< '(' within \c \#if expression + TOKEN_CLOSE, ///< ')' within \c \#if expression + TOKEN_NOT, ///< '!' within \c \#if expression + TOKEN_ZERO, ///< '0' within \c \#if expression + TOKEN_INCLUDE, ///< \c \#include in code }; /** Mapping from a C-style keyword representation to a Token. */ @@ -681,8 +681,8 @@ bool ExpressionOr(Lexer *lexer, StringSet *defines, bool verbose) /** Enumerator to tell how long to ignore 'stuff'. */ enum Ignore { NOT_IGNORE, ///< No ignoring. - IGNORE_UNTIL_ELSE, ///< Ignore till a #else is reached. - IGNORE_UNTIL_ENDIF, ///< Ignore till a #endif is reached. + IGNORE_UNTIL_ELSE, ///< Ignore till a \c \#else is reached. + IGNORE_UNTIL_ENDIF, ///< Ignore till a \c \#endif is reached. }; /** diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 14461d8817..39accd65f1 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -908,9 +908,16 @@ struct DepotWindow : Window { */ virtual bool OnVehicleSelect(const Vehicle *v) { - if (DoCommandP(this->window_number, v->index, _ctrl_pressed ? 1 : 0, CMD_CLONE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_TRAIN + v->type), CcCloneVehicle)) { - ResetObjectToPlace(); + if (_ctrl_pressed) { + /* Share-clone, do not open new viewport, and keep tool active */ + DoCommandP(this->window_number, v->index, 1, CMD_CLONE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_TRAIN + v->type), NULL); + } else { + /* Copy-clone, open viewport for new vehicle, and deselect the tool (assume player wants to changs things on new vehicle) */ + if (DoCommandP(this->window_number, v->index, 0, CMD_CLONE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_TRAIN + v->type), CcCloneVehicle)) { + ResetObjectToPlace(); + } } + return true; } diff --git a/src/disaster_vehicle.cpp b/src/disaster_vehicle.cpp index 98978ddfb0..64ebcd3fa1 100644 --- a/src/disaster_vehicle.cpp +++ b/src/disaster_vehicle.cpp @@ -164,7 +164,7 @@ DisasterVehicle::DisasterVehicle(int x, int y, Direction direction, DisasterSubT this->direction = direction; this->tile = TileVirtXY(x, y); this->subtype = subtype; - this->UpdateDeltaXY(INVALID_DIR); + this->UpdateDeltaXY(); this->owner = OWNER_NONE; this->image_override = 0; this->current_order.Free(); @@ -973,7 +973,7 @@ void ReleaseDisastersTargetingVehicle(VehicleID vehicle) } } -void DisasterVehicle::UpdateDeltaXY(Direction direction) +void DisasterVehicle::UpdateDeltaXY() { this->x_offs = -1; this->y_offs = -1; diff --git a/src/disaster_vehicle.h b/src/disaster_vehicle.h index 06fb36c1e3..e86d96e97d 100644 --- a/src/disaster_vehicle.h +++ b/src/disaster_vehicle.h @@ -48,7 +48,7 @@ struct DisasterVehicle FINAL : public SpecializedVehicle 0) { - _score_part[owner][SCORE_MIN_PROFIT] = ClampToI32(min_profit); + _score_part[owner][SCORE_MIN_PROFIT] = min_profit; } } @@ -213,10 +213,10 @@ int UpdateCompanyRatingAndValue(Company *c, bool update) } while (++cee, --numec); if (min_income > 0) { - _score_part[owner][SCORE_MIN_INCOME] = ClampToI32(min_income); + _score_part[owner][SCORE_MIN_INCOME] = min_income; } - _score_part[owner][SCORE_MAX_INCOME] = ClampToI32(max_income); + _score_part[owner][SCORE_MAX_INCOME] = max_income; } } @@ -230,7 +230,7 @@ int UpdateCompanyRatingAndValue(Company *c, bool update) total_delivered += cee->delivered_cargo.GetSum(); } while (++cee, --numec); - _score_part[owner][SCORE_DELIVERED] = ClampToI32(total_delivered); + _score_part[owner][SCORE_DELIVERED] = total_delivered; } } @@ -242,13 +242,13 @@ int UpdateCompanyRatingAndValue(Company *c, bool update) /* Generate score for company's money */ { if (c->money > 0) { - _score_part[owner][SCORE_MONEY] = ClampToI32(c->money); + _score_part[owner][SCORE_MONEY] = c->money; } } /* Generate score for loan */ { - _score_part[owner][SCORE_LOAN] = ClampToI32(_score_info[SCORE_LOAN].needed - c->current_loan); + _score_part[owner][SCORE_LOAN] = _score_info[SCORE_LOAN].needed - c->current_loan; } /* Now we calculate the score for each item.. */ @@ -696,9 +696,10 @@ static void CompaniesGenStatistics() if (!HasBit(1 << 0 | 1 << 3 | 1 << 6 | 1 << 9, _cur_month)) return; FOR_ALL_COMPANIES(c) { - memmove(&c->old_economy[1], &c->old_economy[0], sizeof(c->old_economy) - sizeof(c->old_economy[0])); + /* Drop the oldest history off the end */ + std::copy_backward(c->old_economy, c->old_economy + MAX_HISTORY_QUARTERS - 1, c->old_economy + MAX_HISTORY_QUARTERS); c->old_economy[0] = c->cur_economy; - memset(&c->cur_economy, 0, sizeof(c->cur_economy)); + c->cur_economy = {}; if (c->num_valid_stat_ent != MAX_HISTORY_QUARTERS) c->num_valid_stat_ent++; @@ -1061,6 +1062,7 @@ static uint DeliverGoodsToIndustry(const Station *st, CargoID cargo_type, uint n uint amount = min(num_pieces, 0xFFFFU - ind->incoming_cargo_waiting[cargo_index]); ind->incoming_cargo_waiting[cargo_index] += amount; + ind->last_cargo_accepted_at[cargo_index] = _date; num_pieces -= amount; accepted += amount; } @@ -1137,7 +1139,6 @@ static void TriggerIndustryProduction(Industry *i) uint16 callback = indspec->callback_mask; i->was_cargo_delivered = true; - i->last_cargo_accepted_at = _date; if (HasBit(callback, CBM_IND_PRODUCTION_CARGO_ARRIVAL) || HasBit(callback, CBM_IND_PRODUCTION_256_TICKS)) { if (HasBit(callback, CBM_IND_PRODUCTION_CARGO_ARRIVAL)) { @@ -1146,14 +1147,15 @@ static void TriggerIndustryProduction(Industry *i) SetWindowDirty(WC_INDUSTRY_VIEW, i->index); } } else { - for (uint cargo_index = 0; cargo_index < lengthof(i->incoming_cargo_waiting); cargo_index++) { - uint cargo_waiting = i->incoming_cargo_waiting[cargo_index]; + for (uint ci_in = 0; ci_in < lengthof(i->incoming_cargo_waiting); ci_in++) { + uint cargo_waiting = i->incoming_cargo_waiting[ci_in]; if (cargo_waiting == 0) continue; - i->produced_cargo_waiting[0] = min(i->produced_cargo_waiting[0] + (cargo_waiting * indspec->input_cargo_multiplier[cargo_index][0] / 256), 0xFFFF); - i->produced_cargo_waiting[1] = min(i->produced_cargo_waiting[1] + (cargo_waiting * indspec->input_cargo_multiplier[cargo_index][1] / 256), 0xFFFF); + for (uint ci_out = 0; ci_out < lengthof(i->produced_cargo_waiting); ci_out++) { + i->produced_cargo_waiting[ci_out] = min(i->produced_cargo_waiting[ci_out] + (cargo_waiting * indspec->input_cargo_multiplier[ci_in][ci_out] / 256), 0xFFFF); + } - i->incoming_cargo_waiting[cargo_index] = 0; + i->incoming_cargo_waiting[ci_in] = 0; } } @@ -1241,7 +1243,6 @@ Money CargoPayment::PayTransfer(const CargoPacket *cp, uint count) /** * Prepare the vehicle to be unloaded. - * @param curr_station the station where the consist is at the moment * @param front_v the vehicle to be unloaded */ void PrepareUnload(Vehicle *front_v) @@ -1366,14 +1367,14 @@ struct IsEmptyAction struct PrepareRefitAction { CargoArray &consist_capleft; ///< Capacities left in the consist. - uint32 &refit_mask; ///< Bitmask of possible refit cargoes. + CargoTypes &refit_mask; ///< Bitmask of possible refit cargoes. /** * Create a refit preparation action. * @param consist_capleft Capacities left in consist, to be updated here. * @param refit_mask Refit mask to be constructed from refit information of vehicles. */ - PrepareRefitAction(CargoArray &consist_capleft, uint32 &refit_mask) : + PrepareRefitAction(CargoArray &consist_capleft, CargoTypes &refit_mask) : consist_capleft(consist_capleft), refit_mask(refit_mask) {} /** @@ -1469,7 +1470,7 @@ static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station Backup cur_company(_current_company, v->owner, FILE_LINE); - uint32 refit_mask = v->GetEngine()->info.refit_mask; + CargoTypes refit_mask = v->GetEngine()->info.refit_mask; /* Remove old capacity from consist capacity and collect refit mask. */ IterateVehicleParts(v_start, PrepareRefitAction(consist_capleft, refit_mask)); @@ -1627,10 +1628,10 @@ static void LoadUnloadVehicle(Vehicle *front) bool completely_emptied = true; bool anything_unloaded = false; bool anything_loaded = false; - uint32 full_load_amount = 0; - uint32 cargo_not_full = 0; - uint32 cargo_full = 0; - uint32 reservation_left = 0; + CargoTypes full_load_amount = 0; + CargoTypes cargo_not_full = 0; + CargoTypes cargo_full = 0; + CargoTypes reservation_left = 0; front->cur_speed = 0; @@ -1838,7 +1839,7 @@ static void LoadUnloadVehicle(Vehicle *front) /* if the aircraft carries passengers and is NOT full, then * continue loading, no matter how much mail is in */ if ((front->type == VEH_AIRCRAFT && IsCargoInClass(front->cargo_type, CC_PASSENGERS) && front->cargo_cap > front->cargo.StoredCount()) || - (cargo_not_full && (cargo_full & ~cargo_not_full) == 0)) { // There are still non-full cargoes + (cargo_not_full != 0 && (cargo_full & ~cargo_not_full) == 0)) { // There are still non-full cargoes finished_loading = false; } } else if (cargo_not_full != 0) { diff --git a/src/economy_func.h b/src/economy_func.h index 111ce85a27..7b369b7d60 100644 --- a/src/economy_func.h +++ b/src/economy_func.h @@ -22,7 +22,7 @@ void ResetPriceBaseMultipliers(); void SetPriceBaseMultiplier(Price price, int factor); extern const ScoreInfo _score_info[]; -extern int _score_part[MAX_COMPANIES][SCORE_END]; +extern int64 _score_part[MAX_COMPANIES][SCORE_END]; extern Economy _economy; /* Prices and also the fractional part. */ extern Prices _price; diff --git a/src/economy_type.h b/src/economy_type.h index 7e7a572413..31f74aacc7 100644 --- a/src/economy_type.h +++ b/src/economy_type.h @@ -152,12 +152,12 @@ enum ExpensesType { EXPENSES_NEW_VEHICLES, ///< New vehicles. EXPENSES_TRAIN_RUN, ///< Running costs trains. EXPENSES_ROADVEH_RUN, ///< Running costs road vehicles. - EXPENSES_AIRCRAFT_RUN, ///< Running costs aircrafts. + EXPENSES_AIRCRAFT_RUN, ///< Running costs aircraft. EXPENSES_SHIP_RUN, ///< Running costs ships. EXPENSES_PROPERTY, ///< Property costs. EXPENSES_TRAIN_INC, ///< Income from trains. EXPENSES_ROADVEH_INC, ///< Income from road vehicles. - EXPENSES_AIRCRAFT_INC, ///< Income from aircrafts. + EXPENSES_AIRCRAFT_INC, ///< Income from aircraft. EXPENSES_SHIP_INC, ///< Income from ships. EXPENSES_LOAN_INT, ///< Interest payments over the loan. EXPENSES_OTHER, ///< Other expenses. diff --git a/src/effectvehicle.cpp b/src/effectvehicle.cpp index 5921cd190e..4d8f58acb8 100644 --- a/src/effectvehicle.cpp +++ b/src/effectvehicle.cpp @@ -603,7 +603,7 @@ EffectVehicle *CreateEffectVehicle(int x, int y, int z, EffectVehicleType type) v->y_pos = y; v->z_pos = z; v->tile = 0; - v->UpdateDeltaXY(INVALID_DIR); + v->UpdateDeltaXY(); v->vehstatus = VS_UNCLICKABLE; _effect_init_procs[type](v); @@ -647,7 +647,7 @@ bool EffectVehicle::Tick() return _effect_tick_procs[this->subtype](this); } -void EffectVehicle::UpdateDeltaXY(Direction direction) +void EffectVehicle::UpdateDeltaXY() { this->x_offs = 0; this->y_offs = 0; diff --git a/src/effectvehicle_base.h b/src/effectvehicle_base.h index 27da420017..d809657fab 100644 --- a/src/effectvehicle_base.h +++ b/src/effectvehicle_base.h @@ -32,7 +32,7 @@ struct EffectVehicle FINAL : public SpecializedVehicle. - */ - -/** - * @file endian_check.cpp - * This pretty simple file checks if the system is LITTLE_ENDIAN or BIG_ENDIAN - * it does that by putting a 1 and a 0 in an array, and read it out as one - * number. If it is 1, it is LITTLE_ENDIAN, if it is 256, it is BIG_ENDIAN - * - * After that it outputs the contents of an include files (endian.h) - * that says or TTD_LITTLE_ENDIAN, or TTD_BIG_ENDIAN. Makefile takes - * care of the real writing to the file. - */ - -#include -#include - -/** Supported endian types */ -enum Endian { - ENDIAN_LITTLE, ///< little endian - ENDIAN_BIG, ///< big endian -}; - -/** - * Shortcut to printf("#define TTD_ENDIAN TTD_*_ENDIAN") - * @param endian endian type to define - */ -static inline void printf_endian(Endian endian) -{ - printf("#define TTD_ENDIAN %s\n", endian == ENDIAN_LITTLE ? "TTD_LITTLE_ENDIAN" : "TTD_BIG_ENDIAN"); -} - -/** - * Main call of the endian_check program - * @param argc argument count - * @param argv arguments themselves - * @return exit code - */ -int main (int argc, char *argv[]) -{ - unsigned char endian_test[2] = { 1, 0 }; - int force_BE = 0, force_LE = 0, force_PREPROCESSOR = 0; - - if (argc > 1 && strcmp(argv[1], "BE") == 0) force_BE = 1; - if (argc > 1 && strcmp(argv[1], "LE") == 0) force_LE = 1; - if (argc > 1 && strcmp(argv[1], "PREPROCESSOR") == 0) force_PREPROCESSOR = 1; - - printf("#ifndef ENDIAN_H\n#define ENDIAN_H\n"); - - if (force_LE == 1) { - printf_endian(ENDIAN_LITTLE); - } else if (force_BE == 1) { - printf_endian(ENDIAN_BIG); - } else if (force_PREPROCESSOR == 1) { - /* Support for universal binaries on OSX - * Universal binaries supports both PPC and x86 - * If a compiler for OSX gets this setting, it will always pick the correct endian and no test is needed - */ - printf("#ifdef __BIG_ENDIAN__\n"); - printf_endian(ENDIAN_BIG); - printf("#else\n"); - printf_endian(ENDIAN_LITTLE); - printf("#endif\n"); - } else if (*(short*)endian_test == 1 ) { - printf_endian(ENDIAN_LITTLE); - } else { - printf_endian(ENDIAN_BIG); - } - printf("#endif\n"); - - return 0; -} diff --git a/src/engine.cpp b/src/engine.cpp index b0af3bc4df..9f500e1cdf 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -431,9 +431,9 @@ uint Engine::GetDisplayMaxTractiveEffort() const /* Only trains and road vehicles have 'tractive effort'. */ switch (this->type) { case VEH_TRAIN: - return (10 * this->GetDisplayWeight() * GetEngineProperty(this->index, PROP_TRAIN_TRACTIVE_EFFORT, this->u.rail.tractive_effort)) / 256; + return (GROUND_ACCELERATION * this->GetDisplayWeight() * GetEngineProperty(this->index, PROP_TRAIN_TRACTIVE_EFFORT, this->u.rail.tractive_effort)) / 256 / 1000; case VEH_ROAD: - return (10 * this->GetDisplayWeight() * GetEngineProperty(this->index, PROP_ROADVEH_TRACTIVE_EFFORT, this->u.road.tractive_effort)) / 256; + return (GROUND_ACCELERATION * this->GetDisplayWeight() * GetEngineProperty(this->index, PROP_ROADVEH_TRACTIVE_EFFORT, this->u.road.tractive_effort)) / 256 / 1000; default: NOT_REACHED(); } @@ -573,7 +573,7 @@ static bool IsWagon(EngineID index) } /** - * Update #reliability of engine \a e, (if needed) update the engine GUIs. + * Update #Engine::reliability and (if needed) update the engine GUIs. * @param e %Engine to update. */ static void CalcEngineReliability(Engine *e) @@ -752,7 +752,7 @@ static CompanyID GetPreviewCompany(Engine *e) CompanyID best_company = INVALID_COMPANY; /* For trains the cargomask has no useful meaning, since you can attach other wagons */ - uint32 cargomask = e->type != VEH_TRAIN ? GetUnionOfArticulatedRefitMasks(e->index, true) : (uint32)-1; + CargoTypes cargomask = e->type != VEH_TRAIN ? GetUnionOfArticulatedRefitMasks(e->index, true) : ALL_CARGOTYPES; int32 best_hist = -1; const Company *c; @@ -1117,7 +1117,9 @@ bool IsEngineRefittable(EngineID engine) /* Is there any cargo except the default cargo? */ CargoID default_cargo = e->GetDefaultCargoType(); - return default_cargo != CT_INVALID && ei->refit_mask != 1U << default_cargo; + CargoTypes default_cargo_mask = 0; + SetBit(default_cargo_mask, default_cargo); + return default_cargo != CT_INVALID && ei->refit_mask != default_cargo_mask; } /** diff --git a/src/engine_func.h b/src/engine_func.h index 6c3fb14ff2..37fb005092 100644 --- a/src/engine_func.h +++ b/src/engine_func.h @@ -26,7 +26,7 @@ extern const uint8 _engine_offsets[4]; bool IsEngineBuildable(EngineID engine, VehicleType type, CompanyID company); bool IsEngineRefittable(EngineID engine); -void GetArticulatedVehicleCargoesAndRefits(EngineID engine, CargoArray *cargoes, uint32 *refits); +void GetArticulatedVehicleCargoesAndRefits(EngineID engine, CargoArray *cargoes, CargoTypes *refits); void SetYearEngineAgingStops(); void StartupOneEngine(Engine *e, Date aging_date); diff --git a/src/engine_type.h b/src/engine_type.h index 8356fda8f8..82f10d9d87 100644 --- a/src/engine_type.h +++ b/src/engine_type.h @@ -137,7 +137,7 @@ struct EngineInfo { byte load_amount; byte climates; ///< Climates supported by the engine. CargoID cargo_type; - uint32 refit_mask; + CargoTypes refit_mask; byte refit_cost; byte misc_flags; ///< Miscellaneous flags. @see EngineMiscFlags byte callback_mask; ///< Bitmask of vehicle callbacks that have to be called diff --git a/src/error_gui.cpp b/src/error_gui.cpp index c8c603afb3..1c59b7e8d0 100644 --- a/src/error_gui.cpp +++ b/src/error_gui.cpp @@ -425,7 +425,7 @@ void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel /** * Schedule a list of errors. * Note: This does not try to display the error now. This is useful if the window system is not yet running. - * @param data Error message datas; cleared afterwards + * @param datas Error message datas; cleared afterwards */ void ScheduleErrorMessage(ErrorList &datas) { diff --git a/src/fileio.cpp b/src/fileio.cpp index 0590efd3a7..0e6d86e3c7 100644 --- a/src/fileio.cpp +++ b/src/fileio.cpp @@ -15,7 +15,7 @@ #include "fios.h" #include "string_func.h" #include "tar_type.h" -#ifdef WIN32 +#ifdef _WIN32 #include # define access _taccess #elif defined(__HAIKU__) @@ -325,15 +325,7 @@ bool FioCheckFileExists(const char *filename, Subdirectory subdir) */ bool FileExists(const char *filename) { -#if defined(WINCE) - /* There is always one platform that doesn't support basic commands... */ - HANDLE hand = CreateFile(OTTD2FS(filename), 0, 0, NULL, OPEN_EXISTING, 0, NULL); - if (hand == INVALID_HANDLE_VALUE) return 1; - CloseHandle(hand); - return 0; -#else return access(OTTD2FS(filename), 0) == 0; -#endif } /** @@ -355,7 +347,7 @@ char *FioGetFullPath(char *buf, const char *last, Searchpath sp, Subdirectory su /** * Find a path to the filename in one of the search directories. - * @param buf [out] Destination buffer for the path. + * @param[out] buf Destination buffer for the path. * @param last End of the destination buffer. * @param subdir Subdirectory to try. * @param filename Filename to look for. @@ -369,7 +361,7 @@ char *FioFindFullPath(char *buf, const char *last, Subdirectory subdir, const ch FOR_ALL_SEARCHPATHS(sp) { FioGetFullPath(buf, last, sp, subdir, filename); if (FileExists(buf)) return buf; -#if !defined(WIN32) +#if !defined(_WIN32) /* Be, as opening files, aware that sometimes the filename * might be in uppercase when it is in lowercase on the * disk. Of course Windows doesn't care about casing. */ @@ -407,7 +399,7 @@ char *FioGetDirectory(char *buf, const char *last, Subdirectory subdir) static FILE *FioFOpenFileSp(const char *filename, const char *mode, Searchpath sp, Subdirectory subdir, size_t *filesize) { -#if defined(WIN32) && defined(UNICODE) +#if defined(_WIN32) && defined(UNICODE) /* fopen is implemented as a define with ellipses for * Unicode support (prepend an L). As we are not sending * a string, but a variable, it 'renames' the variable, @@ -424,12 +416,12 @@ static FILE *FioFOpenFileSp(const char *filename, const char *mode, Searchpath s seprintf(buf, lastof(buf), "%s%s%s", _searchpaths[sp], _subdirs[subdir], filename); } -#if defined(WIN32) +#if defined(_WIN32) if (mode[0] == 'r' && GetFileAttributes(OTTD2FS(buf)) == INVALID_FILE_ATTRIBUTES) return NULL; #endif f = fopen(buf, mode); -#if !defined(WIN32) +#if !defined(_WIN32) if (f == NULL && strtolower(buf + ((subdir == NO_DIRECTORY) ? 0 : strlen(_searchpaths[sp]) - 1))) { f = fopen(buf, mode); } @@ -446,7 +438,7 @@ static FILE *FioFOpenFileSp(const char *filename, const char *mode, Searchpath s /** * Opens a file from inside a tar archive. * @param entry The entry to open. - * @param filesize [out] If not \c NULL, size of the opened file. + * @param[out] filesize If not \c NULL, size of the opened file. * @return File handle of the opened file, or \c NULL if the file is not available. * @note The file is read from within the tar file, and may not return \c EOF after reading the whole file. */ @@ -468,7 +460,6 @@ FILE *FioFOpenFileTar(TarFileListEntry *entry, size_t *filesize) * Opens a OpenTTD file somewhere in a personal or global directory. * @param filename Name of the file to open. * @param subdir Subdirectory to open. - * @param filename Name of the file to open. * @return File handle of the opened file, or \c NULL if the file is not available. */ FILE *FioFOpenFile(const char *filename, const char *mode, Subdirectory subdir, size_t *filesize) @@ -540,11 +531,11 @@ FILE *FioFOpenFile(const char *filename, const char *mode, Subdirectory subdir, * Create a directory with the given name * @param name the new name of the directory */ -static void FioCreateDirectory(const char *name) +void FioCreateDirectory(const char *name) { /* Ignore directory creation errors; they'll surface later on, and most * of the time they are 'directory already exists' errors anyhow. */ -#if defined(WIN32) || defined(WINCE) +#if defined(_WIN32) CreateDirectory(OTTD2FS(name), NULL); #elif defined(OS2) && !defined(__INNOTEK_LIBC__) mkdir(OTTD2FS(name)); @@ -640,7 +631,7 @@ static void SimplifyFileName(char *name) /** * Perform the scanning of a particular subdirectory. - * @param subdir The subdirectory to scan. + * @param sd The subdirectory to scan. * @return The number of found tar files. */ uint TarScanner::DoScan(Subdirectory sd) @@ -988,14 +979,14 @@ bool ExtractTar(const char *tar_filename, Subdirectory subdir) return true; } -#if defined(WIN32) || defined(WINCE) +#if defined(_WIN32) /** * Determine the base (personal dir and game data dir) paths * @param exe the path from the current path to the executable * @note defined in the OS related files (os2.cpp, win32.cpp, unix.cpp etc) */ extern void DetermineBasePaths(const char *exe); -#else /* defined(WIN32) || defined(WINCE) */ +#else /* defined(_WIN32) */ /** * Changes the working directory to the path of the give executable. @@ -1158,7 +1149,7 @@ extern void cocoaSetApplicationBundleDir(); _searchpaths[SP_APPLICATION_BUNDLE_DIR] = NULL; #endif } -#endif /* defined(WIN32) || defined(WINCE) */ +#endif /* defined(_WIN32) */ const char *_personal_dir; @@ -1311,7 +1302,7 @@ void SanitizeFilename(char *filename) /** * Load a file into memory. * @param filename Name of the file to load. - * @param lenp [out] Length of loaded data. + * @param[out] lenp Length of loaded data. * @param maxsize Maximum size to load. * @return Pointer to new memory containing the loaded data, or \c NULL if loading failed. * @note If \a maxsize less than the length of the file, loading fails. diff --git a/src/fileio_func.h b/src/fileio_func.h index 443460b2d3..f5ef58ac06 100644 --- a/src/fileio_func.h +++ b/src/fileio_func.h @@ -55,6 +55,7 @@ char *FioGetFullPath(char *buf, const char *last, Searchpath sp, Subdirectory su char *FioFindFullPath(char *buf, const char *last, Subdirectory subdir, const char *filename); char *FioAppendDirectory(char *buf, const char *last, Searchpath sp, Subdirectory subdir); char *FioGetDirectory(char *buf, const char *last, Subdirectory subdir); +void FioCreateDirectory(const char *name); const char *FiosGetScreenshotDir(); @@ -117,7 +118,7 @@ public: DECLARE_ENUM_AS_BIT_SET(TarScanner::Mode) /* Implementation of opendir/readdir/closedir for Windows */ -#if defined(WIN32) +#if defined(_WIN32) struct DIR; struct dirent { // XXX - only d_name implemented @@ -135,7 +136,7 @@ int closedir(DIR *d); /* Use system-supplied opendir/readdir/closedir functions */ # include # include -#endif /* defined(WIN32) */ +#endif /* defined(_WIN32) */ /** * A wrapper around opendir() which will convert the string from @@ -149,4 +150,17 @@ static inline DIR *ttd_opendir(const char *path) return opendir(OTTD2FS(path)); } + +/** Auto-close a file upon scope exit. */ +class FileCloser { + FILE *f; + +public: + FileCloser(FILE *_f) : f(_f) {} + ~FileCloser() + { + fclose(f); + } +}; + #endif /* FILEIO_FUNC_H */ diff --git a/src/fios.cpp b/src/fios.cpp index 5e78fb1b4d..73365ddc29 100644 --- a/src/fios.cpp +++ b/src/fios.cpp @@ -20,9 +20,9 @@ #include "string_func.h" #include -#ifndef WIN32 +#ifndef _WIN32 # include -#endif /* WIN32 */ +#endif /* _WIN32 */ #include "table/strings.h" @@ -153,9 +153,7 @@ const char *FiosBrowseTo(const FiosItem *item) { switch (item->type) { case FIOS_TYPE_DRIVE: -#if defined(WINCE) - seprintf(_fios_path, _fios_path_last, PATHSEP ""); -#elif defined(WIN32) || defined(__OS2__) +#if defined(_WIN32) || defined(__OS2__) seprintf(_fios_path, _fios_path_last, "%c:" PATHSEP, item->title[0]); #endif break; @@ -320,7 +318,7 @@ bool FiosFileScanner::AddFile(const char *filename, size_t basepath_length, cons } FiosItem *fios = file_list.Append(); -#ifdef WIN32 +#ifdef _WIN32 struct _stat sb; if (_tstat(OTTD2FS(filename), &sb) == 0) { #else diff --git a/src/fios.h b/src/fios.h index 5e17e8ee17..24c9f370eb 100644 --- a/src/fios.h +++ b/src/fios.h @@ -18,6 +18,13 @@ #include "network/core/tcp_content.h" +/** Special values for save-load window for the data parameter of #InvalidateWindowData. */ +enum SaveLoadInvalidateWindowData { + SLIWD_RESCAN_FILES, ///< Rescan all files (when changed directory, ...) + SLIWD_SELECTION_CHANGES, ///< File selection has changed (user click, ...) + SLIWD_FILTER_CHANGES, ///< The filename filter has changed (via the editbox) +}; + typedef SmallMap CompanyPropertiesMap; /** diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp index f20cfd7927..e149d07b47 100644 --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -28,6 +28,7 @@ #include "date_func.h" #include "core/geometry_func.hpp" #include "gamelog.h" +#include "stringfilter_type.h" #include "widgets/fios_widget.h" @@ -76,9 +77,20 @@ static const NWidgetPart _nested_load_dialog_widgets[] = { NWidget(WWT_CAPTION, COLOUR_GREY, WID_SL_CAPTION), NWidget(WWT_DEFSIZEBOX, COLOUR_GREY), EndContainer(), + /* Current directory and free space */ NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_BACKGROUND), SetFill(1, 0), SetResize(1, 0), EndContainer(), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), - NWidget(NWID_VERTICAL), + /* Left side : filter box and available files */ + NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 1), + /* Filter box with label */ + NWidget(NWID_HORIZONTAL), SetPadding(WD_FRAMERECT_TOP, 0, WD_FRAMERECT_BOTTOM, 0), + SetPIP(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_RIGHT, 0), + NWidget(WWT_TEXT, COLOUR_GREY), SetFill(0, 1), SetDataTip(STR_SAVELOAD_FILTER_TITLE , STR_NULL), + NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_FILTER), SetFill(1, 0), SetMinimalSize(50, 12), SetResize(1, 0), + SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), + EndContainer(), + /* Sort buttons */ NWidget(NWID_HORIZONTAL), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SORT_BYNAME), SetDataTip(STR_SORT_BY_CAPTION_NAME, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0), @@ -86,6 +98,7 @@ static const NWidgetPart _nested_load_dialog_widgets[] = { EndContainer(), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SL_HOME_BUTTON), SetMinimalSize(12, 12), SetDataTip(SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON), EndContainer(), + /* Files */ NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_FILE_BACKGROUND), NWidget(NWID_HORIZONTAL), NWidget(WWT_INSET, COLOUR_GREY, WID_SL_DRIVES_DIRECTORIES_LIST), SetFill(1, 1), SetPadding(2, 1, 2, 2), @@ -98,6 +111,8 @@ static const NWidgetPart _nested_load_dialog_widgets[] = { EndContainer(), EndContainer(), EndContainer(), + + /* Right side : game details */ NWidget(WWT_PANEL, COLOUR_GREY), NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SL_DETAILS), SetResize(1, 1), SetFill(1, 1), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_MISSING_NEWGRFS), SetDataTip(STR_NEWGRF_SETTINGS_FIND_MISSING_CONTENT_BUTTON, STR_NEWGRF_SETTINGS_FIND_MISSING_CONTENT_TOOLTIP), SetFill(1, 0), SetResize(1, 0), @@ -119,8 +134,18 @@ static const NWidgetPart _nested_load_heightmap_dialog_widgets[] = { NWidget(WWT_CAPTION, COLOUR_GREY, WID_SL_CAPTION), NWidget(WWT_DEFSIZEBOX, COLOUR_GREY), EndContainer(), + /* Current directory and free space */ NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_BACKGROUND), SetFill(1, 0), SetResize(1, 0), EndContainer(), - NWidget(NWID_VERTICAL), + + NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 1), + /* Filter box with label */ + NWidget(NWID_HORIZONTAL), SetPadding(WD_FRAMERECT_TOP, 0, WD_FRAMERECT_BOTTOM, 0), + SetPIP(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_RIGHT, 0), + NWidget(WWT_TEXT, COLOUR_GREY), SetFill(0, 1), SetDataTip(STR_SAVELOAD_FILTER_TITLE , STR_NULL), + NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_FILTER), SetFill(1, 0), SetMinimalSize(50, 12), SetResize(1, 0), + SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), + EndContainer(), + /* Sort Buttons */ NWidget(NWID_HORIZONTAL), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SORT_BYNAME), SetDataTip(STR_SORT_BY_CAPTION_NAME, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0), @@ -128,6 +153,7 @@ static const NWidgetPart _nested_load_heightmap_dialog_widgets[] = { EndContainer(), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SL_HOME_BUTTON), SetMinimalSize(12, 12), SetDataTip(SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON), EndContainer(), + /* Files */ NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_FILE_BACKGROUND), NWidget(NWID_HORIZONTAL), NWidget(WWT_INSET, COLOUR_GREY, WID_SL_DRIVES_DIRECTORIES_LIST), SetFill(1, 1), SetPadding(2, 1, 2, 2), @@ -152,9 +178,19 @@ static const NWidgetPart _nested_save_dialog_widgets[] = { NWidget(WWT_CAPTION, COLOUR_GREY, WID_SL_CAPTION), NWidget(WWT_DEFSIZEBOX, COLOUR_GREY), EndContainer(), + /* Current directory and free space */ NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_BACKGROUND), SetFill(1, 0), SetResize(1, 0), EndContainer(), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), - NWidget(NWID_VERTICAL), + /* Left side : filter box and available files */ + NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 1), + /* Filter box with label */ + NWidget(NWID_HORIZONTAL), SetPadding(WD_FRAMERECT_TOP, 0, WD_FRAMERECT_BOTTOM, 0), + SetPIP(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_RIGHT, 0), + NWidget(WWT_TEXT, COLOUR_GREY), SetFill(0, 1), SetDataTip(STR_SAVELOAD_FILTER_TITLE , STR_NULL), + NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_FILTER), SetFill(1, 0), SetMinimalSize(50, 12), SetResize(1, 0), + SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), + EndContainer(), + /* Sort buttons */ NWidget(NWID_HORIZONTAL), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SORT_BYNAME), SetDataTip(STR_SORT_BY_CAPTION_NAME, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0), @@ -162,6 +198,7 @@ static const NWidgetPart _nested_save_dialog_widgets[] = { EndContainer(), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SL_HOME_BUTTON), SetMinimalSize(12, 12), SetDataTip(SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON), EndContainer(), + /* Files */ NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_FILE_BACKGROUND), NWidget(NWID_HORIZONTAL), NWidget(WWT_INSET, COLOUR_GREY, WID_SL_DRIVES_DIRECTORIES_LIST), SetPadding(2, 1, 0, 2), @@ -171,11 +208,14 @@ static const NWidgetPart _nested_save_dialog_widgets[] = { NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_SAVE_OSK_TITLE), SetPadding(3, 2, 2, 2), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_SAVELOAD_OSKTITLE, STR_SAVELOAD_EDITBOX_TOOLTIP), EndContainer(), + /* Save/delete buttons */ NWidget(NWID_HORIZONTAL), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_DELETE_SELECTION), SetDataTip(STR_SAVELOAD_DELETE_BUTTON, STR_SAVELOAD_DELETE_TOOLTIP), SetFill(1, 0), SetResize(1, 0), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SAVE_GAME), SetDataTip(STR_SAVELOAD_SAVE_BUTTON, STR_SAVELOAD_SAVE_TOOLTIP), SetFill(1, 0), SetResize(1, 0), EndContainer(), EndContainer(), + + /* Right side : game details */ NWidget(WWT_PANEL, COLOUR_GREY), NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SL_DETAILS), SetResize(1, 1), SetFill(1, 1), NWidget(NWID_HORIZONTAL), @@ -201,7 +241,7 @@ static const TextColour _fios_colours[] = { /** * Sort the collected list save games prior to displaying it in the save/load gui. - * @param [inout] file_list List of save game files found in the directory. + * @param[in,out] file_list List of save game files found in the directory. */ static void SortSaveGameList(FileList &file_list) { @@ -227,6 +267,8 @@ static void SortSaveGameList(FileList &file_list) struct SaveLoadWindow : public Window { private: + static const uint EDITBOX_MAX_SIZE = 50; + QueryString filename_editbox; ///< Filename editbox. AbstractFileType abstract_filetype; /// Type of file to select. SaveLoadOperation fop; ///< File operation to perform. @@ -234,6 +276,11 @@ private: FiosItem o_dir; const FiosItem *selected; ///< Selected game in #fios_items, or \c NULL. Scrollbar *vscroll; + + StringFilter string_filter; ///< Filter for available games. + QueryString filter_editbox; ///< Filter editbox; + SmallVector fios_items_shown; ///< Map of the filtered out fios items + public: /** Generate a default save filename. */ @@ -244,7 +291,7 @@ public: } SaveLoadWindow(WindowDesc *desc, AbstractFileType abstract_filetype, SaveLoadOperation fop) - : Window(desc), filename_editbox(64), abstract_filetype(abstract_filetype), fop(fop) + : Window(desc), filename_editbox(64), abstract_filetype(abstract_filetype), fop(fop), filter_editbox(EDITBOX_MAX_SIZE) { assert(this->fop == SLO_SAVE || this->fop == SLO_LOAD); @@ -296,6 +343,8 @@ public: this->FinishInitNested(0); this->LowerWidget(WID_SL_DRIVES_DIRECTORIES_LIST); + this->querystrings[WID_SL_FILTER] = &this->filter_editbox; + this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR; /* pause is only used in single-player, non-editor mode, non-menu mode. It * will be unpaused in the WE_DESTROY event handler. */ @@ -304,7 +353,7 @@ public: } SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0); - this->OnInvalidateData(0); + this->OnInvalidateData(SLIWD_RESCAN_FILES); ResetObjectToPlace(); @@ -327,8 +376,15 @@ public: strecpy(o_dir.name, _personal_dir, lastof(o_dir.name)); } - /* Focus the edit box by default in the save windows */ - if (this->fop == SLO_SAVE) this->SetFocusedWidget(WID_SL_SAVE_OSK_TITLE); + switch (this->fop) { + case SLO_SAVE: + /* Focus the edit box by default in the save window */ + this->SetFocusedWidget(WID_SL_SAVE_OSK_TITLE); + break; + + default: + this->SetFocusedWidget(WID_SL_FILTER); + } } virtual ~SaveLoadWindow() @@ -370,6 +426,10 @@ public: uint y = r.top + WD_FRAMERECT_TOP; for (uint pos = this->vscroll->GetPosition(); pos < this->fios_items.Length(); pos++) { + if (!this->fios_items_shown[pos]) { + /* The current item is filtered out : we do not show it */ + continue; + } const FiosItem *item = this->fios_items.Get(pos); if (item == this->selected) { @@ -507,7 +567,6 @@ public: SortSaveGameList(this->fios_items); } - this->vscroll->SetCount(this->fios_items.Length()); this->DrawWidgets(); } @@ -530,7 +589,7 @@ public: case WID_SL_HOME_BUTTON: // OpenTTD 'button', jumps to OpenTTD directory FiosBrowseTo(&o_dir); - this->InvalidateData(); + this->InvalidateData(SLIWD_RESCAN_FILES); break; case WID_SL_LOAD_BUTTON: @@ -572,6 +631,12 @@ public: int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SL_DRIVES_DIRECTORIES_LIST, WD_FRAMERECT_TOP); if (y == INT_MAX) return; + /* Get the corresponding non-filtered out item from the list */ + int i = 0; + while (i <= y) { + if (!this->fios_items_shown[i]) y++; + i++; + } const FiosItem *file = this->fios_items.Get(y); const char *name = FiosBrowseTo(file); @@ -586,7 +651,7 @@ public: SaveOrLoad(name, SLO_CHECK, DFT_GAME_FILE, NO_DIRECTORY, false); } - this->InvalidateData(1); + this->InvalidateData(SLIWD_SELECTION_CHANGES); } if (this->fop == SLO_SAVE) { /* Copy clicked name to editbox */ @@ -611,7 +676,7 @@ public: } } else { /* Changed directory, need refresh. */ - this->InvalidateData(); + this->InvalidateData(SLIWD_RESCAN_FILES); } break; } @@ -660,7 +725,7 @@ public: if (!FiosDelete(this->filename_editbox.text.buf)) { ShowErrorMessage(STR_ERROR_UNABLE_TO_DELETE_FILE, INVALID_STRING_ID, WL_ERROR); } else { - this->InvalidateData(); + this->InvalidateData(SLIWD_RESCAN_FILES); /* Reset file name to current date on successful delete */ if (this->abstract_filetype == FT_SAVEGAME) GenerateFileName(); } @@ -691,7 +756,7 @@ public: virtual void OnInvalidateData(int data = 0, bool gui_scope = true) { switch (data) { - case 0: + case SLIWD_RESCAN_FILES: /* Rescan files */ this->selected = NULL; _load_check_data.Clear(); @@ -702,9 +767,13 @@ public: this->vscroll->SetCount(this->fios_items.Length()); this->selected = NULL; _load_check_data.Clear(); + + /* We reset the files filtered */ + this->OnInvalidateData(SLIWD_FILTER_CHANGES); + FALLTHROUGH; - case 1: + case SLIWD_SELECTION_CHANGES: /* Selection changes */ if (!gui_scope) break; @@ -732,6 +801,41 @@ public: NOT_REACHED(); } break; + + case SLIWD_FILTER_CHANGES: + /* Filter changes */ + this->fios_items_shown.Resize(this->fios_items.Length()); + uint items_shown_count = 0; ///< The number of items shown in the list + /* We pass through every fios item */ + for (uint i = 0; i < this->fios_items.Length(); i++) { + if (this->string_filter.IsEmpty()) { + /* We don't filter anything out if the filter editbox is empty */ + this->fios_items_shown[i] = true; + items_shown_count++; + } else { + this->string_filter.ResetState(); + this->string_filter.AddLine(this->fios_items[i].title); + /* We set the vector to show this fios element as filtered depending on the result of the filter */ + this->fios_items_shown[i] = this->string_filter.GetState(); + if (this->fios_items_shown[i]) items_shown_count++; + + if (&(this->fios_items[i]) == this->selected && this->fios_items_shown[i] == false) { + /* The selected element has been filtered out */ + this->selected = NULL; + this->OnInvalidateData(SLIWD_SELECTION_CHANGES); + } + } + } + this->vscroll->SetCount(items_shown_count); + break; + } + } + + virtual void OnEditboxChanged(int wid) + { + if (wid == WID_SL_FILTER) { + this->string_filter.SetFilterTerm(this->filter_editbox.text.buf); + this->InvalidateData(SLIWD_FILTER_CHANGES); } } }; diff --git a/src/fontcache.cpp b/src/fontcache.cpp index 72e42ccbb3..55da0c55c8 100644 --- a/src/fontcache.cpp +++ b/src/fontcache.cpp @@ -86,6 +86,7 @@ public: virtual GlyphID MapCharToGlyph(WChar key) { assert(IsPrintable(key)); return SPRITE_GLYPH | key; } virtual const void *GetFontTable(uint32 tag, size_t &length) { length = 0; return NULL; } virtual const char *GetFontName() { return "sprite"; } + virtual bool IsBuiltInFont() { return true; } }; /** @@ -208,6 +209,8 @@ bool SpriteFontCache::GetDrawGlyphShadow() class FreeTypeFontCache : public FontCache { private: FT_Face face; ///< The font face associated with this font. + int req_size; ///< Requested font size. + int used_size; ///< Used font size. typedef SmallMap > FontTable; ///< Table with font table cache FontTable font_tables; ///< Cached font tables. @@ -236,10 +239,12 @@ private: GlyphEntry *GetGlyphPtr(GlyphID key); void SetGlyphPtr(GlyphID key, const GlyphEntry *glyph, bool duplicate = false); + void SetFontSize(FontSize fs, FT_Face face, int pixels); public: FreeTypeFontCache(FontSize fs, FT_Face face, int pixels); ~FreeTypeFontCache(); + virtual int GetFontSize() const { return this->used_size; } virtual SpriteID GetUnicodeGlyph(WChar key) { return this->parent->GetUnicodeGlyph(key); } virtual void SetUnicodeGlyph(WChar key, SpriteID sprite) { this->parent->SetUnicodeGlyph(key, sprite); } virtual void InitializeUnicodeGlyphMap() { this->parent->InitializeUnicodeGlyphMap(); } @@ -250,6 +255,7 @@ public: virtual GlyphID MapCharToGlyph(WChar key); virtual const void *GetFontTable(uint32 tag, size_t &length); virtual const char *GetFontName() { return face->family_name; } + virtual bool IsBuiltInFont() { return false; } }; FT_Library _library = NULL; @@ -265,22 +271,29 @@ static const byte SHADOW_COLOUR = 2; * @param face The font that has to be loaded. * @param pixels The number of pixels this font should be high. */ -FreeTypeFontCache::FreeTypeFontCache(FontSize fs, FT_Face face, int pixels) : FontCache(fs), face(face), glyph_to_sprite(NULL) +FreeTypeFontCache::FreeTypeFontCache(FontSize fs, FT_Face face, int pixels) : FontCache(fs), face(face), req_size(pixels), glyph_to_sprite(NULL) { assert(face != NULL); + this->SetFontSize(fs, face, pixels); +} + +void FreeTypeFontCache::SetFontSize(FontSize fs, FT_Face face, int pixels) +{ if (pixels == 0) { /* Try to determine a good height based on the minimal height recommended by the font. */ - pixels = _default_font_height[this->fs]; + int scaled_height = ScaleGUITrad(_default_font_height[this->fs]); + pixels = scaled_height; TT_Header *head = (TT_Header *)FT_Get_Sfnt_Table(this->face, ft_sfnt_head); if (head != NULL) { /* Font height is minimum height plus the difference between the default * height for this font size and the small size. */ - int diff = _default_font_height[this->fs] - _default_font_height[FS_SMALL]; - pixels = Clamp(min(head->Lowest_Rec_PPEM, 20) + diff, _default_font_height[this->fs], MAX_FONT_SIZE); + int diff = scaled_height - ScaleGUITrad(_default_font_height[FS_SMALL]); + pixels = Clamp(min(head->Lowest_Rec_PPEM, 20) + diff, scaled_height, MAX_FONT_SIZE); } } + this->used_size = pixels; FT_Error err = FT_Set_Pixel_Sizes(this->face, 0, pixels); if (err != FT_Err_Ok) { @@ -393,6 +406,7 @@ found_face: FreeTypeFontCache::~FreeTypeFontCache() { FT_Done_Face(this->face); + this->face = NULL; this->ClearFontCache(); for (FontTable::iterator iter = this->font_tables.Begin(); iter != this->font_tables.End(); iter++) { @@ -422,6 +436,9 @@ void FreeTypeFontCache::ClearFontCache() this->glyph_to_sprite = NULL; Layouter::ResetFontCache(this->fs); + + /* GUI scaling might have changed, determine font size anew if it was automatically selected. */ + if (this->face != NULL && this->req_size == 0) this->SetFontSize(this->fs, this->face, this->req_size); } FreeTypeFontCache::GlyphEntry *FreeTypeFontCache::GetGlyphPtr(GlyphID key) diff --git a/src/fontcache.h b/src/fontcache.h index 8caf4f1bd3..1f5e56d924 100644 --- a/src/fontcache.h +++ b/src/fontcache.h @@ -64,6 +64,12 @@ public: */ inline int GetUnitsPerEM() const { return this->units_per_em; } + /** + * Get the nominal font size of the font. + * @return The nominal font size. + */ + virtual int GetFontSize() const { return this->height; } + /** * Get the SpriteID mapped to the given key * @param key The key to get the sprite for. @@ -143,6 +149,11 @@ public: { return this->parent != NULL; } + + /** + * Is this a built-in sprite font? + */ + virtual bool IsBuiltInFont() = 0; }; /** Get the SpriteID mapped to the given font size and key */ diff --git a/src/fontdetection.cpp b/src/fontdetection.cpp index 14eef9f640..4279d60f3b 100644 --- a/src/fontdetection.cpp +++ b/src/fontdetection.cpp @@ -28,7 +28,7 @@ extern FT_Library _library; * Windows support * ======================================================================================== */ -#ifdef WIN32 +#ifdef _WIN32 #include "core/alloc_func.hpp" #include "core/math_func.hpp" #include diff --git a/src/framerate_gui.cpp b/src/framerate_gui.cpp new file mode 100644 index 0000000000..7e8e5f34fd --- /dev/null +++ b/src/framerate_gui.cpp @@ -0,0 +1,859 @@ +/* $Id$ */ + +/* +* 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 . +*/ + +/** @file framerate_gui.cpp GUI for displaying framerate/game speed information. */ + +#include "framerate_type.h" +#include +#include "gfx_func.h" +#include "window_gui.h" +#include "table/sprites.h" +#include "strings_func.h" +#include "debug.h" +#include "console_func.h" +#include "console_type.h" + +#include "widgets/framerate_widget.h" + + +/** + * Private declarations for performance measurement implementation + */ +namespace { + + /** Number of data points to keep in buffer for each performance measurement */ + const int NUM_FRAMERATE_POINTS = 512; + /** %Units a second is divided into in performance measurements */ + const TimingMeasurement TIMESTAMP_PRECISION = 1000000; + + struct PerformanceData { + /** Duration value indicating the value is not valid should be considered a gap in measurements */ + static const TimingMeasurement INVALID_DURATION = UINT64_MAX; + + /** Time spent processing each cycle of the performance element, circular buffer */ + TimingMeasurement durations[NUM_FRAMERATE_POINTS]; + /** Start time of each cycle of the performance element, circular buffer */ + TimingMeasurement timestamps[NUM_FRAMERATE_POINTS]; + /** Expected number of cycles per second when the system is running without slowdowns */ + double expected_rate; + /** Next index to write to in \c durations and \c timestamps */ + int next_index; + /** Last index written to in \c durations and \c timestamps */ + int prev_index; + /** Number of data points recorded, clamped to \c NUM_FRAMERATE_POINTS */ + int num_valid; + + /** Current accumulated duration */ + TimingMeasurement acc_duration; + /** Start time for current accumulation cycle */ + TimingMeasurement acc_timestamp; + + /** + * Initialize a data element with an expected collection rate + * @param expected_rate + * Expected number of cycles per second of the performance element. Use 1 if unknown or not relevant. + * The rate is used for highlighting slow-running elements in the GUI. + */ + explicit PerformanceData(double expected_rate) : expected_rate(expected_rate), next_index(0), prev_index(0), num_valid(0) { } + + /** Collect a complete measurement, given start and ending times for a processing block */ + void Add(TimingMeasurement start_time, TimingMeasurement end_time) + { + this->durations[this->next_index] = end_time - start_time; + this->timestamps[this->next_index] = start_time; + this->prev_index = this->next_index; + this->next_index += 1; + if (this->next_index >= NUM_FRAMERATE_POINTS) this->next_index = 0; + this->num_valid = min(NUM_FRAMERATE_POINTS, this->num_valid + 1); + } + + /** Begin an accumulation of multiple measurements into a single value, from a given start time */ + void BeginAccumulate(TimingMeasurement start_time) + { + this->timestamps[this->next_index] = this->acc_timestamp; + this->durations[this->next_index] = this->acc_duration; + this->prev_index = this->next_index; + this->next_index += 1; + if (this->next_index >= NUM_FRAMERATE_POINTS) this->next_index = 0; + this->num_valid = min(NUM_FRAMERATE_POINTS, this->num_valid + 1); + + this->acc_duration = 0; + this->acc_timestamp = start_time; + } + + /** Accumulate a period onto the current measurement */ + void AddAccumulate(TimingMeasurement duration) + { + this->acc_duration += duration; + } + + /** Indicate a pause/expected discontinuity in processing the element */ + void AddPause(TimingMeasurement start_time) + { + if (this->durations[this->prev_index] != INVALID_DURATION) { + this->timestamps[this->next_index] = start_time; + this->durations[this->next_index] = INVALID_DURATION; + this->prev_index = this->next_index; + this->next_index += 1; + if (this->next_index >= NUM_FRAMERATE_POINTS) this->next_index = 0; + this->num_valid += 1; + } + } + + /** Get average cycle processing time over a number of data points */ + double GetAverageDurationMilliseconds(int count) + { + count = min(count, this->num_valid); + + int first_point = this->prev_index - count; + if (first_point < 0) first_point += NUM_FRAMERATE_POINTS; + + /* Sum durations, skipping invalid points */ + double sumtime = 0; + for (int i = first_point; i < first_point + count; i++) { + auto d = this->durations[i % NUM_FRAMERATE_POINTS]; + if (d != INVALID_DURATION) { + sumtime += d; + } else { + /* Don't count the invalid durations */ + count--; + } + } + + if (count == 0) return 0; // avoid div by zero + return sumtime * 1000 / count / TIMESTAMP_PRECISION; + } + + /** Get current rate of a performance element, based on approximately the past one second of data */ + double GetRate() + { + /* Start at last recorded point, end at latest when reaching the earliest recorded point */ + int point = this->prev_index; + int last_point = this->next_index - this->num_valid; + if (last_point < 0) last_point += NUM_FRAMERATE_POINTS; + + /* Number of data points collected */ + int count = 0; + /* Time of previous data point */ + TimingMeasurement last = this->timestamps[point]; + /* Total duration covered by collected points */ + TimingMeasurement total = 0; + + while (point != last_point) { + /* Only record valid data points, but pretend the gaps in measurements aren't there */ + if (this->durations[point] != INVALID_DURATION) { + total += last - this->timestamps[point]; + count++; + } + last = this->timestamps[point]; + if (total >= TIMESTAMP_PRECISION) break; // end after 1 second has been collected + point--; + if (point < 0) point = NUM_FRAMERATE_POINTS - 1; + } + + if (total == 0 || count == 0) return 0; + return (double)count * TIMESTAMP_PRECISION / total; + } + }; + + /** %Game loop rate, cycles per second */ + static const double GL_RATE = 1000.0 / MILLISECONDS_PER_TICK; + + /** + * Storage for all performance element measurements. + * Elements are initialized with the expected rate in recorded values per second. + * @hideinitializer + */ + PerformanceData _pf_data[PFE_MAX] = { + PerformanceData(GL_RATE), // PFE_GAMELOOP + PerformanceData(1), // PFE_ACC_GL_ECONOMY + PerformanceData(1), // PFE_ACC_GL_TRAINS + PerformanceData(1), // PFE_ACC_GL_ROADVEHS + PerformanceData(1), // PFE_ACC_GL_SHIPS + PerformanceData(1), // PFE_ACC_GL_AIRCRAFT + PerformanceData(1), // PFE_GL_LANDSCAPE + PerformanceData(1), // PFE_GL_LINKGRAPH + PerformanceData(GL_RATE), // PFE_DRAWING + PerformanceData(1), // PFE_ACC_DRAWWORLD + PerformanceData(60.0), // PFE_VIDEO + PerformanceData(1000.0 * 8192 / 44100), // PFE_SOUND + }; + +} + + +/** + * Return a timestamp with \c TIMESTAMP_PRECISION ticks per second precision. + * The basis of the timestamp is implementation defined, but the value should be steady, + * so differences can be taken to reliably measure intervals. + */ +static TimingMeasurement GetPerformanceTimer() +{ + using namespace std::chrono; + return (TimingMeasurement)time_point_cast(high_resolution_clock::now()).time_since_epoch().count(); +} + + +/** + * Begin a cycle of a measured element. + * @param elem The element to be measured + */ +PerformanceMeasurer::PerformanceMeasurer(PerformanceElement elem) +{ + assert(elem < PFE_MAX); + + this->elem = elem; + this->start_time = GetPerformanceTimer(); +} + +/** Finish a cycle of a measured element and store the measurement taken. */ +PerformanceMeasurer::~PerformanceMeasurer() +{ + _pf_data[this->elem].Add(this->start_time, GetPerformanceTimer()); +} + +/** Set the rate of expected cycles per second of a performance element. */ +void PerformanceMeasurer::SetExpectedRate(double rate) +{ + _pf_data[this->elem].expected_rate = rate; +} + +/** + * Indicate that a cycle of "pause" where no processing occurs. + * @param elem The element not currently being processed + */ +void PerformanceMeasurer::Paused(PerformanceElement elem) +{ + _pf_data[elem].AddPause(GetPerformanceTimer()); +} + + +/** + * Begin measuring one block of the accumulating value. + * @param elem The element to be measured + */ +PerformanceAccumulator::PerformanceAccumulator(PerformanceElement elem) +{ + assert(elem < PFE_MAX); + + this->elem = elem; + this->start_time = GetPerformanceTimer(); +} + +/** Finish and add one block of the accumulating value. */ +PerformanceAccumulator::~PerformanceAccumulator() +{ + _pf_data[this->elem].AddAccumulate(GetPerformanceTimer() - this->start_time); +} + +/** + * Store the previous accumulator value and reset for a new cycle of accumulating measurements. + * @note This function must be called once per frame, otherwise measurements are not collected. + * @param elem The element to begin a new measurement cycle of + */ +void PerformanceAccumulator::Reset(PerformanceElement elem) +{ + _pf_data[elem].BeginAccumulate(GetPerformanceTimer()); +} + + +void ShowFrametimeGraphWindow(PerformanceElement elem); + + +/** @hideinitializer */ +static const NWidgetPart _framerate_window_widgets[] = { + NWidget(NWID_HORIZONTAL), + NWidget(WWT_CLOSEBOX, COLOUR_GREY), + NWidget(WWT_CAPTION, COLOUR_GREY, WID_FRW_CAPTION), SetDataTip(STR_FRAMERATE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_SHADEBOX, COLOUR_GREY), + NWidget(WWT_STICKYBOX, COLOUR_GREY), + EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(NWID_VERTICAL), SetPadding(6), SetPIP(0, 3, 0), + NWidget(WWT_TEXT, COLOUR_GREY, WID_FRW_RATE_GAMELOOP), SetDataTip(STR_FRAMERATE_RATE_GAMELOOP, STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP), + NWidget(WWT_TEXT, COLOUR_GREY, WID_FRW_RATE_DRAWING), SetDataTip(STR_FRAMERATE_RATE_BLITTER, STR_FRAMERATE_RATE_BLITTER_TOOLTIP), + NWidget(WWT_TEXT, COLOUR_GREY, WID_FRW_RATE_FACTOR), SetDataTip(STR_FRAMERATE_SPEED_FACTOR, STR_FRAMERATE_SPEED_FACTOR_TOOLTIP), + EndContainer(), + EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(NWID_VERTICAL), SetPadding(6), SetPIP(0, 3, 0), + NWidget(NWID_HORIZONTAL), SetPIP(0, 6, 0), + NWidget(WWT_EMPTY, COLOUR_GREY, WID_FRW_TIMES_NAMES), + NWidget(WWT_EMPTY, COLOUR_GREY, WID_FRW_TIMES_CURRENT), + NWidget(WWT_EMPTY, COLOUR_GREY, WID_FRW_TIMES_AVERAGE), + EndContainer(), + NWidget(WWT_TEXT, COLOUR_GREY, WID_FRW_INFO_DATA_POINTS), SetDataTip(STR_FRAMERATE_DATA_POINTS, 0x0), + EndContainer(), + EndContainer(), +}; + +struct FramerateWindow : Window { + bool small; + uint32 next_update; + + struct CachedDecimal { + StringID strid; + uint32 value; + + inline void SetRate(double value, double target) + { + const double threshold_good = target * 0.95; + const double threshold_bad = target * 2 / 3; + value = min(9999.99, value); + this->value = (uint32)(value * 100); + this->strid = (value > threshold_good) ? STR_FRAMERATE_FPS_GOOD : (value < threshold_bad) ? STR_FRAMERATE_FPS_BAD : STR_FRAMERATE_FPS_WARN; + } + + inline void SetTime(double value, double target) + { + const double threshold_good = target / 3; + const double threshold_bad = target; + value = min(9999.99, value); + this->value = (uint32)(value * 100); + this->strid = (value < threshold_good) ? STR_FRAMERATE_MS_GOOD : (value > threshold_bad) ? STR_FRAMERATE_MS_BAD : STR_FRAMERATE_MS_WARN; + } + + inline void InsertDParams(uint n) const + { + SetDParam(n, this->value); + SetDParam(n + 1, 2); + } + }; + + CachedDecimal rate_gameloop; ///< cached game loop tick rate + CachedDecimal rate_drawing; ///< cached drawing frame rate + CachedDecimal speed_gameloop; ///< cached game loop speed factor + CachedDecimal times_shortterm[PFE_MAX]; ///< cached short term average times + CachedDecimal times_longterm[PFE_MAX]; ///< cached long term average times + + static const int VSPACING = 3; ///< space between column heading and values + + FramerateWindow(WindowDesc *desc, WindowNumber number) : Window(desc) + { + this->InitNested(number); + this->small = this->IsShaded(); + this->UpdateData(); + } + + virtual void OnTick() + { + /* Check if the shaded state has changed, switch caption text if it has */ + if (this->small != this->IsShaded()) { + this->small = this->IsShaded(); + this->GetWidget(WID_FRW_CAPTION)->SetDataTip(this->small ? STR_FRAMERATE_CAPTION_SMALL : STR_FRAMERATE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS); + this->next_update = 0; + } + + if (_realtime_tick >= this->next_update) { + this->UpdateData(); + this->SetDirty(); + this->next_update = _realtime_tick + 100; + } + } + + void UpdateData() + { + double gl_rate = _pf_data[PFE_GAMELOOP].GetRate(); + this->rate_gameloop.SetRate(gl_rate, _pf_data[PFE_GAMELOOP].expected_rate); + this->speed_gameloop.SetRate(gl_rate / _pf_data[PFE_GAMELOOP].expected_rate, 1.0); + if (this->small) return; // in small mode, this is everything needed + + this->rate_drawing.SetRate(_pf_data[PFE_DRAWING].GetRate(), _pf_data[PFE_DRAWING].expected_rate); + + for (PerformanceElement e = PFE_FIRST; e < PFE_MAX; e++) { + this->times_shortterm[e].SetTime(_pf_data[e].GetAverageDurationMilliseconds(8), MILLISECONDS_PER_TICK); + this->times_longterm[e].SetTime(_pf_data[e].GetAverageDurationMilliseconds(NUM_FRAMERATE_POINTS), MILLISECONDS_PER_TICK); + } + } + + virtual void SetStringParameters(int widget) const + { + switch (widget) { + case WID_FRW_CAPTION: + /* When the window is shaded, the caption shows game loop rate and speed factor */ + if (!this->small) break; + SetDParam(0, this->rate_gameloop.strid); + this->rate_gameloop.InsertDParams(1); + this->speed_gameloop.InsertDParams(3); + break; + + case WID_FRW_RATE_GAMELOOP: + SetDParam(0, this->rate_gameloop.strid); + this->rate_gameloop.InsertDParams(1); + break; + case WID_FRW_RATE_DRAWING: + SetDParam(0, this->rate_drawing.strid); + this->rate_drawing.InsertDParams(1); + break; + case WID_FRW_RATE_FACTOR: + this->speed_gameloop.InsertDParams(0); + break; + case WID_FRW_INFO_DATA_POINTS: + SetDParam(0, NUM_FRAMERATE_POINTS); + break; + } + } + + virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + { + switch (widget) { + case WID_FRW_RATE_GAMELOOP: + SetDParam(0, STR_FRAMERATE_FPS_GOOD); + SetDParam(1, 999999); + SetDParam(2, 2); + *size = GetStringBoundingBox(STR_FRAMERATE_RATE_GAMELOOP); + break; + case WID_FRW_RATE_DRAWING: + SetDParam(0, STR_FRAMERATE_FPS_GOOD); + SetDParam(1, 999999); + SetDParam(2, 2); + *size = GetStringBoundingBox(STR_FRAMERATE_RATE_BLITTER); + break; + case WID_FRW_RATE_FACTOR: + SetDParam(0, 999999); + SetDParam(1, 2); + *size = GetStringBoundingBox(STR_FRAMERATE_SPEED_FACTOR); + break; + + case WID_FRW_TIMES_NAMES: { + int linecount = PFE_MAX - PFE_FIRST; + size->width = 0; + size->height = FONT_HEIGHT_NORMAL * (linecount + 1) + VSPACING; + for (int line = 0; line < linecount; line++) { + Dimension line_size = GetStringBoundingBox(STR_FRAMERATE_GAMELOOP + line); + size->width = max(size->width, line_size.width); + } + break; + } + + case WID_FRW_TIMES_CURRENT: + case WID_FRW_TIMES_AVERAGE: { + int linecount = PFE_MAX - PFE_FIRST; + *size = GetStringBoundingBox(STR_FRAMERATE_CURRENT + (widget - WID_FRW_TIMES_CURRENT)); + SetDParam(0, 999999); + SetDParam(1, 2); + Dimension item_size = GetStringBoundingBox(STR_FRAMERATE_MS_GOOD); + size->width = max(size->width, item_size.width); + size->height += FONT_HEIGHT_NORMAL * linecount + VSPACING; + break; + } + } + } + + /** Render a column of formatted average durations */ + void DrawElementTimesColumn(const Rect &r, StringID heading_str, const CachedDecimal *values) const + { + int y = r.top; + DrawString(r.left, r.right, y, heading_str, TC_FROMSTRING, SA_CENTER, true); + y += FONT_HEIGHT_NORMAL + VSPACING; + + for (PerformanceElement e = PFE_FIRST; e < PFE_MAX; e++) { + values[e].InsertDParams(0); + DrawString(r.left, r.right, y, values[e].strid, TC_FROMSTRING, SA_RIGHT); + y += FONT_HEIGHT_NORMAL; + } + } + + virtual void DrawWidget(const Rect &r, int widget) const + { + switch (widget) { + case WID_FRW_TIMES_NAMES: { + /* Render a column of titles for performance element names */ + int linecount = PFE_MAX - PFE_FIRST; + int y = r.top + FONT_HEIGHT_NORMAL + VSPACING; // first line contains headings in the value columns + for (int i = 0; i < linecount; i++) { + DrawString(r.left, r.right, y, STR_FRAMERATE_GAMELOOP + i, TC_FROMSTRING, SA_LEFT); + y += FONT_HEIGHT_NORMAL; + } + break; + } + case WID_FRW_TIMES_CURRENT: + /* Render short-term average values */ + DrawElementTimesColumn(r, STR_FRAMERATE_CURRENT, this->times_shortterm); + break; + case WID_FRW_TIMES_AVERAGE: + /* Render averages of all recorded values */ + DrawElementTimesColumn(r, STR_FRAMERATE_AVERAGE, this->times_longterm); + break; + } + } + + virtual void OnClick(Point pt, int widget, int click_count) + { + switch (widget) { + case WID_FRW_TIMES_NAMES: + case WID_FRW_TIMES_CURRENT: + case WID_FRW_TIMES_AVERAGE: { + /* Open time graph windows when clicking detail measurement lines */ + int line = this->GetRowFromWidget(pt.y, widget, VSPACING, FONT_HEIGHT_NORMAL); + if (line > 0) { + line -= 1; + ShowFrametimeGraphWindow((PerformanceElement)line); + } + break; + } + } + } +}; + +static WindowDesc _framerate_display_desc( + WDP_AUTO, "framerate_display", 60, 40, + WC_FRAMERATE_DISPLAY, WC_NONE, + 0, + _framerate_window_widgets, lengthof(_framerate_window_widgets) +); + + +/** @hideinitializer */ +static const NWidgetPart _frametime_graph_window_widgets[] = { + NWidget(NWID_HORIZONTAL), + NWidget(WWT_CLOSEBOX, COLOUR_GREY), + NWidget(WWT_CAPTION, COLOUR_GREY, WID_FGW_CAPTION), SetDataTip(STR_WHITE_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_STICKYBOX, COLOUR_GREY), + EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(NWID_VERTICAL), SetPadding(6), + NWidget(WWT_EMPTY, COLOUR_GREY, WID_FGW_GRAPH), + EndContainer(), + EndContainer(), +}; + +struct FrametimeGraphWindow : Window { + int vertical_scale; ///< number of TIMESTAMP_PRECISION units vertically + int horizontal_scale; ///< number of half-second units horizontally + uint32 next_scale_update; ///< realtime tick for next scale update + + PerformanceElement element; ///< what element this window renders graph for + Dimension graph_size; ///< size of the main graph area (excluding axis labels) + + FrametimeGraphWindow(WindowDesc *desc, WindowNumber number) : Window(desc) + { + this->element = (PerformanceElement)number; + this->horizontal_scale = 4; + this->vertical_scale = TIMESTAMP_PRECISION / 10; + this->next_scale_update = 0; + + this->InitNested(number); + } + + virtual void SetStringParameters(int widget) const + { + switch (widget) { + case WID_FGW_CAPTION: + SetDParam(0, STR_FRAMETIME_CAPTION_GAMELOOP + this->element); + break; + } + } + + virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + { + if (widget == WID_FGW_GRAPH) { + SetDParam(0, 100); + Dimension size_ms_label = GetStringBoundingBox(STR_FRAMERATE_GRAPH_MILLISECONDS); + SetDParam(0, 100); + Dimension size_s_label = GetStringBoundingBox(STR_FRAMERATE_GRAPH_SECONDS); + + /* Size graph in height to fit at least 10 vertical labels with space between, or at least 100 pixels */ + graph_size.height = max(100, 10 * (size_ms_label.height + 1)); + /* Always 2:1 graph area */ + graph_size.width = 2 * graph_size.height; + *size = graph_size; + + size->width += size_ms_label.width + 2; + size->height += size_s_label.height + 2; + } + } + + void SelectHorizontalScale(TimingMeasurement range) + { + /* Determine horizontal scale based on period covered by 60 points + * (slightly less than 2 seconds at full game speed) */ + struct ScaleDef { TimingMeasurement range; int scale; }; + static const ScaleDef hscales[] = { + { 120, 60 }, + { 10, 20 }, + { 5, 10 }, + { 3, 4 }, + { 1, 2 }, + }; + for (const ScaleDef *sc = hscales; sc < hscales + lengthof(hscales); sc++) { + if (range < sc->range) this->horizontal_scale = sc->scale; + } + } + + void SelectVerticalScale(TimingMeasurement range) + { + /* Determine vertical scale based on peak value (within the horizontal scale + a bit) */ + static const TimingMeasurement vscales[] = { + TIMESTAMP_PRECISION * 100, + TIMESTAMP_PRECISION * 10, + TIMESTAMP_PRECISION * 5, + TIMESTAMP_PRECISION, + TIMESTAMP_PRECISION / 2, + TIMESTAMP_PRECISION / 5, + TIMESTAMP_PRECISION / 10, + TIMESTAMP_PRECISION / 50, + TIMESTAMP_PRECISION / 200, + }; + for (const TimingMeasurement *sc = vscales; sc < vscales + lengthof(vscales); sc++) { + if (range < *sc) this->vertical_scale = (int)*sc; + } + } + + /** Recalculate the graph scaling factors based on current recorded data */ + void UpdateScale() + { + const TimingMeasurement *durations = _pf_data[this->element].durations; + const TimingMeasurement *timestamps = _pf_data[this->element].timestamps; + int num_valid = _pf_data[this->element].num_valid; + int point = _pf_data[this->element].prev_index; + + TimingMeasurement lastts = timestamps[point]; + TimingMeasurement time_sum = 0; + TimingMeasurement peak_value = 0; + int count = 0; + + /* Sensible default for when too few measurements are available */ + this->horizontal_scale = 4; + + for (int i = 1; i < num_valid; i++) { + point--; + if (point < 0) point = NUM_FRAMERATE_POINTS - 1; + + TimingMeasurement value = durations[point]; + if (value == PerformanceData::INVALID_DURATION) { + /* Skip gaps in data by pretending time is continuous across them */ + lastts = timestamps[point]; + continue; + } + if (value > peak_value) peak_value = value; + count++; + + /* Accumulate period of time covered by data */ + time_sum += lastts - timestamps[point]; + lastts = timestamps[point]; + + /* Enough data to select a range and get decent data density */ + if (count == 60) this->SelectHorizontalScale(time_sum / TIMESTAMP_PRECISION); + + /* End when enough points have been collected and the horizontal scale has been exceeded */ + if (count >= 60 && time_sum >= (this->horizontal_scale + 2) * TIMESTAMP_PRECISION / 2) break; + } + + this->SelectVerticalScale(peak_value); + } + + virtual void OnTick() + { + this->SetDirty(); + + if (this->next_scale_update < _realtime_tick) { + this->next_scale_update = _realtime_tick + 500; + this->UpdateScale(); + } + } + + /** Scale and interpolate a value from a source range into a destination range */ + template + static inline T Scinterlate(T dst_min, T dst_max, T src_min, T src_max, T value) + { + T dst_diff = dst_max - dst_min; + T src_diff = src_max - src_min; + return (value - src_min) * dst_diff / src_diff + dst_min; + } + + virtual void DrawWidget(const Rect &r, int widget) const + { + if (widget == WID_FGW_GRAPH) { + const TimingMeasurement *durations = _pf_data[this->element].durations; + const TimingMeasurement *timestamps = _pf_data[this->element].timestamps; + int point = _pf_data[this->element].prev_index; + + const int x_zero = r.right - (int)this->graph_size.width; + const int x_max = r.right; + const int y_zero = r.top + (int)this->graph_size.height; + const int y_max = r.top; + const int c_grid = PC_DARK_GREY; + const int c_lines = PC_BLACK; + const int c_peak = PC_DARK_RED; + + const TimingMeasurement draw_horz_scale = (TimingMeasurement)this->horizontal_scale * TIMESTAMP_PRECISION / 2; + const TimingMeasurement draw_vert_scale = (TimingMeasurement)this->vertical_scale; + + /* Number of \c horizontal_scale units in each horizontal division */ + const uint horz_div_scl = (this->horizontal_scale <= 20) ? 1 : 10; + /* Number of divisions of the horizontal axis */ + const uint horz_divisions = this->horizontal_scale / horz_div_scl; + /* Number of divisions of the vertical axis */ + const uint vert_divisions = 10; + + /* Draw division lines and labels for the vertical axis */ + for (uint division = 0; division < vert_divisions; division++) { + int y = Scinterlate(y_zero, y_max, 0, (int)vert_divisions, (int)division); + GfxDrawLine(x_zero, y, x_max, y, c_grid); + if (division % 2 == 0) { + if ((TimingMeasurement)this->vertical_scale > TIMESTAMP_PRECISION) { + SetDParam(0, this->vertical_scale * division / 10 / TIMESTAMP_PRECISION); + DrawString(r.left, x_zero - 2, y - FONT_HEIGHT_SMALL, STR_FRAMERATE_GRAPH_SECONDS, TC_GREY, SA_RIGHT | SA_FORCE, false, FS_SMALL); + } else { + SetDParam(0, this->vertical_scale * division / 10 * 1000 / TIMESTAMP_PRECISION); + DrawString(r.left, x_zero - 2, y - FONT_HEIGHT_SMALL, STR_FRAMERATE_GRAPH_MILLISECONDS, TC_GREY, SA_RIGHT | SA_FORCE, false, FS_SMALL); + } + } + } + /* Draw divison lines and labels for the horizontal axis */ + for (uint division = horz_divisions; division > 0; division--) { + int x = Scinterlate(x_zero, x_max, 0, (int)horz_divisions, (int)horz_divisions - (int)division); + GfxDrawLine(x, y_max, x, y_zero, c_grid); + if (division % 2 == 0) { + SetDParam(0, division * horz_div_scl / 2); + DrawString(x, x_max, y_zero + 2, STR_FRAMERATE_GRAPH_SECONDS, TC_GREY, SA_LEFT | SA_FORCE, false, FS_SMALL); + } + } + + /* Position of last rendered data point */ + Point lastpoint = { + x_max, + (int)Scinterlate(y_zero, y_max, 0, this->vertical_scale, durations[point]) + }; + /* Timestamp of last rendered data point */ + TimingMeasurement lastts = timestamps[point]; + + TimingMeasurement peak_value = 0; + Point peak_point = { 0, 0 }; + TimingMeasurement value_sum = 0; + TimingMeasurement time_sum = 0; + int points_drawn = 0; + + for (int i = 1; i < NUM_FRAMERATE_POINTS; i++) { + point--; + if (point < 0) point = NUM_FRAMERATE_POINTS - 1; + + TimingMeasurement value = durations[point]; + if (value == PerformanceData::INVALID_DURATION) { + /* Skip gaps in measurements, pretend the data points on each side are continuous */ + lastts = timestamps[point]; + continue; + } + + /* Use total time period covered for value along horizontal axis */ + time_sum += lastts - timestamps[point]; + lastts = timestamps[point]; + /* Stop if past the width of the graph */ + if (time_sum > draw_horz_scale) break; + + /* Draw line from previous point to new point */ + Point newpoint = { + (int)Scinterlate(x_zero, x_max, 0, (int64)draw_horz_scale, (int64)draw_horz_scale - (int64)time_sum), + (int)Scinterlate(y_zero, y_max, 0, (int64)draw_vert_scale, (int64)value) + }; + assert(newpoint.x <= lastpoint.x); + GfxDrawLine(lastpoint.x, lastpoint.y, newpoint.x, newpoint.y, c_lines); + lastpoint = newpoint; + + /* Record peak and average value across graphed data */ + value_sum += value; + points_drawn++; + if (value > peak_value) { + peak_value = value; + peak_point = newpoint; + } + } + + /* If the peak value is significantly larger than the average, mark and label it */ + if (points_drawn > 0 && peak_value > TIMESTAMP_PRECISION / 100 && 2 * peak_value > 3 * value_sum / points_drawn) { + TextColour tc_peak = (TextColour)(TC_IS_PALETTE_COLOUR | c_peak); + GfxFillRect(peak_point.x - 1, peak_point.y - 1, peak_point.x + 1, peak_point.y + 1, c_peak); + SetDParam(0, peak_value * 1000 / TIMESTAMP_PRECISION); + int label_y = max(y_max, peak_point.y - FONT_HEIGHT_SMALL); + if (peak_point.x - x_zero > (int)this->graph_size.width / 2) { + DrawString(x_zero, peak_point.x - 2, label_y, STR_FRAMERATE_GRAPH_MILLISECONDS, tc_peak, SA_RIGHT | SA_FORCE, false, FS_SMALL); + } else { + DrawString(peak_point.x + 2, x_max, label_y, STR_FRAMERATE_GRAPH_MILLISECONDS, tc_peak, SA_LEFT | SA_FORCE, false, FS_SMALL); + } + } + } + } +}; + +static WindowDesc _frametime_graph_window_desc( + WDP_AUTO, "frametime_graph", 140, 90, + WC_FRAMETIME_GRAPH, WC_NONE, + 0, + _frametime_graph_window_widgets, lengthof(_frametime_graph_window_widgets) +); + + + +/** Open the general framerate window */ +void ShowFramerateWindow() +{ + AllocateWindowDescFront(&_framerate_display_desc, 0); +} + +/** Open a graph window for a performance element */ +void ShowFrametimeGraphWindow(PerformanceElement elem) +{ + if (elem < PFE_FIRST || elem >= PFE_MAX) return; // maybe warn? + AllocateWindowDescFront(&_frametime_graph_window_desc, elem, true); +} + +/** Print performance statistics to game console */ +void ConPrintFramerate() +{ + const int count1 = NUM_FRAMERATE_POINTS / 8; + const int count2 = NUM_FRAMERATE_POINTS / 4; + const int count3 = NUM_FRAMERATE_POINTS / 1; + + IConsolePrintF(TC_SILVER, "Based on num. data points: %d %d %d", count1, count2, count3); + + static const char *MEASUREMENT_NAMES[PFE_MAX] = { + "Game loop", + " GL station ticks", + " GL train ticks", + " GL road vehicle ticks", + " GL ship ticks", + " GL aircraft ticks", + " GL landscape ticks", + " GL link graph delays", + "Drawing", + " Viewport drawing", + "Video output", + "Sound mixing", + }; + + static const PerformanceElement rate_elements[] = { PFE_GAMELOOP, PFE_DRAWING, PFE_VIDEO }; + + bool printed_anything = false; + + for (const PerformanceElement *e = rate_elements; e < rate_elements + lengthof(rate_elements); e++) { + auto &pf = _pf_data[*e]; + if (pf.num_valid == 0) continue; + IConsolePrintF(TC_GREEN, "%s rate: %.2ffps (expected: %.2ffps)", + MEASUREMENT_NAMES[*e], + pf.GetRate(), + pf.expected_rate); + printed_anything = true; + } + + for (PerformanceElement e = PFE_FIRST; e < PFE_MAX; e++) { + auto &pf = _pf_data[e]; + if (pf.num_valid == 0) continue; + IConsolePrintF(TC_LIGHT_BLUE, "%s times: %.2fms %.2fms %.2fms", + MEASUREMENT_NAMES[e], + pf.GetAverageDurationMilliseconds(count1), + pf.GetAverageDurationMilliseconds(count2), + pf.GetAverageDurationMilliseconds(count3)); + printed_anything = true; + } + + if (!printed_anything) { + IConsoleWarning("No performance measurements have been taken yet"); + } +} diff --git a/src/framerate_type.h b/src/framerate_type.h new file mode 100644 index 0000000000..8df9a279a1 --- /dev/null +++ b/src/framerate_type.h @@ -0,0 +1,109 @@ +/* $Id$ */ + +/* +* 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 . +*/ + +/** @file framerate_type.h + * Types for recording game performance data. + * + * @par Adding new measurements + * Adding a new measurement requires multiple steps, which are outlined here. + * The first thing to do is add a new member of the #PerformanceElement enum. + * It must be added before \c PFE_MAX and should be added in a logical place. + * For example, an element of the game loop would be added next to the other game loop elements, and a rendering element next to the other rendering elements. + * + * @par + * Second is adding a member to the \link anonymous_namespace{framerate_gui.cpp}::_pf_data _pf_data \endlink array, in the same position as the new #PerformanceElement member. + * + * @par + * Third is adding strings for the new element. There is an array in #ConPrintFramerate with strings used for the console command. + * Additionally, there are two sets of strings in \c english.txt for two GUI uses, also in the #PerformanceElement order. + * Search for \c STR_FRAMERATE_GAMELOOP and \c STR_FRAMETIME_CAPTION_GAMELOOP in \c english.txt to find those. + * + * @par + * Last is actually adding the measurements. There are two ways to measure, either one-shot (a single function/block handling all processing), + * or as an accumulated element (multiple functions/blocks that need to be summed across each frame/tick). + * Use either the PerformanceMeasurer or the PerformanceAccumulator class respectively for the two cases. + * Either class is used by instantiating an object of it at the beginning of the block to be measured, so it auto-destructs at the end of the block. + * For PerformanceAccumulator, make sure to also call PerformanceAccumulator::Reset once at the beginning of a new frame. Usually the StateGameLoop function is appropriate for this. + * + * @see framerate_gui.cpp for implementation + */ + +#ifndef FRAMERATE_TYPE_H +#define FRAMERATE_TYPE_H + +#include "stdafx.h" +#include "core/enum_type.hpp" + +/** + * Elements of game performance that can be measured. + * + * @note When adding new elements here, make sure to also update all other locations depending on the length and order of this enum. + * See Adding new measurements above. + */ +enum PerformanceElement { + PFE_FIRST = 0, + PFE_GAMELOOP = 0, ///< Speed of gameloop processing. + PFE_GL_ECONOMY, ///< Time spent processing cargo movement + PFE_GL_TRAINS, ///< Time spent processing trains + PFE_GL_ROADVEHS, ///< Time spend processing road vehicles + PFE_GL_SHIPS, ///< Time spent processing ships + PFE_GL_AIRCRAFT, ///< Time spent processing aircraft + PFE_GL_LANDSCAPE, ///< Time spent processing other world features + PFE_GL_LINKGRAPH, ///< Time spent waiting for link graph background jobs + PFE_DRAWING, ///< Speed of drawing world and GUI. + PFE_DRAWWORLD, ///< Time spent drawing world viewports in GUI + PFE_VIDEO, ///< Speed of painting drawn video buffer. + PFE_SOUND, ///< Speed of mixing audio samples + PFE_MAX, ///< End of enum, must be last. +}; +DECLARE_POSTFIX_INCREMENT(PerformanceElement) + +/** Type used to hold a performance timing measurement */ +typedef uint64 TimingMeasurement; + +/** + * RAII class for measuring simple elements of performance. + * Construct an object with the appropriate element parameter when processing begins, + * time is automatically taken when the object goes out of scope again. + * + * Call Paused at the start of a frame if the processing of this element is paused. + */ +class PerformanceMeasurer { + PerformanceElement elem; + TimingMeasurement start_time; +public: + PerformanceMeasurer(PerformanceElement elem); + ~PerformanceMeasurer(); + void SetExpectedRate(double rate); + static void Paused(PerformanceElement elem); +}; + +/** + * RAII class for measuring multi-step elements of performance. + * At the beginning of a frame, call Reset on the element, then construct an object in the scope where + * each processing cycle happens. The measurements are summed between resets. + * + * Usually StateGameLoop is an appropriate function to place Reset calls in, but for elements with + * more isolated scopes it can also be appropriate to Reset somewhere else. + * An example is the CallVehicleTicks function where all the vehicle type elements are reset. + * + * The PerformanceMeasurer::Paused function can also be used with elements otherwise measured with this class. + */ +class PerformanceAccumulator { + PerformanceElement elem; + TimingMeasurement start_time; +public: + PerformanceAccumulator(PerformanceElement elem); + ~PerformanceAccumulator(); + static void Reset(PerformanceElement elem); +}; + +void ShowFramerateWindow(); + +#endif /* FRAMERATE_TYPE_H */ diff --git a/src/game/game_info.cpp b/src/game/game_info.cpp index 9761532965..f8c04608b7 100644 --- a/src/game/game_info.cpp +++ b/src/game/game_info.cpp @@ -29,9 +29,9 @@ static bool CheckAPIVersion(const char *api_version) strcmp(api_version, "1.8") == 0 || strcmp(api_version, "1.9") == 0; } -#if defined(WIN32) +#if defined(_WIN32) #undef GetClassName -#endif /* WIN32 */ +#endif /* _WIN32 */ template <> const char *GetClassName() { return "GSInfo"; } /* static */ void GameInfo::RegisterAPI(Squirrel *engine) diff --git a/src/game/game_text.cpp b/src/game/game_text.cpp index 42ced20083..a32e5b41d7 100644 --- a/src/game/game_text.cpp +++ b/src/game/game_text.cpp @@ -142,7 +142,7 @@ struct StringListReader : StringReader { /** * Create the reader. * @param data The data to fill during reading. - * @param file The file we are reading. + * @param strings The language strings we are reading. * @param master Are we reading the master file? * @param translation Are we reading a translation? */ diff --git a/src/gamelog.cpp b/src/gamelog.cpp index 400c0d22fb..621117f01b 100644 --- a/src/gamelog.cpp +++ b/src/gamelog.cpp @@ -771,9 +771,9 @@ void GamelogGRFUpdate(const GRFConfig *oldc, const GRFConfig *newc) * Get some basic information from the given gamelog. * @param gamelog_action Pointer to the gamelog to extract information from. * @param gamelog_actions Number of actions in the given gamelog. - * @param [out] last_ottd_rev OpenTTD NewGRF version from the binary that saved the savegame last. - * @param [out] ever_modified Max value of 'modified' from all binaries that ever saved this savegame. - * @param [out] removed_newgrfs Set to true if any NewGRFs have been removed. + * @param[out] last_ottd_rev OpenTTD NewGRF version from the binary that saved the savegame last. + * @param[out] ever_modified Max value of 'modified' from all binaries that ever saved this savegame. + * @param[out] removed_newgrfs Set to true if any NewGRFs have been removed. */ void GamelogInfo(LoggedAction *gamelog_action, uint gamelog_actions, uint32 *last_ottd_rev, byte *ever_modified, bool *removed_newgrfs) { diff --git a/src/gamelog.h b/src/gamelog.h index 7f5b6a7765..83694e3ea8 100644 --- a/src/gamelog.h +++ b/src/gamelog.h @@ -38,7 +38,7 @@ void GamelogReset(); * @param s The string to print. */ typedef void GamelogPrintProc(const char *s); -void GamelogPrint(GamelogPrintProc *proc); // needed for WIN32 / WINCE crash.log +void GamelogPrint(GamelogPrintProc *proc); // needed for WIN32 crash.log void GamelogPrintDebug(int level); void GamelogPrintConsole(); diff --git a/src/genworld.h b/src/genworld.h index ea3faa15fc..1b1c806e09 100644 --- a/src/genworld.h +++ b/src/genworld.h @@ -22,7 +22,7 @@ enum LandscapeGenerator { LG_TERRAGENESIS = 1, ///< TerraGenesis Perlin landscape generator }; -static const uint GENERATE_NEW_SEED = UINT_MAX; ///< Create a new random seed +static const uint32 GENERATE_NEW_SEED = UINT32_MAX; ///< Create a new random seed /** Modes for GenerateWorld */ enum GenWorldMode { @@ -97,7 +97,7 @@ void SetGeneratingWorldProgress(GenWorldProgress cls, uint total); void IncreaseGeneratingWorldProgress(GenWorldProgress cls); void PrepareGenerateWorldProgress(); void ShowGenerateWorldProgress(); -void StartNewGameWithoutGUI(uint seed); +void StartNewGameWithoutGUI(uint32 seed); void ShowCreateScenario(); void StartScenarioEditor(); diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index 359709e361..b22ba5287e 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -288,7 +288,7 @@ static DropDownList *BuildMapsizeDropDown() for (uint i = MIN_MAP_SIZE_BITS; i <= MAX_MAP_SIZE_BITS; i++) { DropDownListParamStringItem *item = new DropDownListParamStringItem(STR_JUST_INT, i, false); - item->SetParam(0, 1 << i); + item->SetParam(0, 1LL << i); *list->Append() = item; } @@ -336,8 +336,8 @@ struct GenerateLandscapeWindow : public Window { { switch (widget) { case WID_GL_START_DATE_TEXT: SetDParam(0, ConvertYMDToDate(_settings_newgame.game_creation.starting_year, 0, 1)); break; - case WID_GL_MAPSIZE_X_PULLDOWN: SetDParam(0, 1 << _settings_newgame.game_creation.map_x); break; - case WID_GL_MAPSIZE_Y_PULLDOWN: SetDParam(0, 1 << _settings_newgame.game_creation.map_y); break; + case WID_GL_MAPSIZE_X_PULLDOWN: SetDParam(0, 1LL << _settings_newgame.game_creation.map_x); break; + case WID_GL_MAPSIZE_Y_PULLDOWN: SetDParam(0, 1LL << _settings_newgame.game_creation.map_y); break; case WID_GL_MAX_HEIGHTLEVEL_TEXT: SetDParam(0, _settings_newgame.construction.max_heightlevel); break; case WID_GL_SNOW_LEVEL_TEXT: SetDParam(0, _settings_newgame.game_creation.snow_line_height); break; @@ -870,7 +870,7 @@ void StartScenarioEditor() * Start a normal game without the GUI. * @param seed The seed of the new game. */ -void StartNewGameWithoutGUI(uint seed) +void StartNewGameWithoutGUI(uint32 seed) { /* GenerateWorld takes care of the possible GENERATE_NEW_SEED value in 'seed' */ _settings_newgame.game_creation.generation_seed = seed; @@ -896,11 +896,11 @@ struct CreateScenarioWindow : public Window break; case WID_CS_MAPSIZE_X_PULLDOWN: - SetDParam(0, 1 << _settings_newgame.game_creation.map_x); + SetDParam(0, 1LL << _settings_newgame.game_creation.map_x); break; case WID_CS_MAPSIZE_Y_PULLDOWN: - SetDParam(0, 1 << _settings_newgame.game_creation.map_y); + SetDParam(0, 1LL << _settings_newgame.game_creation.map_y); break; case WID_CS_FLAT_LAND_HEIGHT_TEXT: diff --git a/src/gfx.cpp b/src/gfx.cpp index 7195051577..605ff7664b 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -703,8 +703,8 @@ Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize) } /** - * Get bounding box of a string. Uses parameters set by #DParam if needed. - * Has the same restrictions as #GetStringBoundingBox(const char *str). + * Get bounding box of a string. Uses parameters set by #SetDParam if needed. + * Has the same restrictions as #GetStringBoundingBox(const char *str, FontSize start_fontsize). * @param strid String to examine. * @return Width and height of the bounding box for the string in pixels. */ @@ -761,7 +761,7 @@ void DrawCharCentered(WChar c, int x, int y, TextColour colour) /** * Get the size of a sprite. * @param sprid Sprite to examine. - * @param [out] offset Optionally returns the sprite position offset. + * @param[out] offset Optionally returns the sprite position offset. * @return Sprite size in pixels. * @note The size assumes (0, 0) as top-left coordinate and ignores any part of the sprite drawn at the left or above that position. */ @@ -1111,16 +1111,17 @@ void DoPaletteAnimations() /** * Determine a contrasty text colour for a coloured background. * @param background Background colour. + * @param threshold Background colour brightness threshold below which the background is considered dark and TC_WHITE is returned, range: 0 - 255, default 128. * @return TC_BLACK or TC_WHITE depending on what gives a better contrast. */ -TextColour GetContrastColour(uint8 background) +TextColour GetContrastColour(uint8 background, uint8 threshold) { Colour c = _cur_palette.palette[background]; /* Compute brightness according to http://www.w3.org/TR/AERT#color-contrast. * The following formula computes 1000 * brightness^2, with brightness being in range 0 to 255. */ uint sq1000_brightness = c.r * c.r * 299 + c.g * c.g * 587 + c.b * c.b * 114; - /* Compare with threshold brightness 128 (50%) */ - return sq1000_brightness < 128 * 128 * 1000 ? TC_WHITE : TC_BLACK; + /* Compare with threshold brightness which defaults to 128 (50%) */ + return sq1000_brightness < ((uint) threshold) * ((uint) threshold) * 1000 ? TC_WHITE : TC_BLACK; } /** @@ -1169,8 +1170,8 @@ byte GetDigitWidth(FontSize size) /** * Determine the broadest digits for guessing the maximum width of a n-digit number. - * @param [out] front Broadest digit, which is not 0. (Use this digit as first digit for numbers with more than one digit.) - * @param [out] next Broadest digit, including 0. (Use this digit for all digits, except the first one; or for numbers with only one digit.) + * @param[out] front Broadest digit, which is not 0. (Use this digit as first digit for numbers with more than one digit.) + * @param[out] next Broadest digit, including 0. (Use this digit for all digits, except the first one; or for numbers with only one digit.) * @param size Font of the digit */ void GetBroadestDigit(uint *front, uint *next, FontSize size) @@ -1214,11 +1215,6 @@ void UndrawMouseCursor() void DrawMouseCursor() { -#if defined(WINCE) - /* Don't ever draw the mouse for WinCE, as we work with a stylus */ - return; -#endif - /* Don't draw the mouse cursor if the screen is not ready */ if (_screen.dst_ptr == NULL) return; @@ -1639,8 +1635,8 @@ void SetAnimatedMouseCursor(const AnimCursor *table) * Update cursor position on mouse movement. * @param x New X position. * @param y New Y position. - * @param queued True, if the OS queues mouse warps after pending mouse movement events. - * False, if the warp applies instantaneous. + * @param queued_warp True, if the OS queues mouse warps after pending mouse movement events. + * False, if the warp applies instantaneous. * @return true, if the OS cursor position should be warped back to this->pos. */ bool CursorVars::UpdateCursorPosition(int x, int y, bool queued_warp) diff --git a/src/gfx_func.h b/src/gfx_func.h index 99461f9079..9f7cb9153d 100644 --- a/src/gfx_func.h +++ b/src/gfx_func.h @@ -187,7 +187,7 @@ int GetCharacterHeight(FontSize size); extern DrawPixelInfo *_cur_dpi; -TextColour GetContrastColour(uint8 background); +TextColour GetContrastColour(uint8 background, uint8 threshold = 128); /** * All 16 colour gradients diff --git a/src/gfx_layout.cpp b/src/gfx_layout.cpp index 3290aea653..c65ead90e1 100644 --- a/src/gfx_layout.cpp +++ b/src/gfx_layout.cpp @@ -21,6 +21,14 @@ #include #endif /* WITH_ICU_LAYOUT */ +#ifdef WITH_UNISCRIBE +#include "os/windows/string_uniscribe.h" +#endif /* WITH_UNISCRIBE */ + +#ifdef WITH_COCOA +#include "os/macosx/string_osx.h" +#endif + #include "safeguards.h" @@ -113,32 +121,18 @@ le_bool Font::getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &poin return FALSE; } -static size_t AppendToBuffer(UChar *buff, const UChar *buffer_last, WChar c) -{ - /* Transform from UTF-32 to internal ICU format of UTF-16. */ - int32 length = 0; - UErrorCode err = U_ZERO_ERROR; - u_strFromUTF32(buff, buffer_last - buff, &length, (UChar32*)&c, 1, &err); - return length; -} - /** * Wrapper for doing layouts with ICU. */ class ICUParagraphLayout : public AutoDeleteSmallVector, public ParagraphLayouter { - ParagraphLayout *p; ///< The actual ICU paragraph layout. + icu::ParagraphLayout *p; ///< The actual ICU paragraph layout. public: - /** Helper for GetLayouter, to get the right type. */ - typedef UChar CharType; - /** Helper for GetLayouter, to get whether the layouter supports RTL. */ - static const bool SUPPORTS_RTL = true; - /** Visual run contains data about the bit of text with the same font. */ class ICUVisualRun : public ParagraphLayouter::VisualRun { - const ParagraphLayout::VisualRun *vr; ///< The actual ICU vr. + const icu::ParagraphLayout::VisualRun *vr; ///< The actual ICU vr. public: - ICUVisualRun(const ParagraphLayout::VisualRun *vr) : vr(vr) { } + ICUVisualRun(const icu::ParagraphLayout::VisualRun *vr) : vr(vr) { } const Font *GetFont() const { return (const Font*)vr->getFont(); } int GetGlyphCount() const { return vr->getGlyphCount(); } @@ -150,10 +144,10 @@ public: /** A single line worth of VisualRuns. */ class ICULine : public AutoDeleteSmallVector, public ParagraphLayouter::Line { - ParagraphLayout::Line *l; ///< The actual ICU line. + icu::ParagraphLayout::Line *l; ///< The actual ICU line. public: - ICULine(ParagraphLayout::Line *l) : l(l) + ICULine(icu::ParagraphLayout::Line *l) : l(l) { for (int i = 0; i < l->countRuns(); i++) { *this->Append() = new ICUVisualRun(l->getVisualRun(i)); @@ -173,46 +167,65 @@ public: } }; - ICUParagraphLayout(ParagraphLayout *p) : p(p) { } + ICUParagraphLayout(icu::ParagraphLayout *p) : p(p) { } ~ICUParagraphLayout() { delete p; } void Reflow() { p->reflow(); } ParagraphLayouter::Line *NextLine(int max_width) { - ParagraphLayout::Line *l = p->nextLine(max_width); + icu::ParagraphLayout::Line *l = p->nextLine(max_width); return l == NULL ? NULL : new ICULine(l); } }; -static ParagraphLayouter *GetParagraphLayout(UChar *buff, UChar *buff_end, FontMap &fontMapping) -{ - int32 length = buff_end - buff; +/** + * Helper class to construct a new #ICUParagraphLayout. + */ +class ICUParagraphLayoutFactory { +public: + /** Helper for GetLayouter, to get the right type. */ + typedef UChar CharType; + /** Helper for GetLayouter, to get whether the layouter supports RTL. */ + static const bool SUPPORTS_RTL = true; - if (length == 0) { - /* ICU's ParagraphLayout cannot handle empty strings, so fake one. */ - buff[0] = ' '; - length = 1; - fontMapping.End()[-1].first++; + static ParagraphLayouter *GetParagraphLayout(UChar *buff, UChar *buff_end, FontMap &fontMapping) + { + int32 length = buff_end - buff; + + if (length == 0) { + /* ICU's ParagraphLayout cannot handle empty strings, so fake one. */ + buff[0] = ' '; + length = 1; + fontMapping.End()[-1].first++; + } + + /* Fill ICU's FontRuns with the right data. */ + icu::FontRuns runs(fontMapping.Length()); + for (FontMap::iterator iter = fontMapping.Begin(); iter != fontMapping.End(); iter++) { + runs.add(iter->second, iter->first); + } + + LEErrorCode status = LE_NO_ERROR; + /* ParagraphLayout does not copy "buff", so it must stay valid. + * "runs" is copied according to the ICU source, but the documentation does not specify anything, so this might break somewhen. */ + icu::ParagraphLayout *p = new icu::ParagraphLayout(buff, length, &runs, NULL, NULL, NULL, _current_text_dir == TD_RTL ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR, false, status); + if (status != LE_NO_ERROR) { + delete p; + return NULL; + } + + return new ICUParagraphLayout(p); } - /* Fill ICU's FontRuns with the right data. */ - FontRuns runs(fontMapping.Length()); - for (FontMap::iterator iter = fontMapping.Begin(); iter != fontMapping.End(); iter++) { - runs.add(iter->second, iter->first); + static size_t AppendToBuffer(UChar *buff, const UChar *buffer_last, WChar c) + { + /* Transform from UTF-32 to internal ICU format of UTF-16. */ + int32 length = 0; + UErrorCode err = U_ZERO_ERROR; + u_strFromUTF32(buff, buffer_last - buff, &length, (UChar32*)&c, 1, &err); + return length; } - - LEErrorCode status = LE_NO_ERROR; - /* ParagraphLayout does not copy "buff", so it must stay valid. - * "runs" is copied according to the ICU source, but the documentation does not specify anything, so this might break somewhen. */ - ParagraphLayout *p = new ParagraphLayout(buff, length, &runs, NULL, NULL, NULL, _current_text_dir == TD_RTL ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR, false, status); - if (status != LE_NO_ERROR) { - delete p; - return NULL; - } - - return new ICUParagraphLayout(p); -} - +}; #endif /* WITH_ICU_LAYOUT */ /*** Paragraph layout ***/ @@ -236,11 +249,6 @@ static ParagraphLayouter *GetParagraphLayout(UChar *buff, UChar *buff_end, FontM */ class FallbackParagraphLayout : public ParagraphLayouter { public: - /** Helper for GetLayouter, to get the right type. */ - typedef WChar CharType; - /** Helper for GetLayouter, to get whether the layouter supports RTL. */ - static const bool SUPPORTS_RTL = false; - /** Visual run contains data about the bit of text with the same font. */ class FallbackVisualRun : public ParagraphLayouter::VisualRun { Font *font; ///< The font used to layout these. @@ -280,6 +288,42 @@ public: const ParagraphLayouter::Line *NextLine(int max_width); }; +/** + * Helper class to construct a new #FallbackParagraphLayout. + */ +class FallbackParagraphLayoutFactory { +public: + /** Helper for GetLayouter, to get the right type. */ + typedef WChar CharType; + /** Helper for GetLayouter, to get whether the layouter supports RTL. */ + static const bool SUPPORTS_RTL = false; + + /** + * Get the actual ParagraphLayout for the given buffer. + * @param buff The begin of the buffer. + * @param buff_end The location after the last element in the buffer. + * @param fontMapping THe mapping of the fonts. + * @return The ParagraphLayout instance. + */ + static ParagraphLayouter *GetParagraphLayout(WChar *buff, WChar *buff_end, FontMap &fontMapping) + { + return new FallbackParagraphLayout(buff, buff_end - buff, fontMapping); + } + + /** + * Append a wide character to the internal buffer. + * @param buff The buffer to append to. + * @param buffer_last The end of the buffer. + * @param c The character to add. + * @return The number of buffer spaces that were used. + */ + static size_t AppendToBuffer(WChar *buff, const WChar *buffer_last, WChar c) + { + *buff = c; + return 1; + } +}; + /** * Create the visual run. * @param font The font to use for this run. @@ -458,11 +502,6 @@ const ParagraphLayouter::Line *FallbackParagraphLayout::NextLine(int max_width) return l; } - const WChar *begin = this->buffer; - const WChar *last_space = NULL; - const WChar *last_char = begin; - int width = 0; - int offset = this->buffer - this->buffer_begin; FontMap::iterator iter = this->runs.Begin(); while (iter->first <= offset) { @@ -473,6 +512,10 @@ const ParagraphLayouter::Line *FallbackParagraphLayout::NextLine(int max_width) const FontCache *fc = iter->second->fc; const WChar *next_run = this->buffer_begin + iter->first; + const WChar *begin = this->buffer; + const WChar *last_space = NULL; + const WChar *last_char; + int width = 0; for (;;) { WChar c = *this->buffer; last_char = this->buffer; @@ -536,31 +579,6 @@ const ParagraphLayouter::Line *FallbackParagraphLayout::NextLine(int max_width) return l; } -/** - * Appand a wide character to the internal buffer. - * @param buff The buffer to append to. - * @param buffer_last The end of the buffer. - * @param c The character to add. - * @return The number of buffer spaces that were used. - */ -static size_t AppendToBuffer(WChar *buff, const WChar *buffer_last, WChar c) -{ - *buff = c; - return 1; -} - -/** - * Get the actual ParagraphLayout for the given buffer. - * @param buff The begin of the buffer. - * @param buff_end The location after the last element in the buffer. - * @param fontMapping THe mapping of the fonts. - * @return The ParagraphLayout instance. - */ -static FallbackParagraphLayout *GetParagraphLayout(WChar *buff, WChar *buff_end, FontMap &fontMapping) -{ - return new FallbackParagraphLayout(buff, buff_end - buff, fontMapping); -} - /** * Helper for getting a ParagraphLayouter of the given type. * @@ -582,6 +600,7 @@ static inline void GetLayouter(Layouter::LineCacheItem &line, const char *&str, Font *f = Layouter::GetFont(state.fontsize, state.cur_colour); line.buffer = buff_begin; + fontMapping.Clear(); /* * Go through the whole string while adding Font instances to the font map @@ -605,7 +624,7 @@ static inline void GetLayouter(Layouter::LineCacheItem &line, const char *&str, * will not be handled in the fallback non ICU case because they are * mostly needed for RTL languages which need more ICU support. */ if (!T::SUPPORTS_RTL && IsTextDirectionChar(c)) continue; - buff += AppendToBuffer(buff, buffer_last, c); + buff += T::AppendToBuffer(buff, buffer_last, c); continue; } @@ -621,7 +640,7 @@ static inline void GetLayouter(Layouter::LineCacheItem &line, const char *&str, if (!fontMapping.Contains(buff - buff_begin)) { fontMapping.Insert(buff - buff_begin, f); } - line.layout = GetParagraphLayout(buff_begin, buff, fontMapping); + line.layout = T::GetParagraphLayout(buff_begin, buff, fontMapping); line.state_after = state; } @@ -654,11 +673,13 @@ Layouter::Layouter(const char *str, int maxw, TextColour colour, FontSize fontsi line.layout->Reflow(); } else { /* Line is new, layout it */ -#ifdef WITH_ICU_LAYOUT FontState old_state = state; +#if defined(WITH_ICU_LAYOUT) || defined(WITH_UNISCRIBE) || defined(WITH_COCOA) const char *old_str = str; +#endif - GetLayouter(line, str, state); +#ifdef WITH_ICU_LAYOUT + GetLayouter(line, str, state); if (line.layout == NULL) { static bool warned = false; if (!warned) { @@ -668,11 +689,32 @@ Layouter::Layouter(const char *str, int maxw, TextColour colour, FontSize fontsi state = old_state; str = old_str; - GetLayouter(line, str, state); } -#else - GetLayouter(line, str, state); #endif + +#ifdef WITH_UNISCRIBE + if (line.layout == NULL) { + GetLayouter(line, str, state); + if (line.layout == NULL) { + state = old_state; + str = old_str; + } + } +#endif + +#ifdef WITH_COCOA + if (line.layout == NULL) { + GetLayouter(line, str, state); + if (line.layout == NULL) { + state = old_state; + str = old_str; + } + } +#endif + + if (line.layout == NULL) { + GetLayouter(line, str, state); + } } /* Copy all lines into a local cache so we can reuse them later on more easily. */ @@ -809,6 +851,13 @@ void Layouter::ResetFontCache(FontSize size) /* We must reset the linecache since it references the just freed fonts */ ResetLineCache(); + +#if defined(WITH_UNISCRIBE) + UniscribeResetScriptCache(size); +#endif +#if defined(WITH_COCOA) + MacOSResetScriptCache(size); +#endif } /** diff --git a/src/gfx_layout.h b/src/gfx_layout.h index 45d79ae474..f6fc3b5c71 100644 --- a/src/gfx_layout.h +++ b/src/gfx_layout.h @@ -22,7 +22,7 @@ #ifdef WITH_ICU_LAYOUT #include "layout/ParagraphLayout.h" -#define ICU_FONTINSTANCE : public LEFontInstance +#define ICU_FONTINSTANCE : public icu::LEFontInstance #else /* WITH_ICU_LAYOUT */ #define ICU_FONTINSTANCE #endif /* WITH_ICU_LAYOUT */ diff --git a/src/gfx_type.h b/src/gfx_type.h index ca9bf9fcef..4cfc149a86 100644 --- a/src/gfx_type.h +++ b/src/gfx_type.h @@ -189,7 +189,7 @@ union Colour { /** * Create a new colour. - * @param The colour in the correct packed format. + * @param data The colour in the correct packed format. */ Colour(uint data = 0) : data(data) { diff --git a/src/gfxinit.cpp b/src/gfxinit.cpp index d5959f5e16..3613ce0d86 100644 --- a/src/gfxinit.cpp +++ b/src/gfxinit.cpp @@ -80,7 +80,7 @@ static uint LoadGrfFile(const char *filename, uint load_index, int file_index) /** * Load an old fashioned GRF file to replace already loaded sprites. * @param filename The name of the file to open. - * @param index_tlb The offsets of each of the sprites. + * @param index_tbl The offsets of each of the sprites. * @param file_index The Fio offset to load the file in. * @return The number of loaded sprites. */ @@ -284,6 +284,9 @@ static bool SwitchNewGRFBlitter() #endif { "8bpp-optimized", 2, 8, 8, 8, 8 }, { "32bpp-optimized", 0, 8, 32, 8, 32 }, +#ifdef WITH_SSE + { "32bpp-sse2-anim", 1, 8, 32, 8, 32 }, +#endif { "32bpp-anim", 1, 8, 32, 8, 32 }, }; diff --git a/src/goal.cpp b/src/goal.cpp index 2f6ca242a9..f7aae350e5 100644 --- a/src/goal.cpp +++ b/src/goal.cpp @@ -23,6 +23,8 @@ #include "string_func.h" #include "gui.h" #include "network/network.h" +#include "network/network_base.h" +#include "network/network_func.h" #include "safeguards.h" @@ -234,7 +236,9 @@ CommandCost CmdSetGoalCompleted(TileIndex tile, DoCommandFlag flags, uint32 p1, * @param flags type of operation * @param p1 various bitstuffed elements * - p1 = (bit 0 - 15) - Unique ID to use for this question. - * - p1 = (bit 16 - 23) - Company for which this question is. + * - p1 = (bit 16 - 23) - Company or client for which this question is. + * - p1 = (bit 24 - 25) - Question type. + * - p1 = (bit 31) - Question target: 0 - company, 1 - client. * @param p2 Buttons of the question. * @param text Text of the question. * @return the cost of this operation or an error @@ -243,17 +247,37 @@ CommandCost CmdGoalQuestion(TileIndex tile, DoCommandFlag flags, uint32 p1, uint { uint16 uniqueid = (GoalType)GB(p1, 0, 16); CompanyID company = (CompanyID)GB(p1, 16, 8); - byte type = GB(p1, 24, 8); +#ifdef ENABLE_NETWORK + ClientIndex client = (ClientIndex)GB(p1, 16, 8); +#endif + byte type = GB(p1, 24, 2); + bool is_client = HasBit(p1, 31); if (_current_company != OWNER_DEITY) return CMD_ERROR; if (StrEmpty(text)) return CMD_ERROR; - if (company != INVALID_COMPANY && !Company::IsValidID(company)) return CMD_ERROR; + if (is_client) { +#ifdef ENABLE_NETWORK + if (!NetworkClientInfo::IsValidID(client)) return CMD_ERROR; +#else + return CMD_ERROR; +#endif + } else { + if (company != INVALID_COMPANY && !Company::IsValidID(company)) return CMD_ERROR; + } if (CountBits(p2) < 1 || CountBits(p2) > 3) return CMD_ERROR; if (p2 >= (1 << GOAL_QUESTION_BUTTON_COUNT)) return CMD_ERROR; if (type >= GOAL_QUESTION_TYPE_COUNT) return CMD_ERROR; if (flags & DC_EXEC) { - if ((company != INVALID_COMPANY && company == _local_company) || (company == INVALID_COMPANY && Company::IsValidID(_local_company))) ShowGoalQuestion(uniqueid, type, p2, text); + if (is_client) { +#ifdef ENABLE_NETWORK + if (NetworkClientInfo::Get(client)->client_id != _network_own_client_id) return CommandCost(); +#endif + } else { + if (company == INVALID_COMPANY && !Company::IsValidID(_local_company)) return CommandCost(); + if (company != INVALID_COMPANY && company != _local_company) return CommandCost(); + } + ShowGoalQuestion(uniqueid, type, p2, text); } return CommandCost(); diff --git a/src/goal_gui.cpp b/src/goal_gui.cpp index f98189d183..ee4d8170e1 100644 --- a/src/goal_gui.cpp +++ b/src/goal_gui.cpp @@ -101,7 +101,7 @@ struct GoalListWindow : public Window { /** * Handle clicking at a goal. - * @param s @Goal clicked at. + * @param s #Goal clicked at. */ void HandleClick(const Goal *s) { @@ -193,7 +193,7 @@ struct GoalListWindow : public Window { /** * Draws either the global goals or the company goal section. * This is a helper method for #DrawWidget. - * @param pos [inout] Vertical line number to draw. + * @param[in,out] pos Vertical line number to draw. * @param cap Number of lines to draw in the window. * @param x Left edge of the text line to draw. * @param y Vertical position of the top edge of the window. @@ -250,8 +250,8 @@ struct GoalListWindow : public Window { /** * Draws a given column of the goal list. * @param column Which column to draw. - * @wid Pointer to the goal list widget. - * @progress_col_width Width of the progress column. + * @param wid Pointer to the goal list widget. + * @param progress_col_width Width of the progress column. * @return max width of drawn text */ void DrawListColumn(GoalColumn column, NWidgetBase *wid, uint progress_col_width) const diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index c12c6ace4d..48b8c4c84a 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -33,8 +33,8 @@ #include "safeguards.h" /* Bitmasks of company and cargo indices that shouldn't be drawn. */ -static uint _legend_excluded_companies; -static uint _legend_excluded_cargo; +static CompanyMask _legend_excluded_companies; +static CargoTypes _legend_excluded_cargo; /* Apparently these don't play well with enums. */ static const OverflowSafeInt64 INVALID_DATAPOINT(INT64_MAX); // Value used for a datapoint that shouldn't be drawn. @@ -166,14 +166,14 @@ struct ValuesInterval { struct BaseGraphWindow : Window { protected: - static const int GRAPH_MAX_DATASETS = 32; + static const int GRAPH_MAX_DATASETS = 64; static const int GRAPH_AXIS_LINE_COLOUR = PC_BLACK; static const int GRAPH_NUM_MONTHS = 24; ///< Number of months displayed in the graph. static const int MIN_GRAPH_NUM_LINES_Y = 9; ///< Minimal number of horizontal lines to draw. static const int MIN_GRID_PIXEL_SIZE = 20; ///< Minimum distance between graph lines. - uint excluded_data; ///< bitmask of the datasets that shouldn't be displayed. + uint64 excluded_data; ///< bitmask of the datasets that shouldn't be displayed. byte num_dataset; byte num_on_x_axis; byte num_vert_lines; @@ -561,7 +561,7 @@ public: */ void UpdateStatistics(bool initialize) { - uint excluded_companies = _legend_excluded_companies; + CompanyMask excluded_companies = _legend_excluded_companies; /* Exclude the companies which aren't valid */ for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { @@ -1402,9 +1402,9 @@ struct PerformanceRatingDetailWindow : Window { int colour_notdone = _colour_gradient[COLOUR_RED][4]; /* Draw all the score parts */ - int val = _score_part[company][score_type]; - int needed = _score_info[score_type].needed; - int score = _score_info[score_type].score; + int64 val = _score_part[company][score_type]; + int64 needed = _score_info[score_type].needed; + int score = _score_info[score_type].score; /* SCORE_TOTAL has his own rules ;) */ if (score_type == SCORE_TOTAL) { @@ -1422,7 +1422,7 @@ struct PerformanceRatingDetailWindow : Window { DrawString(this->score_info_left, this->score_info_right, text_top, STR_BLACK_COMMA, TC_FROMSTRING, SA_RIGHT); /* Calculate the %-bar */ - uint x = Clamp(val, 0, needed) * this->bar_width / needed; + uint x = Clamp(val, 0, needed) * this->bar_width / needed; bool rtl = _current_text_dir == TD_RTL; if (rtl) { x = this->bar_right - x; @@ -1435,7 +1435,7 @@ struct PerformanceRatingDetailWindow : Window { if (x != this->bar_right) GfxFillRect(x, bar_top, this->bar_right, bar_top + this->bar_height, rtl ? colour_done : colour_notdone); /* Draw it */ - SetDParam(0, Clamp(val, 0, needed) * 100 / needed); + SetDParam(0, Clamp(val, 0, needed) * 100 / needed); DrawString(this->bar_left, this->bar_right, text_top, STR_PERFORMANCE_DETAIL_PERCENT, TC_FROMSTRING, SA_HOR_CENTER); /* SCORE_LOAN is inversed */ diff --git a/src/ground_vehicle.cpp b/src/ground_vehicle.cpp index fcdab77b03..6fd8d77106 100644 --- a/src/ground_vehicle.cpp +++ b/src/ground_vehicle.cpp @@ -58,8 +58,8 @@ void GroundVehicle::PowerChanged() this->gcache.cached_air_drag = air_drag + 3 * air_drag * number_of_parts / 20; - max_te *= 10000; // Tractive effort in (tonnes * 1000 * 10 =) N. - max_te /= 256; // Tractive effort is a [0-255] coefficient. + max_te *= GROUND_ACCELERATION; // Tractive effort in (tonnes * 1000 * 9.8 =) N. + max_te /= 256; // Tractive effort is a [0-255] coefficient. if (this->gcache.cached_power != total_power || this->gcache.cached_max_te != max_te) { /* Stop the vehicle if it has no power. */ if (total_power == 0) this->vehstatus |= VS_STOPPED; diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp index 12cce41f74..66d75fb44e 100644 --- a/src/group_cmd.cpp +++ b/src/group_cmd.cpp @@ -98,7 +98,7 @@ void GroupStatistics::Clear() } /** - * Update all caches after loading a game, changing NewGRF etc.. + * Update all caches after loading a game, changing NewGRF, etc. */ /* static */ void GroupStatistics::UpdateAfterLoad() { diff --git a/src/group_gui.cpp b/src/group_gui.cpp index d3e1eafbb9..aef934ccf5 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -977,11 +977,11 @@ static inline VehicleGroupWindow *FindVehicleGroupWindow(VehicleType vt, Owner o } /** - * Opens a 'Rename group' window for newly created group - * @param success did command succeed? - * @param tile unused - * @param p1 vehicle type - * @param p2 unused + * Opens a 'Rename group' window for newly created group. + * @param result Did command succeed? + * @param tile Unused. + * @param p1 Vehicle type. + * @param p2 Unused. * @see CmdCreateGroup */ void CcCreateGroup(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) @@ -995,7 +995,7 @@ void CcCreateGroup(const CommandCost &result, TileIndex tile, uint32 p1, uint32 /** * Open rename window after adding a vehicle to a new group via drag and drop. - * @param success Did command succeed? + * @param result Did command succeed? * @param tile Unused. * @param p1 Unused. * @param p2 Bit 0-19: Vehicle ID. diff --git a/src/heightmap.cpp b/src/heightmap.cpp index 630dc69d7e..17bdbbf610 100644 --- a/src/heightmap.cpp +++ b/src/heightmap.cpp @@ -447,9 +447,9 @@ void FixSlopes() * Reads the heightmap with the correct file reader. * @param dft Type of image file. * @param filename Name of the file to load. - * @param [out] x Length of the image. - * @param [out] y Height of the image. - * @param [inout] map If not \c NULL, destination to store the loaded block of image data. + * @param[out] x Length of the image. + * @param[out] y Height of the image. + * @param[in,out] map If not \c NULL, destination to store the loaded block of image data. * @return Whether loading was successful. */ static bool ReadHeightMap(DetailedFileType dft, const char *filename, uint *x, uint *y, byte **map) diff --git a/src/hotkeys.cpp b/src/hotkeys.cpp index 870e2cbea6..12bd827fa5 100644 --- a/src/hotkeys.cpp +++ b/src/hotkeys.cpp @@ -41,6 +41,7 @@ static const KeycodeNames _keycode_to_name[] = { {"GLOBAL", WKC_GLOBAL_HOTKEY}, {"ESC", WKC_ESC}, {"DEL", WKC_DELETE}, + {"BACKSPACE", WKC_BACKSPACE}, {"RETURN", WKC_RETURN}, {"BACKQUOTE", WKC_BACKQUOTE}, {"F1", WKC_F1}, diff --git a/src/house.h b/src/house.h index ddc2a448c6..94ef62ad54 100644 --- a/src/house.h +++ b/src/house.h @@ -120,7 +120,7 @@ struct HouseSpec { AnimationInfo animation; ///< information about the animation. byte processing_time; ///< Periodic refresh multiplier byte minimum_life; ///< The minimum number of years this house will survive before the town rebuilds it - uint32 watched_cargoes; ///< Cargo types watched for acceptance. + CargoTypes watched_cargoes; ///< Cargo types watched for acceptance. Money GetRemovalCost() const; diff --git a/src/industry.h b/src/industry.h index 9b185efc4b..af0208b3cc 100644 --- a/src/industry.h +++ b/src/industry.h @@ -12,9 +12,11 @@ #ifndef INDUSTRY_H #define INDUSTRY_H +#include #include "newgrf_storage.h" #include "subsidy_type.h" #include "industry_map.h" +#include "industrytype.h" #include "tilearea_type.h" @@ -37,20 +39,20 @@ enum ProductionLevels { * Defines the internal data of a functional industry. */ struct Industry : IndustryPool::PoolItem<&_industry_pool> { - TileArea location; ///< Location of the industry - Town *town; ///< Nearest town - CargoID produced_cargo[2]; ///< 2 production cargo slots - uint16 produced_cargo_waiting[2]; ///< amount of cargo produced per cargo - uint16 incoming_cargo_waiting[3]; ///< incoming cargo waiting to be processed - byte production_rate[2]; ///< production rate for each cargo - byte prod_level; ///< general production level - CargoID accepts_cargo[3]; ///< 3 input cargo slots - uint16 this_month_production[2]; ///< stats of this month's production per cargo - uint16 this_month_transported[2]; ///< stats of this month's transport per cargo - byte last_month_pct_transported[2]; ///< percentage transported per cargo in the last full month - uint16 last_month_production[2]; ///< total units produced per cargo in the last full month - uint16 last_month_transported[2]; ///< total units transported per cargo in the last full month - uint16 counter; ///< used for animation and/or production (if available cargo) + TileArea location; ///< Location of the industry + Town *town; ///< Nearest town + CargoID produced_cargo[INDUSTRY_NUM_OUTPUTS]; ///< 16 production cargo slots + uint16 produced_cargo_waiting[INDUSTRY_NUM_OUTPUTS]; ///< amount of cargo produced per cargo + uint16 incoming_cargo_waiting[INDUSTRY_NUM_INPUTS]; ///< incoming cargo waiting to be processed + byte production_rate[INDUSTRY_NUM_OUTPUTS]; ///< production rate for each cargo + byte prod_level; ///< general production level + CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]; ///< 16 input cargo slots + uint16 this_month_production[INDUSTRY_NUM_OUTPUTS]; ///< stats of this month's production per cargo + uint16 this_month_transported[INDUSTRY_NUM_OUTPUTS]; ///< stats of this month's transport per cargo + byte last_month_pct_transported[INDUSTRY_NUM_OUTPUTS]; ///< percentage transported per cargo in the last full month + uint16 last_month_production[INDUSTRY_NUM_OUTPUTS]; ///< total units produced per cargo in the last full month + uint16 last_month_transported[INDUSTRY_NUM_OUTPUTS]; ///< total units transported per cargo in the last full month + uint16 counter; ///< used for animation and/or production (if available cargo) IndustryType type; ///< type of industry. OwnerByte owner; ///< owner of the industry. Which SHOULD always be (imho) OWNER_NONE @@ -63,7 +65,7 @@ struct Industry : IndustryPool::PoolItem<&_industry_pool> { OwnerByte founder; ///< Founder of the industry Date construction_date; ///< Date of the construction of the industry uint8 construction_type; ///< Way the industry was constructed (@see IndustryConstructionType) - Date last_cargo_accepted_at; ///< Last day cargo was accepted by this industry + Date last_cargo_accepted_at[INDUSTRY_NUM_INPUTS]; ///< Last day each cargo type was accepted by this industry byte selected_layout; ///< Which tile layout was used when creating the industry uint16 random; ///< Random value used for randomisation of all kinds of things @@ -85,6 +87,22 @@ struct Industry : IndustryPool::PoolItem<&_industry_pool> { return IsTileType(tile, MP_INDUSTRY) && GetIndustryIndex(tile) == this->index; } + inline int GetCargoProducedIndex(CargoID cargo) const + { + if (cargo == CT_INVALID) return -1; + const CargoID *pos = std::find(this->produced_cargo, endof(this->produced_cargo), cargo); + if (pos == endof(this->produced_cargo)) return -1; + return pos - this->produced_cargo; + } + + inline int GetCargoAcceptedIndex(CargoID cargo) const + { + if (cargo == CT_INVALID) return -1; + const CargoID *pos = std::find(this->accepts_cargo, endof(this->accepts_cargo), cargo); + if (pos == endof(this->accepts_cargo)) return -1; + return pos - this->accepts_cargo; + } + /** * Get the industry of the given tile * @param tile the tile to get the industry from diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 9c98b120c6..d918ef16bd 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -390,39 +390,53 @@ static Foundation GetFoundation_Industry(TileIndex tile, Slope tileh) return FlatteningFoundation(tileh); } -static void AddAcceptedCargo_Industry(TileIndex tile, CargoArray &acceptance, uint32 *always_accepted) +static void AddAcceptedCargo_Industry(TileIndex tile, CargoArray &acceptance, CargoTypes *always_accepted) { IndustryGfx gfx = GetIndustryGfx(tile); const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx); + const Industry *ind = Industry::GetByTile(tile); - /* When we have to use a callback, we put our data in the next two variables */ - CargoID raw_accepts_cargo[lengthof(itspec->accepts_cargo)]; - uint8 raw_cargo_acceptance[lengthof(itspec->acceptance)]; + /* Starting point for acceptance */ + CargoID accepts_cargo[lengthof(itspec->accepts_cargo)]; + int8 cargo_acceptance[lengthof(itspec->acceptance)]; + MemCpyT(accepts_cargo, itspec->accepts_cargo, lengthof(accepts_cargo)); + MemCpyT(cargo_acceptance, itspec->acceptance, lengthof(cargo_acceptance)); - /* And then these will always point to a same sized array with the required data */ - const CargoID *accepts_cargo = itspec->accepts_cargo; - const uint8 *cargo_acceptance = itspec->acceptance; + if (itspec->special_flags & INDTILE_SPECIAL_ACCEPTS_ALL_CARGO) { + /* Copy all accepted cargoes from industry itself */ + for (uint i = 0; i < lengthof(ind->accepts_cargo); i++) { + CargoID *pos = std::find(accepts_cargo, endof(accepts_cargo), ind->accepts_cargo[i]); + if (pos == endof(accepts_cargo)) { + /* Not found, insert */ + pos = std::find(accepts_cargo, endof(accepts_cargo), CT_INVALID); + if (pos == endof(accepts_cargo)) continue; // nowhere to place, give up on this one + *pos = ind->accepts_cargo[i]; + } + cargo_acceptance[pos - accepts_cargo] += 8; + } + } if (HasBit(itspec->callback_mask, CBM_INDT_ACCEPT_CARGO)) { + /* Try callback for accepts list, if success override all existing accepts */ uint16 res = GetIndustryTileCallback(CBID_INDTILE_ACCEPT_CARGO, 0, 0, gfx, Industry::GetByTile(tile), tile); if (res != CALLBACK_FAILED) { - accepts_cargo = raw_accepts_cargo; - for (uint i = 0; i < lengthof(itspec->accepts_cargo); i++) raw_accepts_cargo[i] = GetCargoTranslation(GB(res, i * 5, 5), itspec->grf_prop.grffile); + MemSetT(accepts_cargo, CT_INVALID, lengthof(accepts_cargo)); + for (uint i = 0; i < 3; i++) accepts_cargo[i] = GetCargoTranslation(GB(res, i * 5, 5), itspec->grf_prop.grffile); } } if (HasBit(itspec->callback_mask, CBM_INDT_CARGO_ACCEPTANCE)) { + /* Try callback for acceptance list, if success override all existing acceptance */ uint16 res = GetIndustryTileCallback(CBID_INDTILE_CARGO_ACCEPTANCE, 0, 0, gfx, Industry::GetByTile(tile), tile); if (res != CALLBACK_FAILED) { - cargo_acceptance = raw_cargo_acceptance; - for (uint i = 0; i < lengthof(itspec->accepts_cargo); i++) raw_cargo_acceptance[i] = GB(res, i * 4, 4); + MemSetT(cargo_acceptance, 0, lengthof(cargo_acceptance)); + for (uint i = 0; i < 3; i++) cargo_acceptance[i] = GB(res, i * 4, 4); } } - const Industry *ind = Industry::GetByTile(tile); for (byte i = 0; i < lengthof(itspec->accepts_cargo); i++) { CargoID a = accepts_cargo[i]; - if (a == CT_INVALID || cargo_acceptance[i] == 0) continue; // work only with valid cargoes + if (a == CT_INVALID || cargo_acceptance[i] <= 0) continue; // work only with valid cargoes /* Add accepted cargo */ acceptance[a] += cargo_acceptance[i]; @@ -1118,8 +1132,9 @@ static void ProduceIndustryGoods(Industry *i) if (HasBit(indsp->callback_mask, CBM_IND_PRODUCTION_256_TICKS)) IndustryProductionCallback(i, 1); IndustryBehaviour indbehav = indsp->behaviour; - i->produced_cargo_waiting[0] = min(0xffff, i->produced_cargo_waiting[0] + i->production_rate[0]); - i->produced_cargo_waiting[1] = min(0xffff, i->produced_cargo_waiting[1] + i->production_rate[1]); + for (size_t j = 0; j < lengthof(i->produced_cargo_waiting); j++) { + i->produced_cargo_waiting[j] = min(0xffff, i->produced_cargo_waiting[j] + i->production_rate[j]); + } if ((indbehav & INDUSTRYBEH_PLANT_FIELDS) != 0) { uint16 cb_res = CALLBACK_FAILED; @@ -1323,7 +1338,7 @@ static CheckNewIndustryProc * const _check_new_industry_procs[CHECK_END] = { * Find a town for the industry, while checking for multiple industries in the same town. * @param tile Position of the industry to build. * @param type Industry type. - * @param [out] town Pointer to return town for the new industry, \c NULL is written if no good town can be found. + * @param[out] t Pointer to return town for the new industry, \c NULL is written if no good town can be found. * @return Succeeded or failed command. * * @pre \c *t != NULL @@ -1365,14 +1380,14 @@ bool IsSlopeRefused(Slope current, Slope refused) /** * Are the tiles of the industry free? - * @param tile Position to check. - * @param it Industry tiles table. - * @param itspec_index The index of the itsepc to build/fund - * @param type Type of the industry. - * @param initial_random_bits The random bits the industry is going to have after construction. - * @param founder Industry founder - * @param creation_type The circumstances the industry is created under. - * @param [out] custom_shape_check Perform custom check for the site. + * @param tile Position to check. + * @param it Industry tiles table. + * @param itspec_index The index of the itsepc to build/fund + * @param type Type of the industry. + * @param initial_random_bits The random bits the industry is going to have after construction. + * @param founder Industry founder + * @param creation_type The circumstances the industry is created under. + * @param[out] custom_shape_check Perform custom check for the site. * @return Failed or succeeded command. */ static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileTable *it, uint itspec_index, int type, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type, bool *custom_shape_check = NULL) @@ -1648,18 +1663,23 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, i->type = type; Industry::IncIndustryTypeCount(type); - i->produced_cargo[0] = indspec->produced_cargo[0]; - i->produced_cargo[1] = indspec->produced_cargo[1]; - i->accepts_cargo[0] = indspec->accepts_cargo[0]; - i->accepts_cargo[1] = indspec->accepts_cargo[1]; - i->accepts_cargo[2] = indspec->accepts_cargo[2]; - i->production_rate[0] = indspec->production_rate[0]; - i->production_rate[1] = indspec->production_rate[1]; + MemCpyT(i->produced_cargo, indspec->produced_cargo, lengthof(i->produced_cargo)); + MemCpyT(i->production_rate, indspec->production_rate, lengthof(i->production_rate)); + MemCpyT(i->accepts_cargo, indspec->accepts_cargo, lengthof(i->accepts_cargo)); + + MemSetT(i->produced_cargo_waiting, 0, lengthof(i->produced_cargo_waiting)); + MemSetT(i->this_month_production, 0, lengthof(i->this_month_production)); + MemSetT(i->this_month_transported, 0, lengthof(i->this_month_transported)); + MemSetT(i->last_month_pct_transported, 0, lengthof(i->last_month_pct_transported)); + MemSetT(i->last_month_transported, 0, lengthof(i->last_month_transported)); + MemSetT(i->incoming_cargo_waiting, 0, lengthof(i->incoming_cargo_waiting)); + MemSetT(i->last_cargo_accepted_at, 0, lengthof(i->last_cargo_accepted_at)); /* don't use smooth economy for industries using production related callbacks */ if (indspec->UsesSmoothEconomy()) { - i->production_rate[0] = min((RandomRange(256) + 128) * i->production_rate[0] >> 8, 255); - i->production_rate[1] = min((RandomRange(256) + 128) * i->production_rate[1] >> 8, 255); + for (size_t ci = 0; ci < lengthof(i->production_rate); ci++) { + i->production_rate[ci] = min((RandomRange(256) + 128) * i->production_rate[ci] >> 8, 255); + } } i->town = t; @@ -1669,19 +1689,6 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, i->random_colour = GB(r, 0, 4); i->counter = GB(r, 4, 12); i->random = initial_random_bits; - i->produced_cargo_waiting[0] = 0; - i->produced_cargo_waiting[1] = 0; - i->incoming_cargo_waiting[0] = 0; - i->incoming_cargo_waiting[1] = 0; - i->incoming_cargo_waiting[2] = 0; - i->this_month_production[0] = 0; - i->this_month_production[1] = 0; - i->this_month_transported[0] = 0; - i->this_month_transported[1] = 0; - i->last_month_pct_transported[0] = 0; - i->last_month_pct_transported[1] = 0; - i->last_month_transported[0] = 0; - i->last_month_transported[1] = 0; i->was_cargo_delivered = false; i->last_prod_year = _cur_year; i->founder = founder; @@ -1712,10 +1719,9 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, } if (_generating_world) { - i->last_month_production[0] = i->production_rate[0] * 8; - i->last_month_production[1] = i->production_rate[1] * 8; - } else { - i->last_month_production[0] = i->last_month_production[1] = 0; + for (size_t ci = 0; ci < lengthof(i->last_month_production); ci++) { + i->last_month_production[ci] = i->production_rate[ci] * 8; + } } if (HasBit(indspec->callback_mask, CBM_IND_DECIDE_COLOUR)) { @@ -1727,28 +1733,56 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, } if (HasBit(indspec->callback_mask, CBM_IND_INPUT_CARGO_TYPES)) { + /* Clear all input cargo types */ for (uint j = 0; j < lengthof(i->accepts_cargo); j++) i->accepts_cargo[j] = CT_INVALID; - for (uint j = 0; j < lengthof(i->accepts_cargo); j++) { + /* Query actual types */ + uint maxcargoes = (indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED) ? lengthof(i->accepts_cargo) : 3; + for (uint j = 0; j < maxcargoes; j++) { uint16 res = GetIndustryCallback(CBID_INDUSTRY_INPUT_CARGO_TYPES, j, 0, i, type, INVALID_TILE); if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break; if (indspec->grf_prop.grffile->grf_version >= 8 && res >= 0x100) { ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_INPUT_CARGO_TYPES, res); break; } - i->accepts_cargo[j] = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile); + CargoID cargo = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile); + if (std::find(indspec->accepts_cargo, endof(indspec->accepts_cargo), cargo) == endof(indspec->accepts_cargo)) { + /* Cargo not in spec, error in NewGRF */ + ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_INPUT_CARGO_TYPES, res); + break; + } + if (std::find(i->accepts_cargo, i->accepts_cargo + j, cargo) != i->accepts_cargo + j) { + /* Duplicate cargo */ + ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_INPUT_CARGO_TYPES, res); + break; + } + i->accepts_cargo[j] = cargo; } } if (HasBit(indspec->callback_mask, CBM_IND_OUTPUT_CARGO_TYPES)) { + /* Clear all output cargo types */ for (uint j = 0; j < lengthof(i->produced_cargo); j++) i->produced_cargo[j] = CT_INVALID; - for (uint j = 0; j < lengthof(i->produced_cargo); j++) { + /* Query actual types */ + uint maxcargoes = (indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED) ? lengthof(i->produced_cargo) : 2; + for (uint j = 0; j < maxcargoes; j++) { uint16 res = GetIndustryCallback(CBID_INDUSTRY_OUTPUT_CARGO_TYPES, j, 0, i, type, INVALID_TILE); if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break; if (indspec->grf_prop.grffile->grf_version >= 8 && res >= 0x100) { ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_OUTPUT_CARGO_TYPES, res); break; } - i->produced_cargo[j] = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile); + CargoID cargo = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile); + if (std::find(indspec->produced_cargo, endof(indspec->produced_cargo), cargo) == endof(indspec->produced_cargo)) { + /* Cargo not in spec, error in NewGRF */ + ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_OUTPUT_CARGO_TYPES, res); + break; + } + if (std::find(i->produced_cargo, i->produced_cargo + j, cargo) != i->produced_cargo + j) { + /* Duplicate cargo */ + ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_OUTPUT_CARGO_TYPES, res); + break; + } + i->produced_cargo[j] = cargo; } } @@ -1793,11 +1827,11 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, * @param flags of operations to conduct * @param indspec pointer to industry specifications * @param itspec_index the index of the itsepc to build/fund - * @param seed random seed (possibly) used by industries - * @param initial_random_bits The random bits the industry is going to have after construction. + * @param random_var8f random seed (possibly) used by industries + * @param random_initial_bits The random bits the industry is going to have after construction. * @param founder Founder of the industry * @param creation_type The circumstances the industry is created under. - * @param [out] ip Pointer to store newly created industry. + * @param[out] ip Pointer to store newly created industry. * @return Succeeded or failed command. * * @post \c *ip contains the newly created industry if all checks are successful and the \a flags request actual creation, else it contains \c NULL afterwards. @@ -1961,7 +1995,7 @@ static Industry *CreateNewIndustry(TileIndex tile, IndustryType type, IndustryAv /** * Compute the appearance probability for an industry during map creation. * @param it Industry type to compute. - * @param [out] force_at_least_one Returns whether at least one instance should be forced on map creation. + * @param[out] force_at_least_one Returns whether at least one instance should be forced on map creation. * @return Relative probability for the industry to appear. */ static uint32 GetScaledIndustryGenerationProbability(IndustryType it, bool *force_at_least_one) @@ -1986,7 +2020,7 @@ static uint32 GetScaledIndustryGenerationProbability(IndustryType it, bool *forc /** * Compute the probability for constructing a new industry during game play. * @param it Industry type to compute. - * @param [out] min_number Minimal number of industries that should exist at the map. + * @param[out] min_number Minimal number of industries that should exist at the map. * @return Relative probability for the industry to appear. */ static uint16 GetIndustryGamePlayProbability(IndustryType it, byte *min_number) @@ -2194,8 +2228,9 @@ void Industry::RecomputeProductionMultipliers() assert(!indspec->UsesSmoothEconomy()); /* Rates are rounded up, so e.g. oilrig always produces some passengers */ - this->production_rate[0] = min(CeilDiv(indspec->production_rate[0] * this->prod_level, PRODLEVEL_DEFAULT), 0xFF); - this->production_rate[1] = min(CeilDiv(indspec->production_rate[1] * this->prod_level, PRODLEVEL_DEFAULT), 0xFF); + for (size_t i = 0; i < lengthof(this->production_rate); i++) { + this->production_rate[i] = min(CeilDiv(indspec->production_rate[i] * this->prod_level, PRODLEVEL_DEFAULT), 0xFF); + } } diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 2e06983af0..98c9edda21 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -74,12 +74,7 @@ static void ShowIndustryCargoesWindow(IndustryType id); /** * Gets the string to display after the cargo name (using callback 37) - * @param cargo the cargo for which the suffix is requested - * - 00 - first accepted cargo type - * - 01 - second accepted cargo type - * - 02 - third accepted cargo type - * - 03 - first produced cargo type - * - 04 - second produced cargo type + * @param cargo the cargo for which the suffix is requested, meaning depends on presence of flag 18 in prop 1A * @param cst the cargo suffix type (for which window is it requested). @see CargoSuffixType * @param ind the industry (NULL if in fund window) * @param ind_type the industry type @@ -134,9 +129,14 @@ static void GetCargoSuffix(uint cargo, CargoSuffixType cst, const Industry *ind, } } +enum CargoSuffixInOut { + CARGOSUFFIX_OUT = 0, + CARGOSUFFIX_IN = 1, +}; + /** * Gets all strings to display after the cargoes of industries (using callback 37) - * @param cb_offset The offset for the cargo used in cb37, 0 for accepted cargoes, 3 for produced cargoes + * @param use_input get suffixes for output cargoes or input cargoes? * @param cst the cargo suffix type (for which window is it requested). @see CargoSuffixType * @param ind the industry (NULL if in fund window) * @param ind_type the industry type @@ -145,14 +145,40 @@ static void GetCargoSuffix(uint cargo, CargoSuffixType cst, const Industry *ind, * @param suffixes is filled with the suffixes */ template -static inline void GetAllCargoSuffixes(uint cb_offset, CargoSuffixType cst, const Industry *ind, IndustryType ind_type, const IndustrySpec *indspec, const TC &cargoes, TS &suffixes) +static inline void GetAllCargoSuffixes(CargoSuffixInOut use_input, CargoSuffixType cst, const Industry *ind, IndustryType ind_type, const IndustrySpec *indspec, const TC &cargoes, TS &suffixes) { assert_compile(lengthof(cargoes) <= lengthof(suffixes)); - for (uint j = 0; j < lengthof(cargoes); j++) { - if (cargoes[j] != CT_INVALID) { - GetCargoSuffix(cb_offset + j, cst, ind, ind_type, indspec, suffixes[j]); - } else { + + if (indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED) { + /* Reworked behaviour with new many-in-many-out scheme */ + for (uint j = 0; j < lengthof(suffixes); j++) { + if (cargoes[j] != CT_INVALID) { + byte local_id = indspec->grf_prop.grffile->cargo_map[cargoes[j]]; // should we check the value for valid? + uint cargotype = local_id << 16 | use_input; + GetCargoSuffix(cargotype, cst, ind, ind_type, indspec, suffixes[j]); + } else { + suffixes[j].text[0] = '\0'; + suffixes[j].display = CSD_CARGO; + } + } + } else { + /* Compatible behaviour with old 3-in-2-out scheme */ + for (uint j = 0; j < lengthof(suffixes); j++) { suffixes[j].text[0] = '\0'; + suffixes[j].display = CSD_CARGO; + } + switch (use_input) { + case CARGOSUFFIX_OUT: + if (cargoes[0] != CT_INVALID) GetCargoSuffix(3, cst, ind, ind_type, indspec, suffixes[0]); + if (cargoes[1] != CT_INVALID) GetCargoSuffix(4, cst, ind, ind_type, indspec, suffixes[1]); + break; + case CARGOSUFFIX_IN: + if (cargoes[0] != CT_INVALID) GetCargoSuffix(0, cst, ind, ind_type, indspec, suffixes[0]); + if (cargoes[1] != CT_INVALID) GetCargoSuffix(1, cst, ind, ind_type, indspec, suffixes[1]); + if (cargoes[2] != CT_INVALID) GetCargoSuffix(2, cst, ind, ind_type, indspec, suffixes[2]); + break; + default: + NOT_REACHED(); } } } @@ -358,8 +384,8 @@ public: const IndustrySpec *indsp = GetIndustrySpec(this->index[i]); - CargoSuffix cargo_suffix[3]; - GetAllCargoSuffixes(0, CST_FUND, NULL, this->index[i], indsp, indsp->accepts_cargo, cargo_suffix); + CargoSuffix cargo_suffix[lengthof(indsp->accepts_cargo)]; + GetAllCargoSuffixes(CARGOSUFFIX_IN, CST_FUND, NULL, this->index[i], indsp, indsp->accepts_cargo, cargo_suffix); StringID str = STR_INDUSTRY_VIEW_REQUIRES_CARGO; byte p = 0; SetDParam(0, STR_JUST_NOTHING); @@ -373,7 +399,7 @@ public: d = maxdim(d, GetStringBoundingBox(str)); /* Draw the produced cargoes, if any. Otherwise, will print "Nothing". */ - GetAllCargoSuffixes(3, CST_FUND, NULL, this->index[i], indsp, indsp->produced_cargo, cargo_suffix); + GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_FUND, NULL, this->index[i], indsp, indsp->produced_cargo, cargo_suffix); str = STR_INDUSTRY_VIEW_PRODUCES_CARGO; p = 0; SetDParam(0, STR_JUST_NOTHING); @@ -477,8 +503,8 @@ public: } /* Draw the accepted cargoes, if any. Otherwise, will print "Nothing". */ - CargoSuffix cargo_suffix[3]; - GetAllCargoSuffixes(0, CST_FUND, NULL, this->selected_type, indsp, indsp->accepts_cargo, cargo_suffix); + CargoSuffix cargo_suffix[lengthof(indsp->accepts_cargo)]; + GetAllCargoSuffixes(CARGOSUFFIX_IN, CST_FUND, NULL, this->selected_type, indsp, indsp->accepts_cargo, cargo_suffix); StringID str = STR_INDUSTRY_VIEW_REQUIRES_CARGO; byte p = 0; SetDParam(0, STR_JUST_NOTHING); @@ -493,7 +519,7 @@ public: y += FONT_HEIGHT_NORMAL; /* Draw the produced cargoes, if any. Otherwise, will print "Nothing". */ - GetAllCargoSuffixes(3, CST_FUND, NULL, this->selected_type, indsp, indsp->produced_cargo, cargo_suffix); + GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_FUND, NULL, this->selected_type, indsp, indsp->produced_cargo, cargo_suffix); str = STR_INDUSTRY_VIEW_PRODUCES_CARGO; p = 0; SetDParam(0, STR_JUST_NOTHING); @@ -508,7 +534,6 @@ public: y += FONT_HEIGHT_NORMAL; /* Get the additional purchase info text, if it has not already been queried. */ - str = STR_NULL; if (HasBit(indsp->callback_mask, CBM_IND_FUND_MORE_TEXT)) { uint16 callback_res = GetIndustryCallback(CBID_INDUSTRY_FUND_MORE_TEXT, 0, 0, NULL, this->selected_type, INVALID_TILE); if (callback_res != CALLBACK_FAILED && callback_res != 0x400) { @@ -684,8 +709,15 @@ static void UpdateIndustryProduction(Industry *i); static inline bool IsProductionAlterable(const Industry *i) { const IndustrySpec *is = GetIndustrySpec(i->type); + bool has_prod = false; + for (size_t j = 0; j < lengthof(is->production_rate); j++) { + if (is->production_rate[j] != 0) { + has_prod = true; + break; + } + } return ((_game_mode == GM_EDITOR || _cheats.setup_prod.value) && - (is->production_rate[0] != 0 || is->production_rate[1] != 0 || is->IsRawIndustry()) && + (has_prod || is->IsRawIndustry()) && !_networking); } @@ -764,8 +796,8 @@ public: y += 2 * FONT_HEIGHT_NORMAL; } - CargoSuffix cargo_suffix[3]; - GetAllCargoSuffixes(0, CST_VIEW, i, i->type, ind, i->accepts_cargo, cargo_suffix); + CargoSuffix cargo_suffix[lengthof(i->accepts_cargo)]; + GetAllCargoSuffixes(CARGOSUFFIX_IN, CST_VIEW, i, i->type, ind, i->accepts_cargo, cargo_suffix); bool stockpiling = HasBit(ind->callback_mask, CBM_IND_PRODUCTION_CARGO_ARRIVAL) || HasBit(ind->callback_mask, CBM_IND_PRODUCTION_256_TICKS); uint left_side = left + WD_FRAMERECT_LEFT * 4; // Indent accepted cargoes. @@ -804,7 +836,7 @@ public: y += FONT_HEIGHT_NORMAL; } - GetAllCargoSuffixes(3, CST_VIEW, i, i->type, ind, i->produced_cargo, cargo_suffix); + GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_VIEW, i, i->type, ind, i->produced_cargo, cargo_suffix); first = true; for (byte j = 0; j < lengthof(i->produced_cargo); j++) { if (i->produced_cargo[j] == CT_INVALID) continue; @@ -1256,7 +1288,7 @@ protected: SetDParam(p++, i->index); static CargoSuffix cargo_suffix[lengthof(i->produced_cargo)]; - GetAllCargoSuffixes(3, CST_DIR, i, i->type, indsp, i->produced_cargo, cargo_suffix); + GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_DIR, i, i->type, indsp, i->produced_cargo, cargo_suffix); /* Industry productions */ for (byte j = 0; j < lengthof(i->produced_cargo); j++) { @@ -1515,7 +1547,7 @@ enum CargoesFieldType { CFT_HEADER, ///< Header text. }; -static const uint MAX_CARGOES = 3; ///< Maximum number of cargoes carried in a #CFT_CARGO field in #CargoesField. +static const uint MAX_CARGOES = 16; ///< Maximum number of cargoes carried in a #CFT_CARGO field in #CargoesField. /** Data about a single field in the #IndustryCargoesWindow panel. */ struct CargoesField { @@ -1523,7 +1555,6 @@ struct CargoesField { static const int HOR_CARGO_BORDER_SPACE; static const int CARGO_STUB_WIDTH; static const int HOR_CARGO_WIDTH, HOR_CARGO_SPACE; - static const int CARGO_FIELD_WIDTH; static const int VERT_CARGO_SPACE, VERT_CARGO_EDGE; static const int BLOB_DISTANCE, BLOB_WIDTH, BLOB_HEIGHT; @@ -1531,7 +1562,9 @@ struct CargoesField { static const int CARGO_LINE_COLOUR; static int small_height, normal_height; + static int cargo_field_width; static int industry_width; + static uint max_cargoes; CargoesFieldType type; ///< Type of field. union { @@ -1580,7 +1613,7 @@ struct CargoesField { /** * Connect a cargo from an industry to the #CFT_CARGO column. * @param cargo Cargo to connect. - * @param produced Cargo is produced (if \c false, cargo is assumed to be accepted). + * @param producer Cargo is produced (if \c false, cargo is assumed to be accepted). * @return Horizontal connection index, or \c -1 if not accepted at all. */ int ConnectCargo(CargoID cargo, bool producer) @@ -1684,20 +1717,19 @@ struct CargoesField { int GetCargoBase(int xpos) const { assert(this->type == CFT_CARGO); + int n = this->u.cargo.num_cargoes; - switch (this->u.cargo.num_cargoes) { - case 0: return xpos + CARGO_FIELD_WIDTH / 2; - case 1: return xpos + CARGO_FIELD_WIDTH / 2 - HOR_CARGO_WIDTH / 2; - case 2: return xpos + CARGO_FIELD_WIDTH / 2 - HOR_CARGO_WIDTH - HOR_CARGO_SPACE / 2; - case 3: return xpos + CARGO_FIELD_WIDTH / 2 - HOR_CARGO_WIDTH - HOR_CARGO_SPACE - HOR_CARGO_WIDTH / 2; - default: NOT_REACHED(); + if (n % 2 == 0) { + return xpos + cargo_field_width / 2 - (HOR_CARGO_WIDTH + HOR_CARGO_SPACE / 2) * (n / 2); + } else { + return xpos + cargo_field_width / 2 - HOR_CARGO_WIDTH / 2 - (HOR_CARGO_WIDTH + HOR_CARGO_SPACE) * (n / 2); } } /** * Draw the field. * @param xpos Position of the left edge. - * @param vpos Position of the top edge. + * @param ypos Position of the top edge. */ void Draw(int xpos, int ypos) const { @@ -1749,7 +1781,7 @@ struct CargoesField { other_left = this->u.industry.other_accepted; } ypos1 += VERT_CARGO_EDGE; - for (uint i = 0; i < MAX_CARGOES; i++) { + for (uint i = 0; i < CargoesField::max_cargoes; i++) { if (other_right[i] != INVALID_CARGO) { const CargoSpec *csp = CargoSpec::Get(other_right[i]); int xp = xpos + industry_width + CARGO_STUB_WIDTH; @@ -1814,7 +1846,7 @@ struct CargoesField { DrawHorConnection(lf + dx - 1, lf + HOR_CARGO_SPACE - 1, ypos, csp); dx = 1; } - DrawHorConnection(cargo_base + col * HOR_CARGO_SPACE + (col + 1) * HOR_CARGO_WIDTH - 1 + dx, xpos + CARGO_FIELD_WIDTH - 1, ypos, csp); + DrawHorConnection(cargo_base + col * HOR_CARGO_SPACE + (col + 1) * HOR_CARGO_WIDTH - 1 + dx, xpos + CargoesField::cargo_field_width - 1, ypos, csp); } ypos += FONT_HEIGHT_NORMAL + VERT_CARGO_SPACE; } @@ -1936,9 +1968,11 @@ private: assert_compile(MAX_CARGOES >= cpp_lengthof(IndustrySpec, produced_cargo)); assert_compile(MAX_CARGOES >= cpp_lengthof(IndustrySpec, accepts_cargo)); -int CargoesField::small_height; ///< Height of the header row. -int CargoesField::normal_height; ///< Height of the non-header rows. -int CargoesField::industry_width; ///< Width of an industry field. +int CargoesField::small_height; ///< Height of the header row. +int CargoesField::normal_height; ///< Height of the non-header rows. +int CargoesField::industry_width; ///< Width of an industry field. +int CargoesField::cargo_field_width; ///< Width of a cargo field. +uint CargoesField::max_cargoes; ///< Largest number of cargoes actually on any industry. const int CargoesField::VERT_INTER_INDUSTRY_SPACE = 6; ///< Amount of space between two industries in a column. const int CargoesField::HOR_CARGO_BORDER_SPACE = 15; ///< Amount of space between the left/right edge of a #CFT_CARGO field, and the left/right most vertical cargo. @@ -1952,9 +1986,6 @@ const int CargoesField::BLOB_DISTANCE = 5; ///< Distance of the industry legend const int CargoesField::BLOB_WIDTH = 12; ///< Width of the industry legend colour, including border. const int CargoesField::BLOB_HEIGHT = 9; ///< Height of the industry legend colour, including border -/** Width of a #CFT_CARGO field. */ -const int CargoesField::CARGO_FIELD_WIDTH = HOR_CARGO_BORDER_SPACE * 2 + HOR_CARGO_WIDTH * MAX_CARGOES + HOR_CARGO_SPACE * (MAX_CARGOES - 1); - const int CargoesField::INDUSTRY_LINE_COLOUR = PC_YELLOW; ///< Line colour of the industry type box. const int CargoesField::CARGO_LINE_COLOUR = PC_YELLOW; ///< Line colour around the cargo. @@ -1979,13 +2010,14 @@ struct CargoesRow { int other_count = 0; const IndustrySpec *indsp = GetIndustrySpec(ind_fld->u.industry.ind_type); - for (uint i = 0; i < lengthof(indsp->produced_cargo); i++) { + assert(CargoesField::max_cargoes <= lengthof(indsp->produced_cargo)); + for (uint i = 0; i < CargoesField::max_cargoes; i++) { int col = cargo_fld->ConnectCargo(indsp->produced_cargo[i], true); if (col < 0) others[other_count++] = indsp->produced_cargo[i]; } /* Allocate other cargoes in the empty holes of the horizontal cargo connections. */ - for (uint i = 0; i < MAX_CARGOES && other_count > 0; i++) { + for (uint i = 0; i < CargoesField::max_cargoes && other_count > 0; i++) { if (cargo_fld->u.cargo.supp_cargoes[i] == INVALID_CARGO) ind_fld->u.industry.other_produced[i] = others[--other_count]; } } else { @@ -2036,13 +2068,14 @@ struct CargoesRow { int other_count = 0; const IndustrySpec *indsp = GetIndustrySpec(ind_fld->u.industry.ind_type); - for (uint i = 0; i < lengthof(indsp->accepts_cargo); i++) { + assert(CargoesField::max_cargoes <= lengthof(indsp->accepts_cargo)); + for (uint i = 0; i < CargoesField::max_cargoes; i++) { int col = cargo_fld->ConnectCargo(indsp->accepts_cargo[i], false); if (col < 0) others[other_count++] = indsp->accepts_cargo[i]; } /* Allocate other cargoes in the empty holes of the horizontal cargo connections. */ - for (uint i = 0; i < MAX_CARGOES && other_count > 0; i++) { + for (uint i = 0; i < CargoesField::max_cargoes && other_count > 0; i++) { if (cargo_fld->u.cargo.cust_cargoes[i] == INVALID_CARGO) ind_fld->u.industry.other_accepted[i] = others[--other_count]; } } else { @@ -2125,10 +2158,13 @@ struct IndustryCargoesWindow : public Window { /* Decide about the size of the box holding the text of an industry type. */ this->ind_textsize.width = 0; this->ind_textsize.height = 0; + CargoesField::max_cargoes = 0; for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) { const IndustrySpec *indsp = GetIndustrySpec(it); if (!indsp->enabled) continue; this->ind_textsize = maxdim(this->ind_textsize, GetStringBoundingBox(indsp->name)); + CargoesField::max_cargoes = max(CargoesField::max_cargoes, std::count_if(indsp->accepts_cargo, endof(indsp->accepts_cargo), IsCargoIDValid)); + CargoesField::max_cargoes = max(CargoesField::max_cargoes, std::count_if(indsp->produced_cargo, endof(indsp->produced_cargo), IsCargoIDValid)); } d.width = max(d.width, this->ind_textsize.width); d.height = this->ind_textsize.height; @@ -2147,18 +2183,21 @@ struct IndustryCargoesWindow : public Window { d.width += 2 * HOR_TEXT_PADDING; /* Ensure the height is enough for the industry type text, for the horizontal connections, and for the cargo labels. */ - uint min_ind_height = CargoesField::VERT_CARGO_EDGE * 2 + MAX_CARGOES * FONT_HEIGHT_NORMAL + (MAX_CARGOES - 1) * CargoesField::VERT_CARGO_SPACE; + uint min_ind_height = CargoesField::VERT_CARGO_EDGE * 2 + CargoesField::max_cargoes * FONT_HEIGHT_NORMAL + (CargoesField::max_cargoes - 1) * CargoesField::VERT_CARGO_SPACE; d.height = max(d.height + 2 * VERT_TEXT_PADDING, min_ind_height); CargoesField::industry_width = d.width; CargoesField::normal_height = d.height + CargoesField::VERT_INTER_INDUSTRY_SPACE; + + /* Width of a #CFT_CARGO field. */ + CargoesField::cargo_field_width = CargoesField::HOR_CARGO_BORDER_SPACE * 2 + CargoesField::HOR_CARGO_WIDTH * CargoesField::max_cargoes + CargoesField::HOR_CARGO_SPACE * (CargoesField::max_cargoes - 1); } virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) { switch (widget) { case WID_IC_PANEL: - size->width = WD_FRAMETEXT_LEFT + CargoesField::industry_width * 3 + CargoesField::CARGO_FIELD_WIDTH * 2 + WD_FRAMETEXT_RIGHT; + size->width = WD_FRAMETEXT_LEFT + CargoesField::industry_width * 3 + CargoesField::cargo_field_width * 2 + WD_FRAMETEXT_RIGHT; break; case WID_IC_IND_DROPDOWN: @@ -2519,7 +2558,7 @@ struct IndustryCargoesWindow : public Window { _cur_dpi = &tmp_dpi; int left_pos = WD_FRAMERECT_LEFT; - if (this->ind_cargo >= NUM_INDUSTRYTYPES) left_pos += (CargoesField::industry_width + CargoesField::CARGO_FIELD_WIDTH) / 2; + if (this->ind_cargo >= NUM_INDUSTRYTYPES) left_pos += (CargoesField::industry_width + CargoesField::cargo_field_width) / 2; int last_column = (this->ind_cargo < NUM_INDUSTRYTYPES) ? 4 : 2; const NWidgetBase *nwp = this->GetWidget(WID_IC_PANEL); @@ -2538,7 +2577,7 @@ struct IndustryCargoesWindow : public Window { } while (col >= 0 && col <= last_column) { this->fields[i].columns[col].Draw(xpos, vpos); - xpos += (col & 1) ? CargoesField::CARGO_FIELD_WIDTH : CargoesField::industry_width; + xpos += (col & 1) ? CargoesField::cargo_field_width : CargoesField::industry_width; col += dir; } } @@ -2570,11 +2609,11 @@ struct IndustryCargoesWindow : public Window { vpos = pt.y - vpos - row * CargoesField::normal_height; // Position in the row + 1 field row++; // rebase row to match index of this->fields. - int xpos = 2 * WD_FRAMERECT_LEFT + ((this->ind_cargo < NUM_INDUSTRYTYPES) ? 0 : (CargoesField::industry_width + CargoesField::CARGO_FIELD_WIDTH) / 2); + int xpos = 2 * WD_FRAMERECT_LEFT + ((this->ind_cargo < NUM_INDUSTRYTYPES) ? 0 : (CargoesField::industry_width + CargoesField::cargo_field_width) / 2); if (pt.x < xpos) return false; int column; for (column = 0; column <= 5; column++) { - int width = (column & 1) ? CargoesField::CARGO_FIELD_WIDTH : CargoesField::industry_width; + int width = (column & 1) ? CargoesField::cargo_field_width : CargoesField::industry_width; if (pt.x < xpos + width) break; xpos += width; } @@ -2587,7 +2626,7 @@ struct IndustryCargoesWindow : public Window { xy->y = vpos; if (_current_text_dir == TD_RTL) { fieldxy->x = num_columns - column; - xy->x = ((column & 1) ? CargoesField::CARGO_FIELD_WIDTH : CargoesField::industry_width) - xpos; + xy->x = ((column & 1) ? CargoesField::cargo_field_width : CargoesField::industry_width) - xpos; } else { fieldxy->x = column; xy->x = xpos; diff --git a/src/industry_type.h b/src/industry_type.h index 6234f7b114..9a8a469017 100644 --- a/src/industry_type.h +++ b/src/industry_type.h @@ -37,6 +37,10 @@ static const IndustryGfx INVALID_INDUSTRYTILE = NUM_INDUSTRYTILES; ///< one a static const int INDUSTRY_COMPLETED = 3; ///< final stage of industry construction. +static const int INDUSTRY_NUM_INPUTS = 16; ///< Number of cargo types an industry can accept +static const int INDUSTRY_NUM_OUTPUTS = 16; ///< Number of cargo types an industry can produce + + void CheckIndustries(); #endif /* INDUSTRY_TYPE_H */ diff --git a/src/industrytype.h b/src/industrytype.h index 03b6c79736..cd451fa777 100644 --- a/src/industrytype.h +++ b/src/industrytype.h @@ -80,6 +80,7 @@ enum IndustryBehaviour { INDUSTRYBEH_PRODCALLBACK_RANDOM = 1 << 15, ///< Production callback needs random bits in var 10 INDUSTRYBEH_NOBUILT_MAPCREATION = 1 << 16, ///< Do not force one instance of this type to appear on map generation INDUSTRYBEH_CANCLOSE_LASTINSTANCE = 1 << 17, ///< Allow closing down the last instance of this type + INDUSTRYBEH_CARGOTYPES_UNLIMITED = 1 << 18, ///< Allow produced/accepted cargoes callbacks to supply more than 2 and 3 types }; DECLARE_ENUM_AS_BIT_SET(IndustryBehaviour) @@ -87,6 +88,7 @@ DECLARE_ENUM_AS_BIT_SET(IndustryBehaviour) enum IndustryTileSpecialFlags { INDTILE_SPECIAL_NONE = 0, INDTILE_SPECIAL_NEXTFRAME_RANDOMBITS = 1 << 0, ///< Callback 0x26 needs random bits + INDTILE_SPECIAL_ACCEPTS_ALL_CARGO = 1 << 1, ///< Tile always accepts all cargoes the associated industry accepts }; DECLARE_ENUM_AS_BIT_SET(IndustryTileSpecialFlags) @@ -99,41 +101,41 @@ struct IndustryTileTable { * Defines the data structure for constructing industry. */ struct IndustrySpec { - const IndustryTileTable * const *table;///< List of the tiles composing the industry - byte num_table; ///< Number of elements in the table - uint8 cost_multiplier; ///< Base construction cost multiplier. - uint32 removal_cost_multiplier; ///< Base removal cost multiplier. - uint32 prospecting_chance; ///< Chance prospecting succeeds - IndustryType conflicting[3]; ///< Industries this industry cannot be close to - byte check_proc; ///< Index to a procedure to check for conflicting circumstances - CargoID produced_cargo[2]; - byte production_rate[2]; + const IndustryTileTable * const *table; ///< List of the tiles composing the industry + byte num_table; ///< Number of elements in the table + uint8 cost_multiplier; ///< Base construction cost multiplier. + uint32 removal_cost_multiplier; ///< Base removal cost multiplier. + uint32 prospecting_chance; ///< Chance prospecting succeeds + IndustryType conflicting[3]; ///< Industries this industry cannot be close to + byte check_proc; ///< Index to a procedure to check for conflicting circumstances + CargoID produced_cargo[INDUSTRY_NUM_OUTPUTS]; + byte production_rate[INDUSTRY_NUM_OUTPUTS]; /** * minimum amount of cargo transported to the stations. * If the waiting cargo is less than this number, no cargo is moved to it. */ byte minimal_cargo; - CargoID accepts_cargo[3]; ///< 3 accepted cargoes. - uint16 input_cargo_multiplier[3][2]; ///< Input cargo multipliers (multiply amount of incoming cargo for the produced cargoes) - IndustryLifeType life_type; ///< This is also known as Industry production flag, in newgrf specs - byte climate_availability; ///< Bitmask, giving landscape enums as bit position - IndustryBehaviour behaviour; ///< How this industry will behave, and how others entities can use it - byte map_colour; ///< colour used for the small map - StringID name; ///< Displayed name of the industry - StringID new_industry_text; ///< Message appearing when the industry is built - StringID closure_text; ///< Message appearing when the industry closes - StringID production_up_text; ///< Message appearing when the industry's production is increasing - StringID production_down_text; ///< Message appearing when the industry's production is decreasing - StringID station_name; ///< Default name for nearby station - byte appear_ingame[NUM_LANDSCAPE]; ///< Probability of appearance in game - byte appear_creation[NUM_LANDSCAPE]; ///< Probability of appearance during map creation - uint8 number_of_sounds; ///< Number of sounds available in the sounds array - const uint8 *random_sounds; ///< array of random sounds. + CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]; ///< 16 accepted cargoes. + uint16 input_cargo_multiplier[INDUSTRY_NUM_INPUTS][INDUSTRY_NUM_OUTPUTS]; ///< Input cargo multipliers (multiply amount of incoming cargo for the produced cargoes) + IndustryLifeType life_type; ///< This is also known as Industry production flag, in newgrf specs + byte climate_availability; ///< Bitmask, giving landscape enums as bit position + IndustryBehaviour behaviour; ///< How this industry will behave, and how others entities can use it + byte map_colour; ///< colour used for the small map + StringID name; ///< Displayed name of the industry + StringID new_industry_text; ///< Message appearing when the industry is built + StringID closure_text; ///< Message appearing when the industry closes + StringID production_up_text; ///< Message appearing when the industry's production is increasing + StringID production_down_text; ///< Message appearing when the industry's production is decreasing + StringID station_name; ///< Default name for nearby station + byte appear_ingame[NUM_LANDSCAPE]; ///< Probability of appearance in game + byte appear_creation[NUM_LANDSCAPE]; ///< Probability of appearance during map creation + uint8 number_of_sounds; ///< Number of sounds available in the sounds array + const uint8 *random_sounds; ///< array of random sounds. /* Newgrf data */ - uint16 callback_mask; ///< Bitmask of industry callbacks that have to be called - uint8 cleanup_flag; ///< flags indicating which data should be freed upon cleaning up - bool enabled; ///< entity still available (by default true).newgrf can disable it, though - GRFFileProps grf_prop; ///< properties related to the grf file + uint16 callback_mask; ///< Bitmask of industry callbacks that have to be called + uint8 cleanup_flag; ///< flags indicating which data should be freed upon cleaning up + bool enabled; ///< entity still available (by default true).newgrf can disable it, though + GRFFileProps grf_prop; ///< properties related to the grf file bool IsRawIndustry() const; bool IsProcessingIndustry() const; @@ -144,10 +146,11 @@ struct IndustrySpec { /** * Defines the data structure of each individual tile of an industry. + * @note A tile can at most accept 3 types of cargo, even if an industry as a whole can accept more types. */ struct IndustryTileSpec { - CargoID accepts_cargo[3]; ///< Cargo accepted by this tile - uint8 acceptance[3]; ///< Level of acceptance per cargo type + CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]; ///< Cargo accepted by this tile + int8 acceptance[INDUSTRY_NUM_INPUTS]; ///< Level of acceptance per cargo type (signed, may be negative!) Slope slopes_refused; ///< slope pattern on which this tile cannot be built byte anim_production; ///< Animation frame to start when goods are produced byte anim_next; ///< Next frame in an animation diff --git a/src/ini.cpp b/src/ini.cpp index 905ebfacf8..6767d8525d 100644 --- a/src/ini.cpp +++ b/src/ini.cpp @@ -19,7 +19,7 @@ # include #endif -#ifdef WIN32 +#ifdef _WIN32 # include # include # include "core/mem_func.hpp" @@ -87,7 +87,7 @@ bool IniFile::SaveToDisk(const char *filename) fclose(f); #endif -#if defined(WIN32) || defined(WIN64) +#if defined(_WIN32) /* _tcsncpy = strcpy is TCHAR is char, but isn't when TCHAR is wchar. */ #undef strncpy /* Allocate space for one more \0 character. */ diff --git a/src/ini_type.h b/src/ini_type.h index ce383b959c..9bd47fd4e5 100644 --- a/src/ini_type.h +++ b/src/ini_type.h @@ -70,7 +70,7 @@ struct IniLoadFile { * Open the INI file. * @param filename Name of the INI file. * @param subdir The subdir to load the file from. - * @param size [out] Size of the opened file. + * @param[out] size Size of the opened file. * @return File handle of the opened file, or \c NULL. */ virtual FILE *OpenFile(const char *filename, Subdirectory subdir, size_t *size) = 0; diff --git a/src/landscape.cpp b/src/landscape.cpp index 185e84a80b..18f27807d7 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -32,6 +32,7 @@ #include "company_func.h" #include "pathfinder/npf/aystar.h" #include "saveload/saveload.h" +#include "framerate_type.h" #include #include @@ -720,6 +721,8 @@ TileIndex _cur_tileloop_tile; */ void RunTileLoop() { + PerformanceAccumulator framerate(PFE_GL_LANDSCAPE); + /* The pseudorandom sequence of tiles is generated using a Galois linear feedback * shift register (LFSR). This allows a deterministic pseudorandom ordering, but * still with minimal state and fast iteration. */ @@ -1080,8 +1083,7 @@ static uint River_Hash(uint tile, uint dir) */ static void BuildRiver(TileIndex begin, TileIndex end) { - AyStar finder; - MemSetT(&finder, 0); + AyStar finder = {}; finder.CalculateG = River_CalculateG; finder.CalculateH = River_CalculateH; finder.GetNeighbours = River_GetNeighbours; @@ -1304,10 +1306,14 @@ void OnTick_LinkGraph(); void CallLandscapeTick() { - OnTick_Town(); - OnTick_Trees(); - OnTick_Station(); - OnTick_Industry(); + { + PerformanceAccumulator framerate(PFE_GL_LANDSCAPE); + + OnTick_Town(); + OnTick_Trees(); + OnTick_Station(); + OnTick_Industry(); + } OnTick_Companies(); OnTick_LinkGraph(); diff --git a/src/lang/afrikaans.txt b/src/lang/afrikaans.txt index b7fee9ae8b..d1e96d41d7 100644 --- a/src/lang/afrikaans.txt +++ b/src/lang/afrikaans.txt @@ -670,10 +670,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Kies 'Be STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Skakel musiek lys skommel aan/af STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Vertoon musiek snit keuse venster -STR_ERROR_NO_SONGS :{WHITE}'n Musiek stel is gekies wat geen liedere bevat nie. Geen liedere sal gespeel word nie - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Musiek Program Keuse STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Liedjie Indeks STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Program - '{STRING}' @@ -1338,8 +1335,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Kleur van die t STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Groen STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Donkergroen STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Violet -STR_CONFIG_SETTING_REVERSE_SCROLLING :Agteruit rol rigting: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :As dit geaktiveer is, skuif die muis die kaart, andersins skuif die muis die kamera. STR_CONFIG_SETTING_SMOOTH_SCROLLING :Maak kykpoort beweegings glad: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Beheer hoe die hoofvertoonvenster skuif na 'n spesifieke posisie - as dit geaktiveer is, dan skuif die venster glad na die posisie toe, andersins skuif die venster direk na die posisie toe. STR_CONFIG_SETTING_MEASURE_TOOLTIP :Toon 'n meting wanneer jy verskeie bou-gereedskap gebruik: {STRING} @@ -1371,8 +1366,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command-klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl-klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Af -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Links-klik vir skermrol: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Maak dit moontlik om die kaart te skuif deur met die die linker-muisknoppie te sleep. Hier opsie werk baie goed vir toestelle met raakskerms. STR_CONFIG_SETTING_AUTOSAVE :Outostoor: {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :Tyd tussen outomatiese spelstore @@ -2690,6 +2683,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Oorspron STR_ABOUT_VERSION :{BLACK}OpenTTD uitgawe {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 Die OpenTTD span +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Spaar Spel STR_SAVELOAD_LOAD_CAPTION :{WHITE}Laai Spel @@ -2981,8 +2981,6 @@ STR_TOWN_POPULATION :{BLACK}Wêreldb STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (City) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Bevolking: {ORANGE}{COMMA}{BLACK} Huise: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passasiers verlede maand: {ORANGE}{COMMA}{BLACK} maks: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Pos verlede maand: {ORANGE}{COMMA}{BLACK} maks: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Vrag nodig om dorp te laat groei: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} vereis STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} vereis in winter @@ -4206,7 +4204,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Te veel STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Te veel treinstasie deele STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Te veel bushalte STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Te veel vragmotor stasies -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Te naby aan 'n ander stasie/laai area STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Te naby aan 'n ander werf STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Te naby aan 'n ander lughawe STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Stasie kan nie hernoem word nie... diff --git a/src/lang/arabic_egypt.txt b/src/lang/arabic_egypt.txt index b026705865..8c4c06b55b 100644 --- a/src/lang/arabic_egypt.txt +++ b/src/lang/arabic_egypt.txt @@ -644,10 +644,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}اختي STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}تشغيل / ايقاف العشوائي STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}اظهار اطار اختيار الموسيقى -STR_ERROR_NO_SONGS :{WHITE}لا تحتوى قاعده الموسيقى المُختاره على اى اغانى. لن تُعزَف اى اغانى - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}برنامج اختيار الموسيقى STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}قائمة المعزوفات STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}برنامج - '{STRING}' @@ -1177,7 +1174,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR :لون الار STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :اخضر STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :اخضر غامق STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :بنفسجي -STR_CONFIG_SETTING_REVERSE_SCROLLING :عكس تحريك الشاشة : {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING :تحريك سلس في نوافذ المشاهدة: {STRING} STR_CONFIG_SETTING_MEASURE_TOOLTIP :عرض المقاسات عند استخدام ادوات البناء المختلفة: {STRING} STR_CONFIG_SETTING_LIVERIES :عرض لون و شعار الشركة: {STRING} @@ -1196,7 +1192,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :الأوامر STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :للتحكم STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :عدم استخدام -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :تصفح بالزر الايسر: {STRING} STR_CONFIG_SETTING_AUTOSAVE :حفظ تلقائي : {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :اختر الوقت بين كل عملية حفظ اتوماتيكية @@ -2322,6 +2317,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}الحق STR_ABOUT_VERSION :{BLACK}النسخة المفتوحة رقم {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}النسخة المفتوحة {COPYRIGHT}2002-2018 فريق النسخة المفتوحة +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}حفظ اللعبة STR_SAVELOAD_LOAD_CAPTION :{WHITE}فتح @@ -2594,8 +2596,6 @@ STR_TOWN_POPULATION :{BLACK}سكان STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} - مدينة - STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}السكان: {ORANGE}{COMMA}{BLACK} المنازل: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}الركاب الشهر الماضي: {ORANGE}{COMMA}{BLACK} الأقصى: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}طرود البريد الشهر الماضي: {ORANGE}{COMMA}{BLACK} الأقصى: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK} نمو المدينة يتطلب بضائع STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} مطلوب STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK}مطلوب في الشتاء @@ -3667,7 +3667,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}يوجد STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}يوجد الكثير من قطاعات محطه السكه الحديديه STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}يوجد الكثير من محطات الحافلات STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}يوجد الكثير من محطات الشاحنات -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}قريب للغايه من محطه اخرى STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}قريب للغايه من مَرسَى اخر STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}قريب للغايه من مطار اخر STR_ERROR_CAN_T_RENAME_STATION :{WHITE}تعذر إعاده تسميه المحطه... diff --git a/src/lang/basque.txt b/src/lang/basque.txt index 6d80461b68..d5511050b1 100644 --- a/src/lang/basque.txt +++ b/src/lang/basque.txt @@ -663,10 +663,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}'Pertson STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Programa zorizko moduan jarri/kendu STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Erakutsi kanten selekzio leihoa -STR_ERROR_NO_SONGS :{WHITE}Kantarik gabeko musika paketea aukeratua. Ez dago kantarik entzuteko - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Musika Programen Selekzioa STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Pistaren Indizea STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programatu - '{STRING}' @@ -872,7 +869,7 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Leihoa {COMMA} STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Leihora kopiatu STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK} Leiho nagusian ikusten dena leiho honetara kopiatu -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Leihotik kpiatutakoa itsatsi +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Aldatu ikuspen nagusia STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Leiho honetan ikusten dena leiho nagusian itsasi # Game options window @@ -1301,8 +1298,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Mapa txikiaren STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Berdea STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Berde iluna STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Bioleta -STR_CONFIG_SETTING_REVERSE_SCROLLING :Leihoa mapan zehar mugitzeko sagua mugitzeko era aldrebes jarri: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Mapan zehar saguaren eskuineko botoiarekin mugitzerakoan izango duen portaera. Desgaitua badago, saguak kamera mugituko du. Gaitua dagoenean, saguak mapa mugituko du STR_CONFIG_SETTING_SMOOTH_SCROLLING :Mapan zehar mugitzerakoan, abiadura moteltzea: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Kontrolatu nola mugituko den ikuspegia lehio nagusitik zehar, puntu jakin batera joateko mapa txikian sakatzen denean edo objektu zehatz batera joateko agintzen denean STR_CONFIG_SETTING_MEASURE_TOOLTIP :Eraikitze tresna ezberdinak erabiltzerakoan neurtresna erakutsi: {STRING} @@ -1334,8 +1329,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Komandoa+Klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+Klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Itzalita -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Saguaren ezkerreko botoiarekin mapan zehar mugitzea: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Gaitu mapatik zehar mugitzea saguaren ezkerreko botoia mapan arrastratzerakoan. Oso erabilgarria da ukipen pantailak erabiltzerakoan STR_CONFIG_SETTING_AUTOSAVE :Auto-gordea: {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :Partida gordetze automatikoaren bitartea aukeratu @@ -2594,6 +2587,15 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Original STR_ABOUT_VERSION :{BLACK}OpenTTD bertsioa {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 The OpenTTD team +# Framerate display window +############ Leave those lines in this order!! +STR_FRAMERATE_GL_TRAINS :{WHITE} Trenen tick-ak: +STR_FRAMERATE_GL_SHIPS :{WHITE} Itsasontzien tick-ak: +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Gordetako jokoa STR_SAVELOAD_LOAD_CAPTION :{WHITE}Jokoa kargatu @@ -2870,8 +2872,6 @@ STR_TOWN_POPULATION :{BLACK}Munduko STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Hiria) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Biztanleria: {ORANGE}{COMMA}{BLACK} Etxe kopurua: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Bidaiari kopurua aurreko hilabetean: {ORANGE}{COMMA}{BLACK} gehienez: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Posta kopurua aurreko hilabetean: {ORANGE}{COMMA}{BLACK} gehienez: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Beharrezko zama herri hazkunderako: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} beharrezkoa STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} Neguan beharrezkoa @@ -3011,6 +3011,7 @@ STR_STATION_VIEW_CARGO_SUPPLY_RATING :{WHITE}{STRING} STR_STATION_VIEW_GROUP :{BLACK}Taldekatu STR_STATION_VIEW_WAITING_STATION :Geltokia: Itxaroten STR_STATION_VIEW_WAITING_AMOUNT :Kopurua: Itxoiten +STR_STATION_VIEW_PLANNED_STATION :Geltokia: Antolatua STR_STATION_VIEW_FROM :{YELLOW}{CARGO_SHORT} {STATION}-tik STR_STATION_VIEW_VIA :{YELLOW}{CARGO_SHORT}{STATION}-tik STR_STATION_VIEW_TO :{YELLOW}{CARGO_SHORT}{STATION}-ra @@ -4075,7 +4076,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Geltoki STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Tren geltoki zati gehiegi STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Autobus geltoki gehiegi STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Kamioi geltoki gehiegi -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Geltoki batetik hurbilegi STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Kai batetik hurbilegi STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Aireportu batetik hurbilegi STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Ezinda geltokia berrizendatu... diff --git a/src/lang/belarusian.txt b/src/lang/belarusian.txt index 71efd347ab..819bce4a2b 100644 --- a/src/lang/belarusian.txt +++ b/src/lang/belarusian.txt @@ -963,6 +963,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}Музычнае афармленне недаступна STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}«{STRING}» STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Трэк STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Назва @@ -982,15 +983,15 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Выбр STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Уключыць/выключыць выпадковы выбар трэкаў STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Паказаць вакно выбару трэкаў -STR_ERROR_NO_SONGS :{WHITE}У выбранай праґраме адсутнічае музыка - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Выбар музычнай праґрамы +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Музычная праграма - '{STRING}' STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} «{STRING}» STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Сьпіс трэкаў STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programme — «{STRING}» STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Ачысьціць +STR_PLAYLIST_CHANGE_SET :{BLACK}Зьмяніць набор STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Ачысьціць сьпіс уласнай праґрамы +STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Змяніць выбар музычнага афармлення на іншы ўсталяваны набор STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Клікніце па назьве трэка, каб дадаць яго ва ўласную праґраму STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Клікніце па назьве трэка, каб выдаліць яго з уласнай праґрамы @@ -1195,7 +1196,7 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Вакно прагляду {COMMA} STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Капіяваць у вакно прагляду STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Скапіяваць бягучую пазыцыю ў вакно прагляду -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Уставіць з вакна прагляду +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}У асноўнае акно STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Перайсьці да гэтага месца ў асноўным вакне # Game options window @@ -1650,8 +1651,12 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Колер ля STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :зялёны STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :цёмна-зялёны STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :фіялетавы -STR_CONFIG_SETTING_REVERSE_SCROLLING :Перавярнуць напрамак зрушэньня прагляду мышшу: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Паводзіны пры пракручваньні мапы правай кнопкай мышы. Калі адключана, мыш перамяшчае кропку позірку. Калі ўключана, мыш перамяшчае мапу. +STR_CONFIG_SETTING_SCROLLMODE :Перамяшчэнне агляду: {STRING} +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Спосаб перамяшчэння па гульнёваму полю +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Перамяшчаць з дапамогай ПКМ, зафіксаваўшы курсор +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Перамяшчаць з дапамогай ПКМ, зафіксаваўшы курсор +STR_CONFIG_SETTING_SCROLLMODE_RMB :Перамяшчаць з дапамогай ПКМ +STR_CONFIG_SETTING_SCROLLMODE_LMB :Перамяшчаць з дапамогай ЛКМ STR_CONFIG_SETTING_SMOOTH_SCROLLING :Павольная пракрутка ў вакне прагляду: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Кантралюе, што адбудзецца ў галоўным вакне, калі пстрыкнуць у малым вакне прагляду па нейкай кропцы. Калі ўключана, позірк будзе павольна перамяшчацца па мапе ў галоўным вакне. Калі выключана — экран адразу прыгне ў вызначанае месца. STR_CONFIG_SETTING_MEASURE_TOOLTIP :Паказваць замеры пры будаўніцтве: {STRING} @@ -1683,8 +1688,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :каманда+ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+клік STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :выключана -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Скролінг па кліку левай кнопкай мышы: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Уключыць пракручваньне мапы цягненьнем з націснутай левай кнопкай мышы. Гэта асабліва зручна пры выкарыстоўваньні сэнсарнага экрана. STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Зачыняць вокны пстрычкай ПКМ: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Зачыняць акно пстрычкай правай кнопкай мышы ў яго межах. Пры гэтым адключаецца з'яўленне падказак па правай кнопцы. @@ -2614,6 +2617,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Схем STR_LINKGRAPH_LEGEND_ALL :{BLACK}Усе STR_LINKGRAPH_LEGEND_NONE :{BLACK}Няма STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Выберыце кампаніі для адлюстраваньня +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}нявыкарыст. @@ -3026,6 +3030,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Арыґ STR_ABOUT_VERSION :{BLACK}OpenTTD вэрсія {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002–2018 Каманда распрацоўнікаў OpenTTD +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Захаваць гульню STR_SAVELOAD_LOAD_CAPTION :{WHITE}Загрузіць гульню @@ -3310,6 +3321,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Увяд STR_TOWN_DIRECTORY_CAPTION :{WHITE}Гарады STR_TOWN_DIRECTORY_NONE :{ORANGE}- Няма - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Мегаполіс){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Сьпіс гарадоў: клiк па назьве паказвае горад у асноўным вакне. Ctrl+клiк паказвае ў дадатковым вакне. STR_TOWN_POPULATION :{BLACK}Насельніцтва: {COMMA} @@ -3317,8 +3329,7 @@ STR_TOWN_POPULATION :{BLACK}Насе STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Мэґаполіс) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Насельніцтва: {ORANGE}{COMMA}{BLACK} Будынкаў: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Пасажыраў за мінулы месяц: {ORANGE}{COMMA}{BLACK} Макс.: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Пошты за мінулы месяц: {ORANGE}{COMMA}{BLACK} Макс.: {ORANGE}{COMMA} +STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} у мінулым месяцы: {ORANGE}{COMMA}{BLACK} Макс.: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Груз, неабходны для росту горада: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} патрабу{G 0 е e e ю}цца STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} патрабу{G 0 е e e ю}цца ўзімку @@ -4577,7 +4588,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Зана STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Занадта вялікая чыгуначная станцыя STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Занадта шмат аўтобусных прыпынкаў STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Занадта шмат грузавых тэрмiналаў -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Занадта блізка да іншай станцыі STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Занадта блізка да іншай прыстані STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Занадта блізка да іншага аэрапорта STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Немагчыма перайменаваць станцыю... @@ -4585,6 +4595,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... гэ STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... няправільны кірунак дарогі STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... на прахадных прыпынках нельга рабіць павароты STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... на прахадных прыпынках нельга рабіць скрыжаваньнi +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... дарога аднабаковая ці заблакавана # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Немагчыма выдаліць частку станцыi... @@ -4836,6 +4847,8 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Арыґіна STR_BASESOUNDS_WIN_DESCRIPTION :Арыґінальны набор гукавога афармленьня з гульні Transport Tycoon Deluxe для Windows. STR_BASESOUNDS_NONE_DESCRIPTION :"Пусты" набор гукавога афармленьня, які не зьмяшчае ніякіх гукаў. STR_BASEMUSIC_WIN_DESCRIPTION :Арыґінальны набор музычнага афармленьня з гульні Transport Tycoon Deluxe для Windows. +STR_BASEMUSIC_DOS_DESCRIPTION :Набор музычнага афармленьня з гульні Transport Tycoon Deluxe для DOS. +STR_BASEMUSIC_TTO_DESCRIPTION :Набор музычнага афармлення з гульні Transport Tycoon (Original/World Editor) для DOS. STR_BASEMUSIC_NONE_DESCRIPTION :"Пусты" набор музычнага афармлення, які не зьмяшчае ніякай музыкі. ##id 0x2000 diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index 859a6c1afa..5c943e651e 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -33,7 +33,7 @@ STR_CARGO_PLURAL_COAL :{G=m}Carvão STR_CARGO_PLURAL_MAIL :{G=f}Correspondências STR_CARGO_PLURAL_OIL :{G=m}Petróleo STR_CARGO_PLURAL_LIVESTOCK :{G=m}Gado -STR_CARGO_PLURAL_GOODS :{G=f}Bens +STR_CARGO_PLURAL_GOODS :{G=m}Bens STR_CARGO_PLURAL_GRAIN :{G=m}Cereais STR_CARGO_PLURAL_WOOD :{G=f}Madeira STR_CARGO_PLURAL_IRON_ORE :{G=m}Minério de Ferro @@ -147,7 +147,7 @@ STR_ABBREV_MAIZE :{TINY_FONT}MI STR_ABBREV_FRUIT :{TINY_FONT}FT STR_ABBREV_DIAMONDS :{TINY_FONT}DM STR_ABBREV_FOOD :{TINY_FONT}AL -STR_ABBREV_PAPER :{TINY_FONT}PL +STR_ABBREV_PAPER :{TINY_FONT}PP STR_ABBREV_GOLD :{TINY_FONT}OU STR_ABBREV_WATER :{TINY_FONT}AG STR_ABBREV_WHEAT :{TINY_FONT}TG @@ -220,7 +220,7 @@ STR_UNITS_FORCE_IMPERIAL :{COMMA}{NBSP}lb STR_UNITS_FORCE_METRIC :{COMMA}{NBSP}kgf STR_UNITS_FORCE_SI :{COMMA}{NBSP}kN -STR_UNITS_HEIGHT_IMPERIAL :{COMMA}{NBSP}pés +STR_UNITS_HEIGHT_IMPERIAL :{COMMA}{NBSP}pé{P "" s} STR_UNITS_HEIGHT_METRIC :{COMMA}{NBSP}m STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m @@ -476,6 +476,7 @@ STR_ABOUT_MENU_SCREENSHOT :Captura de tela STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Ampliado em captura de tela STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Captura de tela em ampliação padrão STR_ABOUT_MENU_GIANT_SCREENSHOT :Captura de tela do mapa inteiro +STR_ABOUT_MENU_SHOW_FRAMERATE :Exibir taxa de quadros STR_ABOUT_MENU_ABOUT_OPENTTD :Sobre 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Alinhador de "sprites" STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Alternar caixas limítrofes @@ -651,6 +652,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}Nenhuma música disponível STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Faixa STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Título @@ -670,15 +672,15 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Selecion STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Alternar programa misturado em ligado/desligado STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Exibir janela de seleção de faixas de música -STR_ERROR_NO_SONGS :{WHITE}Um conjunto de músicas sem canções foi selecionado. Nenhuma música será tocada - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Seleção de Programa de Música +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Programação Musical - '{STRING}' STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} '{STRING}' STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Índice de faixas STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programa - '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Limpar +STR_PLAYLIST_CHANGE_SET :{BLACK}Alterar set STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Limpar programa atual (apenas Personalizado 1 ou Personalizado 2) +STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Altera a seleção de músicas para outro set instalado STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Clique na faixa de música para a adicionar ao programa atual (apenas Personalizado 1 ou Personalizado 2) STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Clique na faixa de música para remover do programa atual (apenas Personalizado 1 ou Personalizado 2) @@ -814,6 +816,7 @@ STR_NEWS_MERGER_TAKEOVER_TITLE :{BIG_FONT}{BLAC STR_PRESIDENT_NAME_MANAGER :{BLACK}{PRESIDENT_NAME}{}(Gerente) STR_NEWS_NEW_TOWN :{BLACK}{BIG_FONT}{STRING} patrocinou a construção da nova cidade {TOWN}! +STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK}{BIG_FONT}Uma nova cidade, {TOWN}, foi construída! STR_NEWS_INDUSTRY_CONSTRUCTION :{BIG_FONT}{BLACK}Nov{G o a} {STRING} em construção próximo a {TOWN}! STR_NEWS_INDUSTRY_PLANTED :{BIG_FONT}{BLACK}Nov{G o a} {STRING} sendo plantada próximo a {TOWN}! @@ -881,10 +884,10 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC # Extra view window STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Janela {COMMA} -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Copiar para janela +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Alterar visualização STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Copiar o local da tela principal para esta janela -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Colar da janela -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Colar a localização desta janela para a tela principal +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Colar da visualização principal +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Colar a localização desta janela para a visualização principal # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opções do Jogo @@ -926,6 +929,7 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :Rand Sul-Africa STR_GAME_OPTIONS_CURRENCY_CUSTOM :Personalizado... STR_GAME_OPTIONS_CURRENCY_GEL :Lari da Georgia STR_GAME_OPTIONS_CURRENCY_IRR :Rial Iraniano +STR_GAME_OPTIONS_CURRENCY_RUB :Novo Rublo Russo (RUB) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Automóveis @@ -1338,10 +1342,14 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Cor do terreno STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Verde STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Verde escuro STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Violeta -STR_CONFIG_SETTING_REVERSE_SCROLLING :Rolar a tela no sentido oposto ao movimento do mouse: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Comportamento quando rolar o mapa com o botão direito. Quando desativado, o mouse move a câmera. Ativado, o mouse move o mapa. +STR_CONFIG_SETTING_SCROLLMODE :Comportamento de rolamento da janela: {STRING} +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Comportamento ao rolar o mapa +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Mover vista com BDM, posição do mouse travada +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Mover mapa com BDM, posição do mouse travada +STR_CONFIG_SETTING_SCROLLMODE_RMB :Mover mapa com BDM +STR_CONFIG_SETTING_SCROLLMODE_LMB :Move o mapa com BEM STR_CONFIG_SETTING_SMOOTH_SCROLLING :Suavizar rolamento da janela: {STRING} -STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Controla como a janela principal rola para uma posição específica quando clicado no minimapa ou após localizar um objeto. Ativado torna o rolamento suave. Desativado torna o rolamento instanâneo +STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Controla como a janela principal rola para uma posição específica quando clicado no minimapa ou após localizar um objeto. Ativado torna o rolamento suave. Desativado torna o rolamento instantâneo STR_CONFIG_SETTING_MEASURE_TOOLTIP :Exibe distâncias quando usar ferramentas de construção: {STRING} STR_CONFIG_SETTING_MEASURE_TOOLTIP_HELPTEXT :Exibe distâncias e diferenças de altitude quando clicando e arrastando enquanto constrói STR_CONFIG_SETTING_LIVERIES :Exibir cores avançadas: {STRING} @@ -1371,8 +1379,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Clique de coman STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Clique de controle STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Desligado -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Mover a tela com o botão esquerdo: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Ativa rolamento do mapa por clique e arraste com o botão esquerdo. Especialmente útil ao usar um touchscreen para o rolamento STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Fechar janela com botão direito do mouse: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Fecha uma janela ao clicar com o botão direito do mouse nela. Desativa o tooltip com o botão direito! @@ -2286,6 +2292,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Legenda STR_LINKGRAPH_LEGEND_ALL :{BLACK}Todas STR_LINKGRAPH_LEGEND_NONE :{BLACK}Nenhuma STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Selecione companhias a serem exibidas +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}não utilizado @@ -2694,6 +2701,52 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Copyrigh STR_ABOUT_VERSION :{BLACK}OpenTTD versão {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 A equipe do OpenTTD +# Framerate display window +STR_FRAMERATE_CAPTION :{WHITE}Taxa de quadros +STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) +STR_FRAMERATE_RATE_GAMELOOP :{WHITE}Taxa de simulação: {STRING} +STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Número de tiques simulados por segundo +STR_FRAMERATE_RATE_BLITTER :{WHITE}Taxa de quadros: {STRING} +STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Número de quadros renderizados por segundo. +STR_FRAMERATE_SPEED_FACTOR :{WHITE}Fator de velocidade do jogo atual: {DECIMAL}x +STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Quão rápido o jogo está sendo executado, comparado com a velocidade esperada na simulação normal +STR_FRAMERATE_CURRENT :{WHITE}Atual +STR_FRAMERATE_AVERAGE :{WHITE}Médio +STR_FRAMERATE_DATA_POINTS :{WHITE}Dados baseados em {COMMA} medidas +STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL}{WHITE} ms +STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL}{WHITE} ms +STR_FRAMERATE_MS_BAD :{RED}{DECIMAL}{WHITE} ms +STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL}{WHITE} quadros/s +STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL}{WHITE} quadros/s +STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL}{WHITE} quadros/s +STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms +STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s +############ Leave those lines in this order!! +STR_FRAMERATE_GL_ECONOMY :{WHITE} Manuseio de carga: +STR_FRAMERATE_GL_TRAINS :{WHITE} Tiques de trem: +STR_FRAMERATE_GL_ROADVEHS :{WHITE} Tiques de automóveis: +STR_FRAMERATE_GL_SHIPS :{WHITE} Tiques de embarcação: +STR_FRAMERATE_GL_AIRCRAFT :{WHITE} Tiques de aeronave: +STR_FRAMERATE_GL_LANDSCAPE :{WHITE} Tiques do mundo: +STR_FRAMERATE_DRAWING :{WHITE}Renderizações de gráficos: +STR_FRAMERATE_DRAWING_VIEWPORTS :{WHITE} Visualizações do mundo: +STR_FRAMERATE_VIDEO :{WHITE}Saída de vídeo: +STR_FRAMERATE_SOUND :{WHITE}Mixagem de áudio: +############ End of leave-in-this-order +############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_GL_ECONOMY :Manuseio de carga +STR_FRAMETIME_CAPTION_GL_TRAINS :Tiques de trem +STR_FRAMETIME_CAPTION_GL_ROADVEHS :Tiques de automóveis +STR_FRAMETIME_CAPTION_GL_SHIPS :Tiques de embarcação +STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Tiques de aeronave: +STR_FRAMETIME_CAPTION_GL_LANDSCAPE :Tiques do mundo +STR_FRAMETIME_CAPTION_DRAWING :Renderizações de gráficos +STR_FRAMETIME_CAPTION_DRAWING_VIEWPORTS :Renderização da janela principal +STR_FRAMETIME_CAPTION_VIDEO :Saída de vídeo +STR_FRAMETIME_CAPTION_SOUND :Mixagem de áudio +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Salvar Jogo STR_SAVELOAD_LOAD_CAPTION :{WHITE}Abrir Jogo @@ -2978,6 +3031,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Coloque STR_TOWN_DIRECTORY_CAPTION :{WHITE}Cidades STR_TOWN_DIRECTORY_NONE :{ORANGE}- Nenhum - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Cidade){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Nomes das cidades - clique no nome para centralizar a visualização principal na cidade. Ctrl+Clique abre uma nova janela na localização da cidade STR_TOWN_POPULATION :{BLACK}População mundial: {COMMA} @@ -2985,8 +3039,7 @@ STR_TOWN_POPULATION :{BLACK}Populaç STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Cidade) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}População: {ORANGE}{COMMA}{BLACK} Casas: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passageiros no mês passado: {ORANGE}{COMMA}{BLACK} máx: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Cartas no mês passado: {ORANGE}{COMMA}{BLACK} máx: {ORANGE}{COMMA} +STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} últ. mês: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Carga necessária para prover o crescimento: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} necessário(a) STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} necessário no inverno @@ -4225,7 +4278,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Estaçõ STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}A estação já tem muitas partes STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Estações de ônibus demais STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Áreas de carga demais -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Muito perto de outra estação/local de carga STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Muito perto de outra doca STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Muito perto de outro aeroporto STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Impossível renomear a estação... @@ -4233,6 +4285,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... é u STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... rua na direção errada STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... paradas "drive-thru" não podem ter esquinas STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... paradas "drive-thru" não podem ter junções +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... rua é mão única ou está bloqueada # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Impossível remover parte da estação... @@ -4301,7 +4354,7 @@ STR_ERROR_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Impossí STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Remova os semáforos antes STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Tipo de linha não apropriado STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Remova a ferrovia antes -STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Rua é mão única ou está bloqueado +STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Rua é mão única ou está bloqueada STR_ERROR_CROSSING_DISALLOWED :{WHITE}Cruzamentos de nível não são permitidos para esse tipo de trilho STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Impossível construir sinais aqui... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Impossível construir ferrovia aqui... @@ -4484,6 +4537,8 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Sons Originais STR_BASESOUNDS_WIN_DESCRIPTION :Sons Originais do Transport Tycoon Deluxe, Edição Windows. STR_BASESOUNDS_NONE_DESCRIPTION :Um pacote de sons sem sons. STR_BASEMUSIC_WIN_DESCRIPTION :Música Original do Transport Tycoon Deluxe, Edição Windows +STR_BASEMUSIC_DOS_DESCRIPTION :Música Original do Transport Tycoon Deluxe DOS. +STR_BASEMUSIC_TTO_DESCRIPTION :Música Original do Transport Tycoon DOS STR_BASEMUSIC_NONE_DESCRIPTION :Um pacote de músicas sem músicas. ##id 0x2000 diff --git a/src/lang/bulgarian.txt b/src/lang/bulgarian.txt index 40394260d4..d085371987 100644 --- a/src/lang/bulgarian.txt +++ b/src/lang/bulgarian.txt @@ -667,10 +667,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Избе STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Активирай/деактивирай разместване на парчетата STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Покажи прозореца за избор на музикални парчета -STR_ERROR_NO_SONGS :{WHITE}Музикален пакет без песни е избран. Няма да се пускат песни. - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Избор на музикалната програма STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Номер на песен STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Програма - '{STRING}' @@ -1320,8 +1317,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Цвят на STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Зелен STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Тъмно зелен STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Виолетов -STR_CONFIG_SETTING_REVERSE_SCROLLING :Обърната посока на преместване: {STRING.n} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Когато опцията бъде активирана, когато "скролвате" картата с десния бутон на мишката ще местите картата, когато опцията не е активирана, мишката ще мести камерата STR_CONFIG_SETTING_SMOOTH_SCROLLING :Плавно местене на камера: {STRING.n} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Ако опцията е активирана, когато натиснете на малката карта камерата ще се придвижи до там плавно, ако не е активирана камерата ще отиде там директно STR_CONFIG_SETTING_MEASURE_TOOLTIP :Подсказка за разстояние при строене: {STRING.f} @@ -1353,8 +1348,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Команда- STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Контрол-щракане STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Изключен -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Скролиране с ляв бутон: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Позволява да "скролнете" картата, чрез влачене на левия бутон на мишката. Това и изключително полезно ако ползвате тъч-скрийн STR_CONFIG_SETTING_AUTOSAVE :Автоматично запазване: {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :Изберете интервал между автоматично запаметяване на играта @@ -2635,6 +2628,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Авто STR_ABOUT_VERSION :{BLACK}OpenTTD версия {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2018 The OpenTTD team +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Запази играта STR_SAVELOAD_LOAD_CAPTION :{WHITE}Отваряне на игра @@ -2918,8 +2918,6 @@ STR_TOWN_POPULATION :{BLACK}Обща STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Град) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Население: {ORANGE}{COMMA}{BLACK} Жилища: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Пътници през последния месец: {ORANGE}{COMMA}{BLACK} максимум: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Поща през последния месец: {ORANGE}{COMMA}{BLACK} максимум: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Товар нужен за растеж на града: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} необходим STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} необходим през зимата @@ -4135,7 +4133,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Твър STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Твърде много части на гара STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Твърде много автобусни спирки STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Твърде много гари за камиони -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Твърде близо до друга гара/товарна платформа STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Прекалено близо до друг док STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Прекалено близо до друго летище STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Станцията не може да бъде преименувана... diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt index 28814005c8..cc641141af 100644 --- a/src/lang/catalan.txt +++ b/src/lang/catalan.txt @@ -476,6 +476,7 @@ STR_ABOUT_MENU_SCREENSHOT :Captura de pant STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Captura de pantalla amb el zoom màxim STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Captura de pantalla amb el zoom predeterminat STR_ABOUT_MENU_GIANT_SCREENSHOT :Captura de pantalla de tot el mapa +STR_ABOUT_MENU_SHOW_FRAMERATE :Mostra els fotogrames per segon STR_ABOUT_MENU_ABOUT_OPENTTD :Quant a l'OpenTTD STR_ABOUT_MENU_SPRITE_ALIGNER :Alineador de sprites STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Commuta les caixes delimitadores @@ -651,6 +652,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}No hi ha peces musicals disponibles STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}«{STRING}» STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Pista STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Títol @@ -670,15 +672,15 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Seleccio STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Habilita/deshabilita la reproducció en ordre aleatori STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Mostra la finestra de selecció de pistes -STR_ERROR_NO_SONGS :{WHITE}S'ha seleccionat un conjunt de música sense peces. No es reproduirà res. - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Selecció de les peces de la llista +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Programació de pistes - «{STRING}» STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} «{STRING}» STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Índex de pistes STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Llista «{STRING}» STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Esborra +STR_PLAYLIST_CHANGE_SET :{BLACK}Canvia conjunt STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Esborra la llista actual (només les llistes personalitzables) +STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Canvia la selecció musical a un altre conjunt instal·lat. STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Clica la pista de música per afegir-la a la llista actual (només en les llistes personalitzables) STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Clica la pista de música per treure-la de la llista actual (només en llistes personalitzables) @@ -881,10 +883,10 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC # Extra view window STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Vista {COMMA} -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Copia a la vista +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Canvia la vista extra STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Mou aquesta vista on està la vista principal -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Vés a la vista -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Mou la vista principal on està aquesta vista +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Canvia vista principal +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Copia el lloc d'aquesta vista extra a la vista principal. # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opcions de la partida @@ -1338,8 +1340,12 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Color del terre STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Verd STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Verd fosc STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Violat -STR_CONFIG_SETTING_REVERSE_SCROLLING :En desplaçar la pantalla amb el ratolí mou la vista en la direcció contrària: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Comportament quan es desplaci el mapa amb el botó dret del ratolí. Quan està desactivat, el ratolí mou la càmera. Quan està activat, el ratolí mou el mapa +STR_CONFIG_SETTING_SCROLLMODE :Desplaçament del mapa: {STRING} +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Comportament quan es desplaça el mapa. +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Mou la vista amb el botó dret del ratolí amb la posició del ratolí fixada +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Mou el mapa amb el botó dret del ratolí amb la posició del ratolí fixada +STR_CONFIG_SETTING_SCROLLMODE_RMB :Mou el mapa amb el botó dret del ratolí +STR_CONFIG_SETTING_SCROLLMODE_LMB :Mou el mapa amb el botó esquerre del ratolí STR_CONFIG_SETTING_SMOOTH_SCROLLING :Desplaçament suau de la vista: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Controla com la vista principal es desplaça a una posició específica quan es clica al mapa petit o quan s'envia una ordre de desplaçar-se a un objecte específic al mapa. Si està activat, la vista es desplaça suaument; si està desactivat, salta directament al punt assenyalat STR_CONFIG_SETTING_MEASURE_TOOLTIP :Mostra un cartell de mesura quan estiguis utilitzant vàries eines de construcció: {STRING} @@ -1371,8 +1377,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command-clic STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Control-clic STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Desactivat -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Desplaçament amb el botó esquerre: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Activa el desplaçament del mapa arrossegant-lo amb el botó esquerre del ratolí. Això és especialment útil quan s'utilitzen pantalles tàctils STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Tanca la finestra amb un clic dret del ratolí: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Tanca una finestra fent-hi un clic amb el botó dret del ratolí. Aquesta opció desactiva els indicadors de funció amb el mateix botó. @@ -2286,6 +2290,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Llegenda STR_LINKGRAPH_LEGEND_ALL :{BLACK}Tot STR_LINKGRAPH_LEGEND_NONE :{BLACK}Cap STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Selecciona les companyies que seran mostrades +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{G=Masculin}{TINY_FONT}{BLACK}no utilitzat @@ -2694,6 +2699,56 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Copyrigh STR_ABOUT_VERSION :{BLACK}Versió {REV} de l'OpenTTD STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 L'equip de l'OpenTTD +# Framerate display window +STR_FRAMERATE_CAPTION :{WHITE}Fotogrames per segon +STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} (x{DECIMAL}) +STR_FRAMERATE_RATE_GAMELOOP :{WHITE}Velocitat de simulació: {STRING} +STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Nombre de tics del joc per segon. +STR_FRAMERATE_RATE_BLITTER :{WHITE}Fotogrames per segon: {STRING} +STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Nombre de fotogrames renderitzats per segon. +STR_FRAMERATE_SPEED_FACTOR :{WHITE}Factor de velocitat actual: x{DECIMAL} +STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Quant ràpid va la partida actual, comparant-ho amb l'estimació de la velocitat normal. +STR_FRAMERATE_CURRENT :{WHITE}Actual +STR_FRAMERATE_AVERAGE :{WHITE}Mitjana +STR_FRAMERATE_DATA_POINTS :{WHITE}Dades basades en {COMMA} mesures. +STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL}{WHITE}{NBSP}ms +STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL}{WHITE}{NBSP}ms +STR_FRAMERATE_MS_BAD :{RED}{DECIMAL}{WHITE}{NBSP}ms +STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL}{WHITE}{NBSP}fps +STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL}{WHITE}{NBSP}fps +STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL}{WHITE}{NBSP}fps +STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA}{NBSP}ms +STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA}{NBSP}s +############ Leave those lines in this order!! +STR_FRAMERATE_GAMELOOP :{WHITE}Total del bucle: +STR_FRAMERATE_GL_ECONOMY :{WHITE} Tractament de la càrrega: +STR_FRAMERATE_GL_TRAINS :{WHITE} Tics de tren: +STR_FRAMERATE_GL_ROADVEHS :{WHITE} Tics de vehicles de carretera: +STR_FRAMERATE_GL_SHIPS :{WHITE} Tics de vaixell: +STR_FRAMERATE_GL_AIRCRAFT :{WHITE} Tics d'aeronau: +STR_FRAMERATE_GL_LANDSCAPE :{WHITE} Tics del mapa: +STR_FRAMERATE_GL_LINKGRAPH :{WHITE} Retard del graf de distribució: +STR_FRAMERATE_DRAWING :{WHITE}Renderitzat de gràfics: +STR_FRAMERATE_DRAWING_VIEWPORTS :{WHITE} Vistes del mapa: +STR_FRAMERATE_VIDEO :{WHITE}Sortida de vídeo: +STR_FRAMERATE_SOUND :{WHITE}Mescla de so: +############ End of leave-in-this-order +############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_GAMELOOP :Bucle +STR_FRAMETIME_CAPTION_GL_ECONOMY :Tractament de la càrrega +STR_FRAMETIME_CAPTION_GL_TRAINS :Tics de tren +STR_FRAMETIME_CAPTION_GL_ROADVEHS :Tics de vehicle de carretera +STR_FRAMETIME_CAPTION_GL_SHIPS :Tics de vaixell +STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Tics d'aeronau +STR_FRAMETIME_CAPTION_GL_LANDSCAPE :Tics del mapa +STR_FRAMETIME_CAPTION_GL_LINKGRAPH :Retard del graf de distribució +STR_FRAMETIME_CAPTION_DRAWING :Renderitzat de gràfics +STR_FRAMETIME_CAPTION_DRAWING_VIEWPORTS :Renderitzat de la vista del mapa +STR_FRAMETIME_CAPTION_VIDEO :Sortida de vídeo +STR_FRAMETIME_CAPTION_SOUND :Mescla de so +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Desa la Partida STR_SAVELOAD_LOAD_CAPTION :{WHITE}Carrega una Partida @@ -2978,6 +3033,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Posa un STR_TOWN_DIRECTORY_CAPTION :{WHITE}Poblacions STR_TOWN_DIRECTORY_NONE :{ORANGE}- Cap - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK} ({COMMA} -{YELLOW} ciutat{BLACK}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Noms de Població - clica al nom per centrar la vista principal a la població. Ctrl+Clic obre una nova vista al lloc de la població STR_TOWN_POPULATION :{BLACK}Població mundial: {COMMA} @@ -2985,8 +3041,7 @@ STR_TOWN_POPULATION :{BLACK}Poblaci STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Ciutat) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Població: {ORANGE}{COMMA}{BLACK} Cases: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passatgers el darrer mes: {ORANGE}{COMMA}{BLACK} màx: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Correu el darrer mes: {ORANGE}{COMMA}{BLACK} màx: {ORANGE}{COMMA} +STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} l'últim mes: {ORANGE}{COMMA}{BLACK} (màx. {ORANGE}{COMMA}{BLACK}) STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Càrrega requerida per tal que la població creixi: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} requerides STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} requerit a l'hivern @@ -4225,7 +4280,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Massa es STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Hi ha massa parts d'estacions de tren STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Massa parades d'autobús STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Masses estacions de càrrega -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Massa prop d'una altra estació/àrea de càrrega STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Massa prop d'un altre moll STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Massa prop d'un altre aeroport STR_ERROR_CAN_T_RENAME_STATION :{WHITE}No es pot canviar el nom de l'estació... @@ -4233,6 +4287,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... aque STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... sentit de la carretera en la direcció incorrecta STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... les estacions d'autobús de pas no poden tenir cantonades STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... les estacions d'autobús de pas no poden tenir interseccions +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... la carretera és d'un sol sentit o està blocada. # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}No es pot treure part de la estació... @@ -4484,6 +4539,8 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Sons originals STR_BASESOUNDS_WIN_DESCRIPTION :Sons originals del Transport Tycoon Deluxe pel Windows. STR_BASESOUNDS_NONE_DESCRIPTION :Una llista de sons buida. STR_BASEMUSIC_WIN_DESCRIPTION :Música original del Transport Tycoon Deluxe pel Windows. +STR_BASEMUSIC_DOS_DESCRIPTION :Música original del Transport Tycoon Deluxe pel DOS. +STR_BASEMUSIC_TTO_DESCRIPTION :Música original del Transport Tycoon Deluxe (original/editor d'escenaris) pel DOS. STR_BASEMUSIC_NONE_DESCRIPTION :Una llista de música sense cap peça. ##id 0x2000 diff --git a/src/lang/croatian.txt b/src/lang/croatian.txt index e7694f1bde..fc7a6a53bb 100644 --- a/src/lang/croatian.txt +++ b/src/lang/croatian.txt @@ -571,6 +571,7 @@ STR_ABOUT_MENU_SCREENSHOT :Slika zaslona STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Zumirano do kraja na slici zaslona STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Standardno zumiranje slike zaslona STR_ABOUT_MENU_GIANT_SCREENSHOT :Slika zaslona cijele karte +STR_ABOUT_MENU_SHOW_FRAMERATE :Prikaži broj sličica u sekundi STR_ABOUT_MENU_ABOUT_OPENTTD :O 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Poravnanje spritea STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Odaberi granične okvire @@ -746,6 +747,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}Nema dostupne muzike STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Traka STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Naslov @@ -765,15 +767,15 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Odaberi STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Uključi/isključi miješanje programa STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Pokaži prozor za izbor glazbenih traka -STR_ERROR_NO_SONGS :{WHITE}Odabran je set glazbe bez pjesama. Ne će se puštati nikakve pjesme - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Izbor glazbenog programa +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Program muzike - '{STRING}' STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Popis traka STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Program- '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Obriši +STR_PLAYLIST_CHANGE_SET :{BLACK}Promijeni set STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Obriši aktivni program (samo Proizvoljno 1 ili Proizvoljno 2) +STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Promijeni odabir muzike na neki drugi instalirani set STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Klikni na glazbenu traku za dodavanje u aktivni program (samo Proizvoljno 1 ili Proizvoljno 2) STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Klikni na glazbenu traku kako bi ju uklonio iz trenutnog programa (samo Proizvoljno 1 ili Proizvoljno 2) @@ -909,6 +911,7 @@ STR_NEWS_MERGER_TAKEOVER_TITLE :{BIG_FONT}{BLAC STR_PRESIDENT_NAME_MANAGER :{BLACK}{PRESIDENT_NAME}{}(Direktor) STR_NEWS_NEW_TOWN :{BLACK}{BIG_FONT}Tvrtka {STRING} sponzorira izgradnju novoga grada {TOWN}! +STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK}{BIG_FONT}Sagrađen je novi grad {TOWN}! STR_NEWS_INDUSTRY_CONSTRUCTION :{BIG_FONT}{BLACK}Započela je izgradnja nove {STRING.gen} u blizini grada {TOWN}a! STR_NEWS_INDUSTRY_PLANTED :{BIG_FONT}{BLACK}Nova {STRING} trenutno se sadi blizu grada {TOWN}a! @@ -976,10 +979,10 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC # Extra view window STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Mini pogled {COMMA} -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Kopiraj u mini pogled +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Promijeni pogled STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Kopiraj lokaciju globalnog pogleda u ovaj mini pogled -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Zalijepi iz mini pogleda -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Zalijepi lokaciju ovog mini pogleda u globalni pogled +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Promijeni glavni pogled +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Kopiraj lokaciju ovog mini pogleda u glavni pogled # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Postavke igre @@ -1021,6 +1024,7 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :Južnoafrički STR_GAME_OPTIONS_CURRENCY_CUSTOM :Proizvoljno... STR_GAME_OPTIONS_CURRENCY_GEL :Gruzijski Lari (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :Iranski Rial (IRR) +STR_GAME_OPTIONS_CURRENCY_RUB :Nove ruske rublje (RUB) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Cestovna vozila @@ -1433,8 +1437,12 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Boja terena na STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :{G=female}Zelena STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :{G=female}Tamno zelena STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :{G=female}Ljubičasta -STR_CONFIG_SETTING_REVERSE_SCROLLING :Promijeni smjer klizanja: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Ponašanje kod pomicanja karte desnim gumbom miša. Kada je isključeno, miš pomiče kameru. Kada je uključeno, miš pomiče kartu +STR_CONFIG_SETTING_SCROLLMODE :Ponašanje klizanja kroz mini pogled: {STRING} +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Ponašanje kod klizanja kroz mapu +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Pomiči mini pogled sa desnom tipkom miša, pozicija miša zaključana +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Pomiči mapu sa desnom tipkom miša, pozicija miša zaključana +STR_CONFIG_SETTING_SCROLLMODE_RMB :Pomiči mapu sa desnom tipkom miša +STR_CONFIG_SETTING_SCROLLMODE_LMB :Pomiči mapu sa lijevom tipkom miša STR_CONFIG_SETTING_SMOOTH_SCROLLING :Glatko klizanje kroz mini pogled: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Odredi kako se glavni prikaz pomiče na određeno mjesto kada se klikne na malu kartu ili kada se izda naredba za pomicanje na određeni objekt na karti. Ako je uključeno, prikaz se pomiče glatko, ako je isključeno, prikaz izravno skače na ciljnu lokaciju STR_CONFIG_SETTING_MEASURE_TOOLTIP :Pokaži mjerni naputak prilikom korištenja raznih alata za izgradnju: {STRING} @@ -1466,8 +1474,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command+klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Control+klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Isključeno -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Skrolanje lijevim klikom: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Uključi pomicanje karte povlačenjem pomoću lijevog gumba miša. Ovo je posebno korisno kada se koristi zaslon osjetljiv na dodir STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Zatvori prozor nakon desnog klika: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Zatvara prozor nakon desnog klika unutar prozora. S desnim klikom zatvaraju se i upute alata! @@ -2381,6 +2387,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Kazalo p STR_LINKGRAPH_LEGEND_ALL :{BLACK}Sve STR_LINKGRAPH_LEGEND_NONE :{BLACK}Ništa STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Odaberi tvrtke koje će se prikazati +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}nekorišten @@ -2789,6 +2796,56 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Izvorno STR_ABOUT_VERSION :{BLACK}OpenTTD verzija {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 OpenTTD tim +# Framerate display window +STR_FRAMERATE_CAPTION :{WHITE}Broj sličica +STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) +STR_FRAMERATE_RATE_GAMELOOP :{BLACK}Stopa simulacije: {STRING} +STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Broj otkucaja igre simuliranih u sekundi. +STR_FRAMERATE_RATE_BLITTER :{BLACK}Broj sličica u sekundi: {STRING} +STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Broj sličica videa prikayanih u sekundi. +STR_FRAMERATE_SPEED_FACTOR :{BLACK}Trenutni faktor brzine igre: {DECIMAL}x +STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Koliko brzo se igra izvodi trenutno u usporedbi sa očekivanom brzinom u uobičajenoj simulaciji. +STR_FRAMERATE_CURRENT :{WHITE}Trenutno +STR_FRAMERATE_AVERAGE :{WHITE}Prosječno +STR_FRAMERATE_DATA_POINTS :{BLACK}Podaci bazirani na {COMMA} mjerama +STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms +STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms +STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} ms +STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} sličica/s +STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} sličica/s +STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} sličica/s +STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms +STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s +############ Leave those lines in this order!! +STR_FRAMERATE_GAMELOOP :{BLACK}Zbroj petlji igre: +STR_FRAMERATE_GL_ECONOMY :{BLACK} Korištenje tereta: +STR_FRAMERATE_GL_TRAINS :{BLACK} Otkucaji vlakova: +STR_FRAMERATE_GL_ROADVEHS :{BLACK} Otkucaji cestovnih vozila: +STR_FRAMERATE_GL_SHIPS :{BLACK} Otkucaji brodova: +STR_FRAMERATE_GL_AIRCRAFT :{BLACK} Otkucaji aviona: +STR_FRAMERATE_GL_LANDSCAPE :{BLACK} Otkucaji svijeta: +STR_FRAMERATE_GL_LINKGRAPH :{BLACK} Odmak linka grafikona: +STR_FRAMERATE_DRAWING :{BLACK}Prikaz grafike: +STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK} Prikazi svijeta: +STR_FRAMERATE_VIDEO :{BLACK}Video izlaz: +STR_FRAMERATE_SOUND :{BLACK}Miksanje zvukova: +############ End of leave-in-this-order +############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_GAMELOOP :Petlja igre +STR_FRAMETIME_CAPTION_GL_ECONOMY :Korištenje tereta +STR_FRAMETIME_CAPTION_GL_TRAINS :Otkucaji vlakova +STR_FRAMETIME_CAPTION_GL_ROADVEHS :Otkucaji cestovnih vozila +STR_FRAMETIME_CAPTION_GL_SHIPS :Otkucaji brodova +STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Otkucaji aviona +STR_FRAMETIME_CAPTION_GL_LANDSCAPE :Otkucaji svijeta +STR_FRAMETIME_CAPTION_GL_LINKGRAPH :Odmak linka grafikona +STR_FRAMETIME_CAPTION_DRAWING :Prikaz grafike +STR_FRAMETIME_CAPTION_DRAWING_VIEWPORTS :Prikazi svijeta +STR_FRAMETIME_CAPTION_VIDEO :Video izlaz +STR_FRAMETIME_CAPTION_SOUND :Miksanje zvukova +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Spremi igru STR_SAVELOAD_LOAD_CAPTION :{WHITE}Učitaj igru @@ -2811,6 +2868,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Detalji STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Nema dostupnih informacija. STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} +STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtriraj niz: STR_SAVELOAD_OSKTITLE :{BLACK}Upiši ime za spremanje igre @@ -3009,6 +3067,8 @@ STR_NEWGRF_ERROR_READ_BOUNDS :Pročitaj nakon STR_NEWGRF_ERROR_GRM_FAILED :Zatraženi GRF resursi nisu dostupni (sprite {3:NUM}) STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING} je isključen od strane {STRING} STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Pogrešan/nepoznat format raspored sprite-a (sprite {3:NUM}) +STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG :Previše elemenata na listi postavki varijabli (sprite {3:NUM}, postavka {4:HEX}) +STR_NEWGRF_ERROR_INDPROD_CALLBACK :Pogrešna callback funkcija za industrijsku proizvodnju (sprite {3:NUM}, "{1:STRING}") # NewGRF related 'general' warnings STR_NEWGRF_POPUP_CAUTION_CAPTION :{WHITE}Oprez! @@ -3073,6 +3133,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Unesi im STR_TOWN_DIRECTORY_CAPTION :{WHITE}Gradovi STR_TOWN_DIRECTORY_NONE :{ORANGE}- Ništa - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Grad){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Imena gradova - klikni na ime kako bi centrirao pogled na grad. Ctrl+klik otvara novi prozor sa lokacijom grada STR_TOWN_POPULATION :{BLACK}Svjetsko stanovništvo: {COMMA} @@ -3080,8 +3141,7 @@ STR_TOWN_POPULATION :{BLACK}Svjetsko STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Metropola) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Stanovništvo: {ORANGE}{COMMA}{BLACK} Kuće: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Putnika prošli mjesec: {ORANGE}{COMMA}{BLACK} najviše: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Pošte prošli mjesec: {ORANGE}{COMMA}{BLACK} najviše: {ORANGE}{COMMA} +STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} prošli mjesec: {ORANGE}{COMMA}{BLACK} maks: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Potrebno tereta za rast grada: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} potrebno STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} potrebno zimi @@ -4320,7 +4380,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Previše STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Previše dijelova željezničke postaje STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Previše autobusnih postaja STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Previše kamionskih postaja -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Preblizu drugoj postaji/terminalu STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Preblizu drugom pristaništu STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Preblizu drugoj zračnoj luci STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Nije moguće preimenovati postaju... @@ -4328,6 +4387,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... ovo STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... cesta je orijentirana u krivom smjeru STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... prolazne postaje ne mogu imati zavoje STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... prolazne postaje ne mogu imati raskrižja +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... cesta je jednosmjerna ili je blokirana # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Nije moguće ukloniti dio postaje... @@ -4579,6 +4639,8 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Originalni zvuk STR_BASESOUNDS_WIN_DESCRIPTION :Originalni zvukovi za Transport Tycoon Deluxe Windows izdanje. STR_BASESOUNDS_NONE_DESCRIPTION :Zvučni paket bez ikakvih zvukova. STR_BASEMUSIC_WIN_DESCRIPTION :Originalna glazba za Transport Tycoon Deluxe Windows izdanje. +STR_BASEMUSIC_DOS_DESCRIPTION :Originalna glazba za Transport Tycoon Deluxe DOS izdanje. +STR_BASEMUSIC_TTO_DESCRIPTION :Originalna glazba za Transport Tycoon (original/editor svijeta) DOS izdanje. STR_BASEMUSIC_NONE_DESCRIPTION :Glazbeni paket bez ikakve glazbe. ##id 0x2000 diff --git a/src/lang/czech.txt b/src/lang/czech.txt index cab72a7c92..5512bc616d 100644 --- a/src/lang/czech.txt +++ b/src/lang/czech.txt @@ -550,6 +550,7 @@ STR_ABOUT_MENU_SCREENSHOT :Screenshot STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Screenshot v plném přiblížení STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Screenshot ve výchozím přiblížení STR_ABOUT_MENU_GIANT_SCREENSHOT :Screenshot celé mapy +STR_ABOUT_MENU_SHOW_FRAMERATE :Zobrazit počet snímků za sekundu STR_ABOUT_MENU_ABOUT_OPENTTD :O 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Zarovnávání spritů STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Přepnout ohraničení @@ -737,6 +738,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}Hudba nedostupná STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Skladba STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Název @@ -756,15 +758,13 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Zvolit p STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Zapnout/vypnout náhodné opakování skladeb STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Ukaž skladbu ve výběrovém okně -STR_ERROR_NO_SONGS :{WHITE}Byl vybrán hudební set bez písní. Nebudou přehrány žádné písně - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Volba programu hudby STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Index skladeb STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Program - '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Vymazat STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Vyprázdnit současný program (jen u Voleb 1 a 2) +STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Změnit výběr hudby na jinou nainstalovanou sadu. STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Skladba se přidá do zvoleného programu (Volba 1 nebo 2) klepnutím na její název STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Hudební stopu odstraníš ze současného programu (pouze u vlastního) kliknutím na ni @@ -900,6 +900,7 @@ STR_NEWS_MERGER_TAKEOVER_TITLE :{BIG_FONT}{BLAC STR_PRESIDENT_NAME_MANAGER :{BLACK}{PRESIDENT_NAME}{}(Prezident) STR_NEWS_NEW_TOWN :{BLACK}{BIG_FONT}Společnost {STRING} zaplatila výstavbu nového města {TOWN}! +STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK}{BIG_FONT}Nové město {TOWN} bylo vystavěno! STR_NEWS_INDUSTRY_CONSTRUCTION :{BIG_FONT}{BLACK}Nov{G ý á é í é é á} {STRING.small} se staví poblíž města {TOWN}! STR_NEWS_INDUSTRY_PLANTED :{BIG_FONT}{BLACK}Nov{G ý á é í é é á} {STRING.small} se vysazuj{G 0 e e e í í í í} poblíž města {TOWN}! @@ -969,7 +970,7 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Pohled {COMMA} STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Nastavit jako pohled STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Nastavit současné zorné pole jako pohled -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Přejít na pohled +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Změnit hlavní pohled STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Nastavit pohled do zorného pole # Game options window @@ -1012,6 +1013,7 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :Jihoafrický ra STR_GAME_OPTIONS_CURRENCY_CUSTOM :Vlastní... STR_GAME_OPTIONS_CURRENCY_GEL :Georgijské Lari (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :Íránský Riál (IRR) +STR_GAME_OPTIONS_CURRENCY_RUB :Ruský rubl (RUB) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Silniční vozidla jezdí @@ -1424,8 +1426,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Barva terénu n STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :zelená STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :tmavě zelená STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :fialová -STR_CONFIG_SETTING_REVERSE_SCROLLING :Posouvat pohled opačným směrem: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Chování při posouvání mapy pomocí stisku pravého tlačítka myši. Pokud vypnuto, myš pohybuje kamerou. Pokud zapnuto, myš pohybuje mapou STR_CONFIG_SETTING_SMOOTH_SCROLLING :Plynulé posouvání po mapě: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Ovládá jak se hlavní pohled posouvá na specifické místo na mapě, kliknutím na minimapu nebo spuštěním příkazu na posun na specifický objekt na mapě. Pokud zapnuto, pohled se posouvá plynule, pokud vypnuto, skáče pohled přímo na cílové místo STR_CONFIG_SETTING_MEASURE_TOOLTIP :Ukázat rozměry při použití stavebních nástrojů: {STRING} @@ -1457,8 +1457,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command + klikn STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Control + kliknutí STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :vypnutá -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Posouvání levým tlačítkem: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Povolit posouvání mapy chycením pomocí levého tlačítka myši. Toto je velmi užitečné hlavně při použití s dotykovou obrazovkou. STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Zavírat okno kliknutím pravým tlačítkem myši: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Zavírat okno kliknutím pravým tlačítkem na něj. Znemožňuje využívat nápovědu zobrazující se při stisknutí pravého tlačítka myši! @@ -2372,6 +2370,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Legenda STR_LINKGRAPH_LEGEND_ALL :{BLACK}Všechny STR_LINKGRAPH_LEGEND_NONE :{BLACK}Žádný STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Vybrat firmy, které mají být zobrazeny +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}nepoužívaný @@ -2786,6 +2785,28 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Původn STR_ABOUT_VERSION :{BLACK}OpenTTD verze {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 Tým OpenTTD +# Framerate display window +STR_FRAMERATE_CAPTION :{WHITE}Počet snímků za sekundu +STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Počet snímků videa vykreslovaných za sekundu. +STR_FRAMERATE_SPEED_FACTOR :{WHITE}Aktuální činitel rychlosti hry: {DECIMAL}x +STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Rychlost, kterou hra právě běží, v porovnání s očekávanou rychlostí při běžné rychlosti simulace. +STR_FRAMERATE_AVERAGE :{WHITE}Průměr +STR_FRAMERATE_MS_BAD :{RED}{DECIMAL}{WHITE} ms +STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL}{WHITE} sním{P "ek" "ky" "ků"}/s +STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL}{WHITE} sním{P "ek" "ky" "ků"}/s +STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms +STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s +############ Leave those lines in this order!! +STR_FRAMERATE_GL_ECONOMY :{WHITE} Manipulace s nákladem: +STR_FRAMERATE_DRAWING :{WHITE}Vykreslování grafiky: +############ End of leave-in-this-order +############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_GL_ECONOMY :Manipulace s nákladem +STR_FRAMETIME_CAPTION_DRAWING :Vykreslování grafiky +STR_FRAMETIME_CAPTION_SOUND :Míchání zvuků +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Uložit hru STR_SAVELOAD_LOAD_CAPTION :{WHITE}Otevřít hru @@ -3070,6 +3091,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Zadej n STR_TOWN_DIRECTORY_CAPTION :{WHITE}Města STR_TOWN_DIRECTORY_NONE :{ORANGE}- Nic - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (velkoměsto){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Jména měst - pohled na město zaměříš kliknutím na jeho jméno. Při stisknutém Ctrl otevřeš nový pohled STR_TOWN_POPULATION :{BLACK}Populace světa: {COMMA} @@ -3077,8 +3099,7 @@ STR_TOWN_POPULATION :{BLACK}Populace STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (velkoměsto) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Populace: {ORANGE}{COMMA}{BLACK} Domů: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Cestujících minulý měsíc: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Pošta za minulý měsíc: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} +STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} minulý měsíc: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Množství doručeného nákladu potřebného pro rozvoj města: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{RED}Je potřeba {ORANGE}{STRING} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} vyžadováno v zimě @@ -4320,7 +4341,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Příli STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Příliš mnoho staničních částí STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Příliš mnoho autobusových zastávek STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Příliš mnoho zastávek nákladních automobilů -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Příliš blízko k jinému nádraží nebo nákladové rampě STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Příliš blízko k jinému doku STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Příliš blízko k jinému letišti STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Nelze přejmenovat stanici... @@ -4328,6 +4348,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... tato STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... silnice je otočena jiným směrem STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... průjezdné zastávky nemohou být v zatáčce STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... průjezdné zastávky nemohou být na křižovatce +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... silnice je jednosměrná nebo uzavřená. # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Nelze odstranit část stanice... @@ -4586,6 +4607,8 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Původní sada STR_BASESOUNDS_WIN_DESCRIPTION :Původní sada zvuků Transport Tycoon Deluxe (verze pro Windows). STR_BASESOUNDS_NONE_DESCRIPTION :Prázdná sada zvuků. STR_BASEMUSIC_WIN_DESCRIPTION :Původní hudba Transport Tycoon Deluxe (verze pro Windows). +STR_BASEMUSIC_DOS_DESCRIPTION :Původní hudba Transport Tycoon Deluxe (verze pro DOS). +STR_BASEMUSIC_TTO_DESCRIPTION :Původní hudba Transport Tycoon (verze pro DOS). STR_BASEMUSIC_NONE_DESCRIPTION :Prázná hudební sada. ##id 0x2000 diff --git a/src/lang/danish.txt b/src/lang/danish.txt index 3119390f3e..813a496d15 100644 --- a/src/lang/danish.txt +++ b/src/lang/danish.txt @@ -650,6 +650,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}Ingen musik tilgængelig STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Nummer STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Titel @@ -669,15 +670,13 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Select ' STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Tilfældig afspilning til/fra STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Vis vinduet med musiknummervalg -STR_ERROR_NO_SONGS :{WHITE}Det valgte musik sæt er uden sange. Der kan ikke afspilles musik. - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Musikprogram Valg STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Nummerliste STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Program - '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Ryd STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Ryd det valgte program (Gælder kun Custom1/Custom2) +STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Ændre musik listen til et anden installeret sæt STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Klik på et musiknummer for at tilføje det til programlisten (kun for Custom1/Custom2) STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Klik på et musiknummer for at fjerne det fra programlisten (kun for Custom1/Custom2) @@ -1337,8 +1336,10 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Land farve brug STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Grøn STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Mørkegrøn STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Violet -STR_CONFIG_SETTING_REVERSE_SCROLLING :Flyt i modsat retning ved scroll med musen: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Adfærd når kortet rulles med højre museknap. Hvis deaktiveret, bevæger musen kameraet. Når funktionen er aktiveret, flytter musen kortet +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Bevæg syns vinduet med højre mussetast, musse position låst +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Bevæg kortet med højre mussetast, musse position låst +STR_CONFIG_SETTING_SCROLLMODE_RMB :Bevæg kortet med højre musseknap +STR_CONFIG_SETTING_SCROLLMODE_LMB :Bevæg kortet med venstre musseknap STR_CONFIG_SETTING_SMOOTH_SCROLLING :Jævn scrolling af udsnit: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Kontroller hvordan de vigtigste visning ruller til en bestemt position, når du klikker på det lille kort eller når de udsteder en kommando til at rulle til en bestemt genstand på kortet. Hvis aktiveret, ruller udsigtspunktet jævnt, hvis deaktiveret springer den direkte til det valgte punkt STR_CONFIG_SETTING_MEASURE_TOOLTIP :Vis måleværktøjstip ved brug af div. bygge-værktøjer: {STRING} @@ -1370,8 +1371,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Kommandoklik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Kontrolklik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Fra -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Venstreklik-scrolling: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Aktiver rulle kortet ved at trække den med venstre museknap. Dette er især nyttigt, når du bruger en touch-screen til at rulle STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Luk vindue ved højre-klik: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Lukker vinduet ved at højreklikke inde i det. Deaktiverer værktøjstip ved at højreklikke! @@ -2693,6 +2692,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Original STR_ABOUT_VERSION :{BLACK}OpenTTD version {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 OpenTTD teamet +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Gem spil STR_SAVELOAD_LOAD_CAPTION :{WHITE}Hent spil @@ -2984,8 +2990,6 @@ STR_TOWN_POPULATION :{BLACK}Verdens STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (by) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Indbyggere: {ORANGE}{COMMA}{BLACK} Huse: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passagerer sidste måned: {ORANGE}{COMMA}{BLACK} maks.: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Post sidste måned: {ORANGE}{COMMA}{BLACK} maks.: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Nødvendig godsmængde for at byen kan vokse: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} krævet STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} kræves om vinteren @@ -4224,7 +4228,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}For mang STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Banegården er i for mange dele STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}For mange busterminaler STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}For mange fragtcentraler -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}For tæt på en anden station/fragtcentral STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}For tæt på en anden havn STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}For tæt på en anden lufthavn STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Kan ikke omdøbe stationen... @@ -4232,6 +4235,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... denn STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... vejen peger i den forkerte retning STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... drive-through stops kan ikke have hjørner STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... drive-through stops kan ikke have kryds +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}vejen er ensrettet eller blokeret # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Kan ikke fjerne en del af en station... diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt index 383706f727..4598851f64 100644 --- a/src/lang/dutch.txt +++ b/src/lang/dutch.txt @@ -98,7 +98,7 @@ STR_QUANTITY_NOTHING : STR_QUANTITY_PASSENGERS :{COMMA}{NBSP}passagier{P "" s} STR_QUANTITY_COAL :{WEIGHT_LONG} kolen STR_QUANTITY_MAIL :{COMMA}{NBSP}zak{P "" ken} post -STR_QUANTITY_OIL :{VOLUME_LONG} Vaten Olie +STR_QUANTITY_OIL :{VOLUME_LONG} Vaten olie STR_QUANTITY_LIVESTOCK :{COMMA}{NBSP}stuk{P "" s} vee STR_QUANTITY_GOODS :{COMMA}{NBSP}krat{P "" ten} goederen STR_QUANTITY_GRAIN :{WEIGHT_LONG} graan @@ -107,7 +107,7 @@ STR_QUANTITY_IRON_ORE :{WEIGHT_LONG} i STR_QUANTITY_STEEL :{WEIGHT_LONG} staal STR_QUANTITY_VALUABLES :{COMMA}{NBSP}zak{P "" ken} kostbaarheden STR_QUANTITY_COPPER_ORE :{WEIGHT_LONG} kopererts -STR_QUANTITY_MAIZE :{WEIGHT_LONG} mais +STR_QUANTITY_MAIZE :{WEIGHT_LONG} maïs STR_QUANTITY_FRUIT :{WEIGHT_LONG} fruit STR_QUANTITY_DIAMONDS :{COMMA}{NBSP}zak{P "" ken} diamanten STR_QUANTITY_FOOD :{WEIGHT_LONG} voedsel @@ -224,7 +224,7 @@ STR_UNITS_HEIGHT_METRIC :{COMMA}{NBSP}m STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}Filter tekst: +STR_LIST_FILTER_TITLE :{BLACK}Filtertekst: STR_LIST_FILTER_OSKTITLE :{BLACK}Voer filtertekst in STR_LIST_FILTER_TOOLTIP :{BLACK}Geef een woord waarop gefilterd kan worden in de lijst @@ -239,7 +239,7 @@ STR_BUTTON_RENAME :{BLACK}Hernoem STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Sluit venster STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Vensternaam - sleep om venster te verplaatsen STR_TOOLTIP_SHADE :{BLACK}Klap venster in - toon alleen de titelbalk -STR_TOOLTIP_DEBUG :{BLACK}Toon NewGRF debug informatie +STR_TOOLTIP_DEBUG :{BLACK}Toon NewGRF-debuginformatie STR_TOOLTIP_DEFSIZE :{BLACK}wijzig venster naar standaardgrootte. Ctrl+Klik om de huidige grootte als standaard op te slaan STR_TOOLTIP_STICKY :{BLACK}Markeer dit venster als niet-sluitbaar door de 'Sluit alle vensters'-knop. Ctrl+Klik om status als default op te slaan STR_TOOLTIP_RESIZE :{BLACK}Klik en sleep om de grootte van dit venster te veranderen @@ -324,10 +324,10 @@ STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_STATIONS :{BLACK}Toon lij STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_FINANCES :{BLACK}Toon financiële informatie over het bedrijf STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_GENERAL :{BLACK}Toon algemene informatie over het bedrijf STR_TOOLBAR_TOOLTIP_DISPLAY_STORY_BOOK :{BLACK}Toon verhaallijn -STR_TOOLBAR_TOOLTIP_DISPLAY_GOALS_LIST :{BLACK}Geven doellijst +STR_TOOLBAR_TOOLTIP_DISPLAY_GOALS_LIST :{BLACK}Geef doellijst weer STR_TOOLBAR_TOOLTIP_DISPLAY_GRAPHS :{BLACK}Toon grafieken STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_LEAGUE :{BLACK}Toon bedrijfscompetitietabel -STR_TOOLBAR_TOOLTIP_FUND_CONSTRUCTION_OF_NEW :{BLACK}Betaal de bouw van nieuwe industrie of toon lijst van alle industrieën +STR_TOOLBAR_TOOLTIP_FUND_CONSTRUCTION_OF_NEW :{BLACK}Financier de bouw van nieuwe industrie of toon lijst van alle industrieën STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_TRAINS :{BLACK}Toon lijst met treinen van het bedrijf. Ctrl+klik schakelt tussen lijst van groepen/voertuigen STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_ROAD_VEHICLES :{BLACK}Toon lijst met wegvoertuigen van het bedrijf. Ctrl+klik schakelt tussen lijst van groepen/voertuigen STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_SHIPS :{BLACK}Toon lijst met schepen van het bedrijf. Ctrl+klik schakelt tussen lijst van groepen/voertuigen @@ -340,8 +340,8 @@ STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Bouw hav STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Bouw vliegvelden STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Open de landschapsbalk om land te verhogen/verlagen, bomen te planten, etc. STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Toon geluid/muziekscherm -STR_TOOLBAR_TOOLTIP_SHOW_LAST_MESSAGE_NEWS :{BLACK}Toon laatste (nieuws)bericht, toon berichtinstellingen -STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION :{BLACK}Landinformatie, console, script-debug, screenshots, over OpenTTD +STR_TOOLBAR_TOOLTIP_SHOW_LAST_MESSAGE_NEWS :{BLACK}Toon laatst (nieuws)bericht, toon berichtinstellingen +STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION :{BLACK}Landinformatie, console, scriptdebug, screenshots, over OpenTTD STR_TOOLBAR_TOOLTIP_SWITCH_TOOLBAR :{BLACK}Verwissel knoppenbalk # Extra tooltips for the scenario editor toolbar @@ -354,7 +354,7 @@ STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE :{BLACK}Klik om STR_SCENEDIT_TOOLBAR_TOOLTIP_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Toon kaart, stedenlijst STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Landschapsontwikkeling STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Stadsontwikkeling -STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Industrie-ontwikkeling +STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Industrieontwikkeling STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Wegenbouw STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plant bomen. Shift schakelt tussen bouwen/inschatting van de kosten STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Plaats bord @@ -365,7 +365,7 @@ STR_SCENEDIT_FILE_MENU_SAVE_SCENARIO :Scenario opslaa STR_SCENEDIT_FILE_MENU_LOAD_SCENARIO :Scenario openen STR_SCENEDIT_FILE_MENU_SAVE_HEIGHTMAP :Hoogtekaart opslaan STR_SCENEDIT_FILE_MENU_LOAD_HEIGHTMAP :Laad hoogtekaart -STR_SCENEDIT_FILE_MENU_QUIT_EDITOR :Sluit scenario editor +STR_SCENEDIT_FILE_MENU_QUIT_EDITOR :Sluit scenario-editor STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Afsluiten ############ range for SE file menu starts @@ -373,14 +373,14 @@ STR_SCENEDIT_FILE_MENU_QUIT :Afsluiten ############ range for settings menu starts STR_SETTINGS_MENU_GAME_OPTIONS :Spelopties STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Instellingen -STR_SETTINGS_MENU_SCRIPT_SETTINGS :AI/Game script instellingen -STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF instellingen +STR_SETTINGS_MENU_SCRIPT_SETTINGS :AI/Spelscriptinstellingen +STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF-instellingen STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Doorzichtigheidsopties STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Toon plaatsnamen STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED :Toon stationsnamen STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED :Toon controlepostnamen STR_SETTINGS_MENU_SIGNS_DISPLAYED :Toon borden -STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS :Toon tegenstander's borden en namen +STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS :Toon borden en namen van tegenstanders STR_SETTINGS_MENU_FULL_ANIMATION :Alle animaties STR_SETTINGS_MENU_FULL_DETAIL :Alle details STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS :Transparante gebouwen @@ -398,7 +398,7 @@ STR_FILE_MENU_EXIT :Afsluiten # map menu STR_MAP_MENU_MAP_OF_WORLD :Kaart STR_MAP_MENU_EXTRA_VIEW_PORT :Extra kijkvenster -STR_MAP_MENU_LINGRAPH_LEGEND :Vracht Stroom Legenda +STR_MAP_MENU_LINGRAPH_LEGEND :Vrachtstroomlegende STR_MAP_MENU_SIGN_LIST :Bordenlijst ############ range for town menu starts @@ -422,7 +422,7 @@ STR_GRAPH_MENU_CARGO_PAYMENT_RATES :Vrachtprijzen ############ range for company league menu starts STR_GRAPH_MENU_COMPANY_LEAGUE_TABLE :Bedrijfscompetitietabel STR_GRAPH_MENU_DETAILED_PERFORMANCE_RATING :Gedetailleerde prestatiescore -STR_GRAPH_MENU_HIGHSCORE :Score tabel +STR_GRAPH_MENU_HIGHSCORE :Scoretabel ############ range ends here ############ range for industry menu starts @@ -434,13 +434,13 @@ STR_INDUSTRY_MENU_FUND_NEW_INDUSTRY :Betaal nieuwe i ############ range for railway construction menu starts STR_RAIL_MENU_RAILROAD_CONSTRUCTION :Bouw spoorwegen STR_RAIL_MENU_ELRAIL_CONSTRUCTION :Bouw geëlektrificeerde spoorwegen -STR_RAIL_MENU_MONORAIL_CONSTRUCTION :Bouw monorail-spoorwegen -STR_RAIL_MENU_MAGLEV_CONSTRUCTION :Bouw magneetzweeftrein-spoorwegen +STR_RAIL_MENU_MONORAIL_CONSTRUCTION :Bouw monorailspoorwegen +STR_RAIL_MENU_MAGLEV_CONSTRUCTION :Bouw magneetzweeftreinspoorwegen ############ range ends here ############ range for road construction menu starts STR_ROAD_MENU_ROAD_CONSTRUCTION :Bouw wegen -STR_ROAD_MENU_TRAM_CONSTRUCTION :Bouw tramwegen +STR_ROAD_MENU_TRAM_CONSTRUCTION :Bouw tramsporen ############ range ends here ############ range for waterways construction menu starts @@ -462,7 +462,7 @@ STR_TOOLBAR_SOUND_MUSIC :Geluid/muziek ############ range ends here ############ range for message menu starts -STR_NEWS_MENU_LAST_MESSAGE_NEWS_REPORT :Laatste (nieuws)bericht +STR_NEWS_MENU_LAST_MESSAGE_NEWS_REPORT :Laatst (nieuws)bericht STR_NEWS_MENU_MESSAGE_HISTORY_MENU :Berichtengeschiedenis ############ range ends here @@ -475,8 +475,9 @@ STR_ABOUT_MENU_SCREENSHOT :Screenshot STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Ingezoomd screenshot STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Screenshot met standaard zoom STR_ABOUT_MENU_GIANT_SCREENSHOT :Screenshot van hele kaart +STR_ABOUT_MENU_SHOW_FRAMERATE :Toon frame rate STR_ABOUT_MENU_ABOUT_OPENTTD :Over 'OpenTTD' -STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite uitlijner +STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite-uitlijner STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Schakel selectiekaders STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS :Schakel kleuren van braakliggende grond aan/uit ############ range ends here @@ -632,10 +633,10 @@ STR_PERFORMANCE_DETAIL_DELIVERED_TOOLTIP :{BLACK}Het aant STR_PERFORMANCE_DETAIL_CARGO_TOOLTIP :{BLACK}Aantal soorten vracht die in het laatste kwartaal zijn afgeleverd STR_PERFORMANCE_DETAIL_MONEY_TOOLTIP :{BLACK}Hoeveelheid geld op de bank STR_PERFORMANCE_DETAIL_LOAN_TOOLTIP :{BLACK}De hoeveelheid geld die dit bedrijf leent -STR_PERFORMANCE_DETAIL_TOTAL_TOOLTIP :{BLACK}Totaal aantal punten uit de mogelijke punten +STR_PERFORMANCE_DETAIL_TOTAL_TOOLTIP :{BLACK}Totaal aantal punten van de mogelijke punten # Music window -STR_MUSIC_JAZZ_JUKEBOX_CAPTION :{WHITE}Jazz-jukebox +STR_MUSIC_JAZZ_JUKEBOX_CAPTION :{WHITE}Jazzjukebox STR_MUSIC_PLAYLIST_ALL :{TINY_FONT}{BLACK}Alle STR_MUSIC_PLAYLIST_OLD_STYLE :{TINY_FONT}{BLACK}Oude Stijl STR_MUSIC_PLAYLIST_NEW_STYLE :{TINY_FONT}{BLACK}Nieuwe Stijl @@ -650,6 +651,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}Geen muziek beschikbaar STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Nummer STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Titel @@ -663,21 +665,21 @@ STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Gebruik STR_MUSIC_TOOLTIP_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Selecteer 'alle nummers'-programma STR_MUSIC_TOOLTIP_SELECT_OLD_STYLE_MUSIC :{BLACK}Selecteer 'oude stijl-muziek'-programma STR_MUSIC_TOOLTIP_SELECT_NEW_STYLE_MUSIC :{BLACK}Selecteer 'nieuwe stijl-muziek'-programma -STR_MUSIC_TOOLTIP_SELECT_EZY_STREET_STYLE :{BLACK}Kies 'Ezy Street-stijl-muziek'-programma +STR_MUSIC_TOOLTIP_SELECT_EZY_STREET_STYLE :{BLACK}Kies 'Ezy Street stylemuziek'-programma STR_MUSIC_TOOLTIP_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Selecteer 'Aangepast1'-programma STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Selecteer 'Aangepast2'-programma STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Programmashuffle aan/uit STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Toon nummerkeuzescherm -STR_ERROR_NO_SONGS :{WHITE}Er is een muziek set zonder liedjes gekozen. Er zal geen muziek worden gespeeld - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Muziekprogrammakeuze +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Muziekprogramma - '{STRING}' STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Nummerindex STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programma - '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Maak leeg +STR_PLAYLIST_CHANGE_SET :{BLACK}Verander set STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Maak huidig programma leeg (alleen Aangepast1 en Aangepast2) +STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Verander muziekselectie naar een andere geïnstalleerde set STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Klik op het nummer om deze aan het programma toe te voegen (alleen Aangepast1 en Aangepast2) STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Klik op het nummer om deze uit het programma te verwijderen (alleen Aangepast1 en Aangepast2) @@ -705,14 +707,14 @@ STR_SMALLMAP_TYPE_VEHICLES :Voertuigen STR_SMALLMAP_TYPE_INDUSTRIES :Industrieën STR_SMALLMAP_TYPE_ROUTEMAP :Vrachtstroom STR_SMALLMAP_TYPE_ROUTES :Routes -STR_SMALLMAP_TYPE_VEGETATION :Begroeiïng +STR_SMALLMAP_TYPE_VEGETATION :Begroeiing STR_SMALLMAP_TYPE_OWNERS :Eigenaren STR_SMALLMAP_TOOLTIP_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Toon landcontouren op de kaart STR_SMALLMAP_TOOLTIP_SHOW_VEHICLES_ON_MAP :{BLACK}Toon voertuigen op de kaart STR_SMALLMAP_TOOLTIP_SHOW_INDUSTRIES_ON_MAP :{BLACK}Toon industrieën op de kaart STR_SMALLMAP_TOOLTIP_SHOW_LINK_STATS_ON_MAP :{BLACK}Toon vrachtstroom op de kaart STR_SMALLMAP_TOOLTIP_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Toon transportroutes op de kaart -STR_SMALLMAP_TOOLTIP_SHOW_VEGETATION_ON_MAP :{BLACK}Toon begroeiïng op de kaart +STR_SMALLMAP_TOOLTIP_SHOW_VEGETATION_ON_MAP :{BLACK}Toon begroeiing op de kaart STR_SMALLMAP_TOOLTIP_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Toon landeigenaren op de kaart STR_SMALLMAP_TOOLTIP_INDUSTRY_SELECTION :{BLACK}Klik op een industriesoort om deze weer te geven. Ctrl+klik verbergt alle andere industriesoorten behalve de geselecteerde. Nogmaals Ctrl+klik geeft opnieuw alle industriesoorten weer. STR_SMALLMAP_TOOLTIP_COMPANY_SELECTION :{BLACK}Klik op een bedrijf om de bedrijfseigendommen weer te geven. Ctrl+klik verbergt alle andere bedrijven behalve de geselecteerde. Nogmaals Ctrl+klik geeft opnieuw alle bedrijven weer. @@ -737,7 +739,7 @@ STR_SMALLMAP_LEGENDA_DOCK :{TINY_FONT}{BLA STR_SMALLMAP_LEGENDA_ROUGH_LAND :{TINY_FONT}{BLACK}Ruw land STR_SMALLMAP_LEGENDA_GRASS_LAND :{TINY_FONT}{BLACK}Grasland STR_SMALLMAP_LEGENDA_BARE_LAND :{TINY_FONT}{BLACK}Braakliggend land -STR_SMALLMAP_LEGENDA_FIELDS :{TINY_FONT}{BLACK}Velden +STR_SMALLMAP_LEGENDA_FIELDS :{TINY_FONT}{BLACK}Akkers STR_SMALLMAP_LEGENDA_TREES :{TINY_FONT}{BLACK}Bomen STR_SMALLMAP_LEGENDA_ROCKS :{TINY_FONT}{BLACK}Rotsen STR_SMALLMAP_LEGENDA_WATER :{TINY_FONT}{BLACK}Water @@ -765,7 +767,7 @@ STR_SMALLMAP_TOOLTIP_DISABLE_ALL_CARGOS :{BLACK}Toon gee STR_SMALLMAP_TOOLTIP_ENABLE_ALL_CARGOS :{BLACK}Toon alle vrachtsoorten op de kaart # Status bar messages -STR_STATUSBAR_TOOLTIP_SHOW_LAST_NEWS :{BLACK}Toon laatste (nieuws)bericht +STR_STATUSBAR_TOOLTIP_SHOW_LAST_NEWS :{BLACK}Toon laatst (nieuws)bericht STR_STATUSBAR_COMPANY_NAME :{SILVER}- - {COMPANY} - - STR_STATUSBAR_PAUSED :{YELLOW}* * GEPAUZEERD * * STR_STATUSBAR_AUTOSAVE :{RED}AUTOMATISCH OPSLAAN @@ -844,7 +846,7 @@ STR_NEWS_VEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}{VEHICLE STR_NEWS_VEHICLE_HAS_VOID_ORDER :{WHITE}{VEHICLE} heeft een lege order STR_NEWS_VEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}{VEHICLE} heeft dubbele orders STR_NEWS_VEHICLE_HAS_INVALID_ENTRY :{WHITE}{VEHICLE} heeft een ongeldig station in de orders -STR_NEWS_PLANE_USES_TOO_SHORT_RUNWAY :{WHITE}{VEHICLE} heeft in de opdrachten een luchthaven waarvan de start-en landingsbaan is te kort +STR_NEWS_PLANE_USES_TOO_SHORT_RUNWAY :{WHITE}{VEHICLE} heeft in de opdrachten een luchthaven waarvan de start-en landingsbaan te kort is STR_NEWS_VEHICLE_IS_GETTING_OLD :{WHITE}{VEHICLE} is oud aan het worden STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD :{WHITE}{VEHICLE} is erg oud aan het worden @@ -874,16 +876,16 @@ STR_NEWS_SERVICE_SUBSIDY_AWARDED_DOUBLE :{BIG_FONT}{BLAC STR_NEWS_SERVICE_SUBSIDY_AWARDED_TRIPLE :{BIG_FONT}{BLACK}Subsidie uitgereikt aan {STRING}!{}{}{STRING}route van {STRING} naar {STRING} krijgt volgend jaar driedubbel betaald! STR_NEWS_SERVICE_SUBSIDY_AWARDED_QUADRUPLE :{BIG_FONT}{BLACK}Subsidie uitgereikt aan {STRING}!{}{}{STRING}route van {STRING} naar {STRING} krijgt volgend jaar vierdubbel betaald! -STR_NEWS_ROAD_REBUILDING :{BIG_FONT}{BLACK}Verkeerschaos in {TOWN}!{}{}Wegreparatie betaald door {STRING} zorgt voor 6 maanden van irritatie bij weggebruikers! -STR_NEWS_EXCLUSIVE_RIGHTS_TITLE :{BIG_FONT}{BLACK}Transport monopoly! -STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLACK}Lokale overheid van {TOWN} tekend contract met {STRING} voor een jaar exclusieve transportrechten! +STR_NEWS_ROAD_REBUILDING :{BIG_FONT}{BLACK}Verkeerschaos in {TOWN}!{}{}Wegherstelling betaald door {STRING} zorgt voor 6 maanden van miserie bij weggebruikers! +STR_NEWS_EXCLUSIVE_RIGHTS_TITLE :{BIG_FONT}{BLACK}Transportmonopolie! +STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLACK}Lokale overheid van {TOWN} tekent contract met {STRING} voor een jaar exclusieve transportrechten! # Extra view window STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Kijkvenster {COMMA} -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Kopieer naar kijkvenster +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Verander kijkvenster STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Kopieer de locatie van het algemene scherm naar dit kijkvenster -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Plak van kijkvenster -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Plak de locatie van dit kijkvenster naar het algemene scherm +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Verander algemeen scherm +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Kopieer de locatie van dit kijkvenster naar het algemene scherm # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Spelopties @@ -925,6 +927,7 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :Zuid-Afrikaanse STR_GAME_OPTIONS_CURRENCY_CUSTOM :Aangepast... STR_GAME_OPTIONS_CURRENCY_GEL :Georgische Lari (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :Iraanse Rial (IRR) +STR_GAME_OPTIONS_CURRENCY_RUB :Nieuwe Russische Roebel (RUB) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Wegvoertuigen @@ -1147,7 +1150,7 @@ STR_CONFIG_SETTING_RUNNING_COSTS :Onderhoudskoste STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Het niveau van onderhoud en bedrijfskosten van voertuigen en infrastuctuur STR_CONFIG_SETTING_CONSTRUCTION_SPEED :Bouwsnelheid: {STRING} STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :Beperk de hoeveelheid bouwactiviteiten voor computerspeler -STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS :Voertuig storingen: {STRING} +STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS :Voertuigstoringen: {STRING} STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS_HELPTEXT :Controle hoe vaak onvoldoende onderhouden voertuigen kapot kunnen gaan STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER :Subsidie indicator: {STRING} STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER_HELPTEXT :Instellen hoeveel wordt betaald voor gesubsidieerde verbindingen @@ -1337,10 +1340,14 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Kleur van het t STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Groen STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Donker groen STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Violet -STR_CONFIG_SETTING_REVERSE_SCROLLING :Omgekeerde scrollrichting: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Gedrag wanneer gescrolld wordt door de map met de rechter muisknop. Indien uitgeschakeld bestuurd de muis de camera. Indien ingeschakeld bestuurd de muis de kaart. +STR_CONFIG_SETTING_SCROLLMODE :Bekijk scrollgedrag: {STRING} +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Gedrag tijdens het scrollen van de kaart +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Verplaats kijkvenster met RMB, muispositie staat vast +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Verplaats kaart met RMB, muispositie staat vast +STR_CONFIG_SETTING_SCROLLMODE_RMB :Verplaats kaart met RMB +STR_CONFIG_SETTING_SCROLLMODE_LMB :Verplaats kaart met LMB STR_CONFIG_SETTING_SMOOTH_SCROLLING :Vloeiend scrollen kijkvenster: {STRING} -STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Bepalen hoe de hoofdweergave schuift naar een specifieke positie bij het klikken op de minikaart of bij de afgifte van een opdracht om naar een specifiek object op de kaart. Indien ingeschakeld, de viewport scrollt soepel, als deze uitgeschakeld gaat u rechtstreeks naar de beoogde plek +STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Bepalen hoe de hoofdweergave naar een specifieke positie schuift bij het klikken op de minikaart of bij het uitvoeren van een commando om naar een specifiek object op de kaart te scrollen. Indien ingeschakeld, dan scrollt het kijkvenster soepel, als deze uitgeschakeld gaat u rechtstreeks naar de beoogde plek STR_CONFIG_SETTING_MEASURE_TOOLTIP :Toon dimensie-informatie bij het gebruik van diverse bouwgereedschappen: {STRING} STR_CONFIG_SETTING_MEASURE_TOOLTIP_HELPTEXT :Geef tegelafstanden en hoogteverschillen weer bij het slepen tijdens het bouwen STR_CONFIG_SETTING_LIVERIES :Laat alle voertuigkleuren zien: {STRING} @@ -1370,8 +1377,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command-klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Uit -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Scrollen met linkermuisknop: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Schakel scrollen met de linkermuisknop in door te slepen. Dit is vooral handig bij het gebruik van een touchscreen voor scrollen STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Sluit window met rechts-klik: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Sluit een venster door met de rechtermuisknop erin te klikken. Schakelt de tooltip uit met de rechtermuisknop! @@ -1510,7 +1515,7 @@ STR_CONFIG_SETTING_NEWS_CHANGES_ACCEPTANCE_HELPTEXT :Toon een berich STR_CONFIG_SETTING_NEWS_SUBSIDIES :Subsidies: {STRING} STR_CONFIG_SETTING_NEWS_SUBSIDIES_HELPTEXT :Toon een krant over subsidie gerelateerde gebeurtenissen STR_CONFIG_SETTING_NEWS_GENERAL_INFORMATION :Algemene informatie: {STRING} -STR_CONFIG_SETTING_NEWS_GENERAL_INFORMATION_HELPTEXT :Weergave krant over algemene gebeurtenissen, zoals de aankoop van exclusieve rechten of financiering van weg-reconstructie +STR_CONFIG_SETTING_NEWS_GENERAL_INFORMATION_HELPTEXT :Geef krant weer over algemene gebeurtenissen, zoals de aankoop van exclusieve rechten of financiering van wegherstelling STR_CONFIG_SETTING_NEWS_MESSAGES_OFF :Uit STR_CONFIG_SETTING_NEWS_MESSAGES_SUMMARY :Samengevat @@ -1518,7 +1523,7 @@ STR_CONFIG_SETTING_NEWS_MESSAGES_FULL :Volledig STR_CONFIG_SETTING_COLOURED_NEWS_YEAR :Kleurenfoto's komen in: {STRING} STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT :Jaar dat de krant aankondigt in kleur te gaan afdrukken. Voor dit jaar wordt zwart-wit gebruikt -STR_CONFIG_SETTING_STARTING_YEAR :Beginjaar: {STRING} +STR_CONFIG_SETTING_STARTING_YEAR :Startjaar: {STRING} STR_CONFIG_SETTING_SMOOTH_ECONOMY :Vloeiende economie inschakelen (meer, kleinere veranderingen): {STRING} STR_CONFIG_SETTING_SMOOTH_ECONOMY_HELPTEXT :Wanneer ingeschakeld, industrie produktie verandert vaker en in kleinere stappen. Deze instelling heeft meestal geen effect, als de industrie soorten worden geleverd door een NewGRF STR_CONFIG_SETTING_ALLOW_SHARES :Sta het kopen van aandelen van andere bedrijven toe: {STRING} @@ -1736,7 +1741,7 @@ STR_INTRO_SCENARIO_EDITOR :{BLACK}Scenario STR_INTRO_MULTIPLAYER :{BLACK}Multiplayer STR_INTRO_GAME_OPTIONS :{BLACK}Spelopties -STR_INTRO_HIGHSCORE :{BLACK}Score tabel +STR_INTRO_HIGHSCORE :{BLACK}Scoretabel STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Instellingen STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF-instellingen STR_INTRO_ONLINE_CONTENT :{BLACK}Online inhoud zoeken @@ -1748,7 +1753,7 @@ STR_INTRO_TOOLTIP_LOAD_GAME :{BLACK}Laad een STR_INTRO_TOOLTIP_PLAY_HEIGHTMAP :{BLACK}Start een nieuw spel, gebruik een hoogtekaart als landschap STR_INTRO_TOOLTIP_PLAY_SCENARIO :{BLACK}Start een nieuw spel, gebaseerd op een scenario STR_INTRO_TOOLTIP_SCENARIO_EDITOR :{BLACK}Maak een eigen spelwereld/scenario -STR_INTRO_TOOLTIP_MULTIPLAYER :{BLACK}Start een multiplayer spel +STR_INTRO_TOOLTIP_MULTIPLAYER :{BLACK}Start een multiplayerspel STR_INTRO_TOOLTIP_TEMPERATE :{BLACK}Kies gematigd klimaat STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE :{BLACK}Kies subarctisch klimaat @@ -1756,7 +1761,7 @@ STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE :{BLACK}Kies sub STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE :{BLACK}Kies speelgoedlandschap STR_INTRO_TOOLTIP_GAME_OPTIONS :{BLACK}Toon spelopties -STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Toon score tabel +STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Toon scoretabel STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Scherminstellingen STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Toon NewGRF-instellingen STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Zoeken naar nieuwe en aangepaste inhoud om te downloaden @@ -1816,7 +1821,7 @@ STR_LIVERY_TRAIN_TOOLTIP :{BLACK}Toon kle STR_LIVERY_ROAD_VEHICLE_TOOLTIP :{BLACK}Toon kleurenschema's voor wegvoertuigen STR_LIVERY_SHIP_TOOLTIP :{BLACK}Toon kleurenschema's voor schepen STR_LIVERY_AIRCRAFT_TOOLTIP :{BLACK}Toon kleurenschema's voor vliegtuigen -STR_LIVERY_PRIMARY_TOOLTIP :{BLACK}Kies de hoofdkleur voor het geselecteerde schema. Ctrl+klik deze kleu bij alle schema's gebruiken +STR_LIVERY_PRIMARY_TOOLTIP :{BLACK}Kies de hoofdkleur voor het geselecteerde schema. Ctrl+klik zal deze kleur instellen voor elk schema STR_LIVERY_SECONDARY_TOOLTIP :{BLACK}Kies de tweede kleur voor het geselecteerde schema. Ctrl+klik om deze kleur in alle schema's te gebruiken STR_LIVERY_PANEL_TOOLTIP :{BLACK}Kies een kleurenschema om te wijzigen, of meerdere schema's met Ctrl+klik. Vink de keuzevakjes aan/uit om het gebruik van het schema aan/uit te zetten @@ -1824,8 +1829,8 @@ STR_LIVERY_DEFAULT :Standaard kleur STR_LIVERY_STEAM :Stoomlocomotief STR_LIVERY_DIESEL :Diesellocomotief STR_LIVERY_ELECTRIC :Elektrische locomotief -STR_LIVERY_MONORAIL :Monorail-locomotief -STR_LIVERY_MAGLEV :Zweeftrein-locomotief +STR_LIVERY_MONORAIL :Monoraillocomotief +STR_LIVERY_MAGLEV :Zweeftreinlocomotief STR_LIVERY_DMU :Dieseltreinstel STR_LIVERY_EMU :Elektrisch treinstel STR_LIVERY_PASSENGER_WAGON_STEAM :Passagierswagon (Stoom) @@ -1905,7 +1910,7 @@ STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Verander # Network server list STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Multiplayer STR_NETWORK_SERVER_LIST_ADVERTISED :{BLACK}Openbaar -STR_NETWORK_SERVER_LIST_ADVERTISED_TOOLTIP :{BLACK}Kies tussen een openbaar (internet) en een niet openbaar (Local Area Network, LAN) spel +STR_NETWORK_SERVER_LIST_ADVERTISED_TOOLTIP :{BLACK}Kies tussen een openbaar (internet) en een niet-openbaar (Local Area Network, LAN) spel STR_NETWORK_SERVER_LIST_ADVERTISED_NO :Nee STR_NETWORK_SERVER_LIST_ADVERTISED_YES :Ja STR_NETWORK_SERVER_LIST_PLAYER_NAME :{BLACK}Spelersnaam: @@ -1959,10 +1964,10 @@ STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Vul je n STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}Voer het IP-adres van de server in # Start new multiplayer server -STR_NETWORK_START_SERVER_CAPTION :{WHITE}Start nieuw multiplayer spel +STR_NETWORK_START_SERVER_CAPTION :{WHITE}Start nieuw multiplayerspel STR_NETWORK_START_SERVER_NEW_GAME_NAME :{BLACK}Spelnaam: -STR_NETWORK_START_SERVER_NEW_GAME_NAME_TOOLTIP :{BLACK}De spelnaam wordt weergegeven aan andere spelers in het multiplayer-spelselectie menu +STR_NETWORK_START_SERVER_NEW_GAME_NAME_TOOLTIP :{BLACK}De spelnaam wordt weergegeven aan andere spelers in het multiplayerspelselectiemenu STR_NETWORK_START_SERVER_SET_PASSWORD :{BLACK}Kies wachtwoord STR_NETWORK_START_SERVER_PASSWORD_TOOLTIP :{BLACK}Bescherm je spel met een wachtwoord als je niet wilt dat deze algemeen toegankelijk is @@ -1980,7 +1985,7 @@ STR_NETWORK_START_SERVER_NUMBER_OF_SPECTATORS_TOOLTIP :{BLACK}Beperk d STR_NETWORK_START_SERVER_LANGUAGE_SPOKEN :{BLACK}Gesproken taal: STR_NETWORK_START_SERVER_LANGUAGE_TOOLTIP :{BLACK}Andere spelers zullen weten welke taal er wordt gesproken op de server -STR_NETWORK_START_SERVER_NEW_GAME_NAME_OSKTITLE :{BLACK}Geef de naam van het netwerk spel +STR_NETWORK_START_SERVER_NEW_GAME_NAME_OSKTITLE :{BLACK}Geef de naam van het netwerkspel # Network game languages ############ Leave those lines in this order!! @@ -2016,7 +2021,7 @@ STR_NETWORK_LANG_UKRAINIAN :Oekraïens STR_NETWORK_LANG_AFRIKAANS :Afrikaans STR_NETWORK_LANG_CROATIAN :Kroatisch STR_NETWORK_LANG_CATALAN :Catalaans -STR_NETWORK_LANG_ESTONIAN :Ests +STR_NETWORK_LANG_ESTONIAN :Estisch STR_NETWORK_LANG_GALICIAN :Galiciaans STR_NETWORK_LANG_GREEK :Grieks STR_NETWORK_LANG_LATVIAN :Lets @@ -2030,7 +2035,7 @@ STR_NETWORK_GAME_LOBBY_COMPANY_LIST_TOOLTIP :{BLACK}Een lijs STR_NETWORK_GAME_LOBBY_COMPANY_INFO :{SILVER}BEDRIJFSINFORMATIE STR_NETWORK_GAME_LOBBY_COMPANY_NAME :{SILVER}Bedrijfsnaam: {WHITE}{STRING} -STR_NETWORK_GAME_LOBBY_INAUGURATION_YEAR :{SILVER}Begonnen in: {WHITE}{NUM} +STR_NETWORK_GAME_LOBBY_INAUGURATION_YEAR :{SILVER}Gestart in: {WHITE}{NUM} STR_NETWORK_GAME_LOBBY_VALUE :{SILVER}Bedrijfswaarde: {WHITE}{CURRENCY_LONG} STR_NETWORK_GAME_LOBBY_CURRENT_BALANCE :{SILVER}Huidige kas: {WHITE}{CURRENCY_LONG} STR_NETWORK_GAME_LOBBY_LAST_YEARS_INCOME :{SILVER}Inkomen vorig jaar: {WHITE}{CURRENCY_LONG} @@ -2054,8 +2059,8 @@ STR_NETWORK_CONNECTING_CAPTION :{WHITE}Verbinde STR_NETWORK_CONNECTING_1 :{BLACK}(1/6) Verbinden... STR_NETWORK_CONNECTING_2 :{BLACK}(2/6) Inloggen... STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Wachten... -STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Downloaden kaart... -STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Verwerken gegevens... +STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Kaart downloaden... +STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Gegevens verwerken... STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Registreren... STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Spelinformatie ophalen... @@ -2115,20 +2120,20 @@ STR_NETWORK_CHAT_TO_COMPANY :[Team] Aan {STR STR_NETWORK_CHAT_CLIENT :[Privé] {STRING}: {WHITE}{STRING} STR_NETWORK_CHAT_TO_CLIENT :[Privé] Aan {STRING}: {WHITE}{STRING} STR_NETWORK_CHAT_ALL :[Iedereen] {STRING}: {WHITE}{STRING} -STR_NETWORK_CHAT_OSKTITLE :{BLACK}Geef de tekst voor de netwerk-chat +STR_NETWORK_CHAT_OSKTITLE :{BLACK}Geef tekst voor netwerkchat # Network messages STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Geen netwerkapparaten gevonden of gecompileerd zonder ENABLE_NETWORK STR_NETWORK_ERROR_NOSERVER :{WHITE}Kon geen enkel netwerkspel vinden STR_NETWORK_ERROR_NOCONNECTION :{WHITE}De server beantwoordde het verzoek niet -STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Kan geen verbinding maken, je hebt niet dezelfde NewGRF bestanden als de server +STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Kan geen verbinding maken, je hebt niet dezelfde NewGRF-bestanden als de server STR_NETWORK_ERROR_DESYNC :{WHITE}Synchronisatie van netwerkspel mislukt STR_NETWORK_ERROR_LOSTCONNECTION :{WHITE}Verbinding met netwerkspel kwijt STR_NETWORK_ERROR_SAVEGAMEERROR :{WHITE}Kon opgeslagen spel niet laden STR_NETWORK_ERROR_SERVER_START :{WHITE}Kan server niet starten STR_NETWORK_ERROR_CLIENT_START :{WHITE}Kan geen verbinding maken STR_NETWORK_ERROR_TIMEOUT :{WHITE}Verbinding #{NUM} duurde te lang -STR_NETWORK_ERROR_SERVER_ERROR :{WHITE}Er is een protocolfout gemaakt en onze verbinding is gesloten +STR_NETWORK_ERROR_SERVER_ERROR :{WHITE}Er is een protocolfout gedetecteerd en de verbinding werd gesloten STR_NETWORK_ERROR_WRONG_REVISION :{WHITE}De revisie van deze client komt niet overeen met de revisie van de server STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}Ongeldig wachtwoord STR_NETWORK_ERROR_SERVER_FULL :{WHITE}De server is vol @@ -2137,9 +2142,9 @@ STR_NETWORK_ERROR_KICKED :{WHITE}Je bent STR_NETWORK_ERROR_CHEATER :{WHITE}Valsspelen is niet toegestaan op deze server STR_NETWORK_ERROR_TOO_MANY_COMMANDS :{WHITE}Je stuurde te veel commando's naar de server STR_NETWORK_ERROR_TIMEOUT_PASSWORD :{WHITE}Het invoeren van het wachtwoord duurde te lang -STR_NETWORK_ERROR_TIMEOUT_COMPUTER :{WHITE}Het duurde jouw computer te lang totdat uw computer zich aanmeldde -STR_NETWORK_ERROR_TIMEOUT_MAP :{WHITE}Het duurde jouw computer te lang om de kaart te downloaden -STR_NETWORK_ERROR_TIMEOUT_JOIN :{WHITE}Het duurde jouw computer te lang om met de server te verbinden +STR_NETWORK_ERROR_TIMEOUT_COMPUTER :{WHITE}Uw computer is te traag om de server bij te houden +STR_NETWORK_ERROR_TIMEOUT_MAP :{WHITE}Uw computer deed er te lang over om de kaart te downloaden +STR_NETWORK_ERROR_TIMEOUT_JOIN :{WHITE}Uw computer deed er te lang over om met de server te verbinden ############ Leave those lines in this order!! STR_NETWORK_ERROR_CLIENT_GENERAL :algemene fout @@ -2159,7 +2164,7 @@ STR_NETWORK_ERROR_CLIENT_CHEATER :probeerde vals STR_NETWORK_ERROR_CLIENT_SERVER_FULL :server is vol STR_NETWORK_ERROR_CLIENT_TOO_MANY_COMMANDS :stuurde te veel commando's STR_NETWORK_ERROR_CLIENT_TIMEOUT_PASSWORD :wachtwoord niet op tijd ontvangen -STR_NETWORK_ERROR_CLIENT_TIMEOUT_COMPUTER :algemene timeout +STR_NETWORK_ERROR_CLIENT_TIMEOUT_COMPUTER :algemene time-out STR_NETWORK_ERROR_CLIENT_TIMEOUT_MAP :downloaden van de kaart duurde te lang STR_NETWORK_ERROR_CLIENT_TIMEOUT_JOIN :verwerken van de kaart duurde te lang ############ End of leave-in-this-order @@ -2174,12 +2179,12 @@ STR_NETWORK_SERVER_MESSAGE_GAME_PAUSED :Spel gepauzeerd STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_1 :Spel nog steeds gepauzeerd ({STRING}) STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_2 :Spel nog steeds gepauzeerd ({STRING}, {STRING}) STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_3 :Spel nog steeds gepauzeerd ({STRING}, {STRING}, {STRING}) -STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_4 :Spel is nog steeds gepauzeerd ({STRING}, {STRING}, {STRING}, {STRING}) +STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_4 :Spel nog steeds gepauzeerd ({STRING}, {STRING}, {STRING}, {STRING}) STR_NETWORK_SERVER_MESSAGE_GAME_UNPAUSED :Spel vervolgd ({STRING}) STR_NETWORK_SERVER_MESSAGE_GAME_REASON_NOT_ENOUGH_PLAYERS :aantal spelers STR_NETWORK_SERVER_MESSAGE_GAME_REASON_CONNECTING_CLIENTS :spelers maken verbinding STR_NETWORK_SERVER_MESSAGE_GAME_REASON_MANUAL :handmatig -STR_NETWORK_SERVER_MESSAGE_GAME_REASON_GAME_SCRIPT :spel script +STR_NETWORK_SERVER_MESSAGE_GAME_REASON_GAME_SCRIPT :spelscript ############ End of leave-in-this-order STR_NETWORK_MESSAGE_CLIENT_LEAVING :vertrekt STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} heeft zich bij het spel gevoegd @@ -2191,8 +2196,8 @@ STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} he STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} heeft zijn/haar naam gewijzigd naar {STRING} STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} gaf je bedrijf {2:CURRENCY_LONG} STR_NETWORK_MESSAGE_GAVE_MONEY_AWAY :*** Je gaf {2:CURRENCY_LONG} aan {1:STRING} -STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}De server heeft de sessie gestopt -STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}De server wordt opnieuw gestart...{}Wacht aub... +STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}De server heeft de sessie gesloten +STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}De server wordt opnieuw gestart...{}Wacht alstublieft... # Content downloading window STR_CONTENT_TITLE :{WHITE}Download extra content @@ -2263,7 +2268,7 @@ STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD_FILE_NOT_WRITABLE :{WHITE}... best STR_CONTENT_ERROR_COULD_NOT_EXTRACT :{WHITE}Kon gedownload bestand niet uitpakken STR_MISSING_GRAPHICS_SET_CAPTION :{WHITE}Ontbrekende graphics -STR_MISSING_GRAPHICS_SET_MESSAGE :{BLACK}OpenTTD heeft graphics nodig om te kunnen werken, maar er konden er geen gevonden worden. Wilt u toestaan dat OpenTTD graphics downloadt en installeert? +STR_MISSING_GRAPHICS_SET_MESSAGE :{BLACK}OpenTTD heeft graphics nodig om te kunnen werken, maar er konden er geen gevonden worden. Staat u toe dat OpenTTD deze graphics downloadt en installeert? STR_MISSING_GRAPHICS_YES_DOWNLOAD :{BLACK}Ja, download de graphics STR_MISSING_GRAPHICS_NO_QUIT :{BLACK}Nee, OpenTTD afsluiten @@ -2281,10 +2286,11 @@ STR_TRANSPARENT_LOADING_TOOLTIP :{BLACK}Schakel STR_TRANSPARENT_INVISIBLE_TOOLTIP :{BLACK}Maak objecten onzichtbaar in plaats van transparant # Linkgraph legend window -STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Vracht Stroom Legenda +STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Vrachtstroomlegende STR_LINKGRAPH_LEGEND_ALL :{BLACK}Alle STR_LINKGRAPH_LEGEND_NONE :{BLACK}Geen STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Selecteer weer te geven bedrijven +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}ongebruikt @@ -2310,8 +2316,8 @@ STR_JOIN_WAYPOINT_CREATE_SPLITTED_WAYPOINT :{YELLOW}Bouw ee # Rail construction toolbar STR_RAIL_TOOLBAR_RAILROAD_CONSTRUCTION_CAPTION :Bouw spoorwegen STR_RAIL_TOOLBAR_ELRAIL_CONSTRUCTION_CAPTION :Bouw geëlektrificeerde spoorwegen -STR_RAIL_TOOLBAR_MONORAIL_CONSTRUCTION_CAPTION :Bouw monorail-spoorwegen -STR_RAIL_TOOLBAR_MAGLEV_CONSTRUCTION_CAPTION :Bouw magneetzweeftrein-spoorwegen +STR_RAIL_TOOLBAR_MONORAIL_CONSTRUCTION_CAPTION :Bouw monorailspoorwegen +STR_RAIL_TOOLBAR_MAGLEV_CONSTRUCTION_CAPTION :Bouw magneetzweeftreinspoorwegen STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Plaats spoor. Ctrl schakelt tussen bouwen/verwijderen van het spoor. Shift schakelt tussen bouwen/inschatting van de kosten STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}Bouw spoor met de Autorail-methode. Ctrl schakelt tussen bouwen/verwijderen van het spoor. Shift schakelt tussen bouwen/inschatting van de kosten @@ -2325,7 +2331,7 @@ STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Kies tus STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL :{BLACK}Verander spoortype. Shift schakelt tussen bouwen/inschatting van de kosten STR_RAIL_NAME_RAILROAD :Spoorweg -STR_RAIL_NAME_ELRAIL :Spoorweg met bovenleiding +STR_RAIL_NAME_ELRAIL :Geëlektrificeerde spoorweg STR_RAIL_NAME_MONORAIL :Monorail STR_RAIL_NAME_MAGLEV :Zweeftrein @@ -2362,9 +2368,9 @@ STR_BUILD_SIGNAL_SEMAPHORE_EXIT_TOOLTIP :{BLACK}Uitgangs STR_BUILD_SIGNAL_SEMAPHORE_COMBO_TOOLTIP :{BLACK}Combinatiesein (armsein){}Het combinatiesein gedraagt zich als zowel ingangs- als uitgangssein. Zo kun je grote netwerken van beginseinen maken STR_BUILD_SIGNAL_SEMAPHORE_PBS_TOOLTIP :{BLACK}Routesein (armsein){}Een routesein laat meer dan één trein tegelijk in een seinblok toe als de trein een route kan reserveren naar een veilige stopplaats. Routeseinen kunnen van achteren worden gepasseerd STR_BUILD_SIGNAL_SEMAPHORE_PBS_OWAY_TOOLTIP :{BLACK}Eenrichtingsrouteseinen (armsein){}Een routesein laat meer dan één trein tegelijk in een seinblok toe als de trein een route kan reserveren naar een veilige stopplaats. Eenrichtingsrouteseinen kunnen niet van achteren worden gepasseerd -STR_BUILD_SIGNAL_ELECTRIC_NORM_TOOLTIP :{BLACK}Standaard sein (elektrisch){}Seinen zijn nodig om te voorkomen dat treinen botsen bij netwerken met meer dan één trein +STR_BUILD_SIGNAL_ELECTRIC_NORM_TOOLTIP :{BLACK}Standaardsein (elektrisch){}Seinen zijn nodig om te voorkomen dat treinen botsen bij netwerken met meer dan één trein STR_BUILD_SIGNAL_ELECTRIC_ENTRY_TOOLTIP :{BLACK}Ingangssein (elektrisch){}Groen als er meer dan één groen uitgangssein is in de volgende sectie. Anders is deze rood -STR_BUILD_SIGNAL_ELECTRIC_EXIT_TOOLTIP :{BLACK}Uitgangssein (elektrisch){}Gedraagt zich hetzelfde als een standaard sein, maar is nodig om ingangs- & combinatie-seinen aan te sturen +STR_BUILD_SIGNAL_ELECTRIC_EXIT_TOOLTIP :{BLACK}Uitgangssein (elektrisch){}Gedraagt zich hetzelfde als een standaardsein, maar is nodig om ingangs- & combinatie-seinen aan te sturen STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Combinatiesein (elektrisch){}Het combinatiesein gedraagt zich als zowel ingangs- als uitgangssein. Zo kun je grote netwerken van beginseinen maken STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}Routeseinen (elektrisch){}Een routesein laat meer dan één trein tegelijk op een seinblok toe als de trein een route kan reserveren naar een veilige stopplaats. Routeseinen kunnen van achteren worden gepasseerd STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP :{BLACK}Eenrichtingsrouteseinen (elektrisch){}Een routesein laat meer dan één trein tegelijk op een seinblok toe als de trein een route kan reserveren naar een veilige stopplaats. Eenrichtingsrouteseinen kunnen niet van achteren worden gepasseerd @@ -2375,13 +2381,13 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Vergroot # Bridge selection window STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Kies type spoorbrug -STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Kies type brug +STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Kies type wegbrug STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Brugkeuze - klik op de gewenste brug om die te bouwen STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Hangend, Staal STR_BRIDGE_NAME_GIRDER_STEEL :Koker, Staal -STR_BRIDGE_NAME_CANTILEVER_STEEL :Cantilever, Staal +STR_BRIDGE_NAME_CANTILEVER_STEEL :Vrijdragend, Staal STR_BRIDGE_NAME_SUSPENSION_CONCRETE :Hangend, Beton STR_BRIDGE_NAME_WOODEN :Hout STR_BRIDGE_NAME_CONCRETE :Beton @@ -2391,24 +2397,24 @@ STR_BRIDGE_TUBULAR_SILICON :Buis, Silicium # Road construction toolbar STR_ROAD_TOOLBAR_ROAD_CONSTRUCTION_CAPTION :{WHITE}Bouw wegen -STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION :{WHITE}Bouw tramwegen +STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION :{WHITE}Bouw tramsporen STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION :{BLACK}Bouw weg. Ctrl schakelt tussen bouwen/verwijderen van de weg. Shift schakelt tussen bouwen/inschatting van de kosten -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION :{BLACK}Bouw tramrails. Ctrl schakelt tussen bouwen/verwijderen van tramrails. Shift schakelt tussen bouwen/inschatting van de kosten +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION :{BLACK}Bouw tramsporen. Ctrl schakelt tussen bouwen/verwijderen van tramsporen. Shift schakelt tussen bouwen/inschatting van de kosten STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD :{BLACK}Bouw weg met de Autoroad-methode. Ctrl schakelt tussen bouwen/verwijderen van de weg. Shift schakelt tussen bouwen/inschatting van de kosten -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM :{BLACK}Bouw tramrails met de Autotram-methode. Ctrl schakelt tussen bouwen/verwijderen van tramrails. Shift schakelt tussen bouwen/inschatting van de kosten +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM :{BLACK}Bouw tramsporen met de Autotram-methode. Ctrl schakelt tussen bouwen/verwijderen van tramrails. Shift schakelt tussen bouwen/inschatting van de kosten STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Bouw garage (voor het kopen en onderhouden van wegvoertuigen). Shift schakelt tussen bouwen/inschatting van de kosten STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT :{BLACK}Bouw tramdepot (voor het kopen en onderhouden van trams). Shift schakelt tussen bouwen/inschatting van de kosten STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION :{BLACK}Bouw bushalte. Houd Ctrl ingedrukt om samen te voegen met ander station. Shift schakelt tussen bouwen/inschatting van de kosten -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION :{BLACK}Bouw passagiertramhalte. Houd Ctrl ingedrukt om samen te voegen met ander station. Shift schakelt tussen bouwen/inschatting van de kosten +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION :{BLACK}Bouw passagierstramhalte. Houd Ctrl ingedrukt om samen te voegen met ander station. Shift schakelt tussen bouwen/inschatting van de kosten STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY :{BLACK}Bouw vrachtwagenlaadhal. Houd Ctrl ingedrukt om samen te voegen met ander station. Shift schakelt tussen bouwen/inschatting van de kosten STR_ROAD_TOOLBAR_TOOLTIP_BUILD_CARGO_TRAM_STATION :{BLACK}Bouw vrachttramhalte. Houd Ctrl ingedrukt om samen te voegen met ander station. Shift schakelt tussen bouwen/inschatting van de kosten STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD :{BLACK}Activeer/Deactiveer eenrichtingsverkeer -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE :{BLACK}Bouw viaduct. Shift schakelt tussen bouwen/inschatting van de kosten -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE :{BLACK}Bouw brug voor tramrails. Shift schakelt tussen bouwen/inschatting van de kosten +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE :{BLACK}Bouw wegbrug. Shift schakelt tussen bouwen/inschatting van de kosten +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE :{BLACK}Bouw brug voor tramsporen. Shift schakelt tussen bouwen/inschatting van de kosten STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Bouw wegtunnel. Shift schakelt tussen bouwen/inschatting van de kosten STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Bouw tramtunnel. Shift schakelt tussen bouwen/inschatting van de kosten STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Kies tussen bouwen en verwijderen bij wegenbouw -STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Kies tussen bouwen en verwijderen bij tramrailaanleg +STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Kies tussen bouwen en verwijderen bij tramspooraanleg # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Richting van garage @@ -2452,12 +2458,12 @@ STR_TOOLBAR_AIRCRAFT_BUILD_AIRPORT_TOOLTIP :{BLACK}Bouw vli # Airport construction window STR_STATION_BUILD_AIRPORT_CAPTION :{WHITE}Keuze van vliegveld STR_STATION_BUILD_AIRPORT_TOOLTIP :{BLACK}Kies grootte en type van vliegveld -STR_STATION_BUILD_AIRPORT_CLASS_LABEL :{BLACK}Vliegveld klasse +STR_STATION_BUILD_AIRPORT_CLASS_LABEL :{BLACK}Vliegveldklasse STR_STATION_BUILD_AIRPORT_LAYOUT_NAME :{BLACK}Layout {NUM} STR_AIRPORT_SMALL :Klein STR_AIRPORT_CITY :Stad -STR_AIRPORT_METRO :Hoofdstedelijk +STR_AIRPORT_METRO :Grootstedelijk STR_AIRPORT_INTERNATIONAL :Internationaal vliegveld STR_AIRPORT_COMMUTER :Pendel STR_AIRPORT_INTERCONTINENTAL :Intercontinentaal @@ -2487,11 +2493,11 @@ STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Bekijk h STR_OBJECT_BUILD_SIZE :{BLACK}Grootte: {GOLD}{NUM} x {NUM} tegels STR_OBJECT_CLASS_LTHS :Vuurtorens -STR_OBJECT_CLASS_TRNS :Zender +STR_OBJECT_CLASS_TRNS :Zendmasten # Tree planting window (last two for SE only) STR_PLANT_TREE_CAPTION :{WHITE}Bomen -STR_PLANT_TREE_TOOLTIP :{BLACK}Kies een soort boom om te planten. Als de tegel al bomen bevat zullen er meer bomen van verschillende types bij komen, onafhankelijk van het geselecteerde type. +STR_PLANT_TREE_TOOLTIP :{BLACK}Kies een soort boom om te planten. Als de tegel al bomen bevat, zullen er meer bomen van verschillende types bijkomen, onafhankelijk van het geselecteerde type. STR_TREES_RANDOM_TYPE :{BLACK}Willekeurige soorten bomen STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Plant bomen van willekeurige soort. Shift+klik wisselt tussen bouwen/toont verwachte kosten STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Willekeurige bomen @@ -2579,21 +2585,21 @@ STR_LAND_AREA_INFORMATION_OWNER_N_A :Geen STR_LAND_AREA_INFORMATION_OWNER :{BLACK}Eigenaar: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_ROAD_OWNER :{BLACK}Eigenaar van weg: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Eigenaar van tramrails: {LTBLUE}{STRING} -STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Spoorweg eigenaar: {LTBLUE}{STRING} +STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Eigenaar van spoorweg: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Gemeente: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Geen STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coördinaten: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Bouwjaar: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Stationsklasse: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Stationstype: {LTBLUE}{STRING} -STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Vliegveld klasse: {LTBLUE}{STRING} -STR_LAND_AREA_INFORMATION_AIRPORT_NAME :{BLACK}Vliegveld naam: {LTBLUE}{STRING} -STR_LAND_AREA_INFORMATION_AIRPORTTILE_NAME :{BLACK}Vliegveld tegel naam: {LTBLUE}{STRING} +STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Vliegveldklasse: {LTBLUE}{STRING} +STR_LAND_AREA_INFORMATION_AIRPORT_NAME :{BLACK}Vliegveldnaam: {LTBLUE}{STRING} +STR_LAND_AREA_INFORMATION_AIRPORTTILE_NAME :{BLACK}Vliegveldtegelnaam: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Geaccepteerde vracht: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) -STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Rail type: {LTBLUE}{STRING} -STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Spoor snelheidslimiet: {LTBLUE}{VELOCITY} +STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Spoortype: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Spoorsnelheidslimiet: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Snelheidslimiet weg: {LTBLUE}{VELOCITY} # Description of land area of different tiles @@ -2605,35 +2611,35 @@ STR_LAI_CLEAR_DESCRIPTION_FIELDS :Akkers STR_LAI_CLEAR_DESCRIPTION_SNOW_COVERED_LAND :Sneeuw STR_LAI_CLEAR_DESCRIPTION_DESERT :Woestijn -STR_LAI_RAIL_DESCRIPTION_TRACK :Spoorweg spoor -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_SIGNALS :Spoorweg spoor met blokseinen -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRESIGNALS :Spoorweg spoor met voorseinen -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXITSIGNALS :Spoorweg spoor met exitseinen -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBOSIGNALS :Spoorweg spoor met combo-seinen -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBSSIGNALS :Spoorweg spoor met routeseinen -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NOENTRYSIGNALS :Spoorweg spoor met eenrichtingsseinen -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PRESIGNALS :Spoorweg spoor met blok en voorseinen -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_EXITSIGNALS :Spoorweg spoor met blok en exitseinen -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_COMBOSIGNALS :Spoorweg spoor met blok en combo-seinen -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PBSSIGNALS :Spoorweg spoor met blok en routeseinen -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_NOENTRYSIGNALS :Spoorweg spoor met blok en eenrichtingsseinen -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_EXITSIGNALS :Spoorweg spoor met voor- en exitseinen -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_COMBOSIGNALS :Spoorweg spoor met voor- en combo-seinen -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_PBSSIGNALS :Spoorweg spoor met voor- en routeseinen -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_NOENTRYSIGNALS :Spoorweg spoor met voor- en eenrichtingsseinen -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_COMBOSIGNALS :Spoorweg spoor met exit- en combo-seinen +STR_LAI_RAIL_DESCRIPTION_TRACK :Spoor +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_SIGNALS :Spoor met blokseinen +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRESIGNALS :Spoor met voorseinen +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXITSIGNALS :Spoor met uitgangsseinen +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBOSIGNALS :Spoor met combinatieseinen +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBSSIGNALS :Spoor met routeseinen +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NOENTRYSIGNALS :Spoor met eenrichtingsseinen +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PRESIGNALS :Spoor met blok- en voorseinen +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_EXITSIGNALS :Spoor met blok- en uitgangsseinen +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_COMBOSIGNALS :Spoor met blok- en combinatieseinen +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PBSSIGNALS :Spoor met blok- en routeseinen +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_NOENTRYSIGNALS :Spoor met blok- en eenrichtingsseinen +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_EXITSIGNALS :Spoor met voor- en uitgangsseinen +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_COMBOSIGNALS :Spoor met voor- en combinatieseinen +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_PBSSIGNALS :Spoor met voor- en routeseinen +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_NOENTRYSIGNALS :Spoor met voor- en eenrichtingsseinen +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_COMBOSIGNALS :Spoor met uitgangs- en combinatieseinen STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_PBSSIGNALS :Spoorweg spoor met exit- en routeseinen -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_NOENTRYSIGNALS :Spoorweg spoor met exit- en eenrichtingsseinen -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_PBSSIGNALS :Spoorweg spoor met combo- en routeseinen -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_NOENTRYSIGNALS :Spoorweg Spoor met combo- en eenrichtingssein -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBS_NOENTRYSIGNALS :Spoorweg spoor met route en eenrichtingssein -STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT :Spoorweg trein depot +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_NOENTRYSIGNALS :Spoor met uitgangs- en eenrichtingsseinen +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_PBSSIGNALS :Spoor met combinatie- en routeseinen +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_NOENTRYSIGNALS :Spoor met combinatie- en eenrichtingsseinen +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBS_NOENTRYSIGNALS :Spoor met route- en eenrichtingsseinen +STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT :Spoorwegtreindepot STR_LAI_ROAD_DESCRIPTION_ROAD :Weg STR_LAI_ROAD_DESCRIPTION_ROAD_WITH_STREETLIGHTS :Weg met straatlantaarns STR_LAI_ROAD_DESCRIPTION_TREE_LINED_ROAD :Weg met bomenrij STR_LAI_ROAD_DESCRIPTION_ROAD_VEHICLE_DEPOT :Garage -STR_LAI_ROAD_DESCRIPTION_ROAD_RAIL_LEVEL_CROSSING :Gelijkvloerse overweg +STR_LAI_ROAD_DESCRIPTION_ROAD_RAIL_LEVEL_CROSSING :Gelijkvloerse kruising met weg/spoor STR_LAI_ROAD_DESCRIPTION_TRAMWAY :Tramrails # Houses come directly from their building names @@ -2664,21 +2670,21 @@ STR_LAI_WATER_DESCRIPTION_SHIP_DEPOT :Dok STR_LAI_TUNNEL_DESCRIPTION_RAILROAD :Spoortunnel STR_LAI_TUNNEL_DESCRIPTION_ROAD :Wegtunnel -STR_LAI_BRIDGE_DESCRIPTION_RAIL_SUSPENSION_STEEL :Stalen hangbrug (spoor) -STR_LAI_BRIDGE_DESCRIPTION_RAIL_GIRDER_STEEL :Stalen kokerbrug (spoor) -STR_LAI_BRIDGE_DESCRIPTION_RAIL_CANTILEVER_STEEL :Stalen cantileverbrug (spoor) -STR_LAI_BRIDGE_DESCRIPTION_RAIL_SUSPENSION_CONCRETE :Hangbrug van gewapend beton (spoor) -STR_LAI_BRIDGE_DESCRIPTION_RAIL_WOODEN :Houten brug (spoor) -STR_LAI_BRIDGE_DESCRIPTION_RAIL_CONCRETE :Betonnen brug (spoor) -STR_LAI_BRIDGE_DESCRIPTION_RAIL_TUBULAR_STEEL :Buisvormige brug (spoor) +STR_LAI_BRIDGE_DESCRIPTION_RAIL_SUSPENSION_STEEL :Stalen hangende spoorbrug +STR_LAI_BRIDGE_DESCRIPTION_RAIL_GIRDER_STEEL :Spoorbrug met stalen koker +STR_LAI_BRIDGE_DESCRIPTION_RAIL_CANTILEVER_STEEL :Stalen vrijdragende spoorbrug +STR_LAI_BRIDGE_DESCRIPTION_RAIL_SUSPENSION_CONCRETE :Hangende spoorbrug van gewapend beton +STR_LAI_BRIDGE_DESCRIPTION_RAIL_WOODEN :Houten spoorbrug +STR_LAI_BRIDGE_DESCRIPTION_RAIL_CONCRETE :Betonnen spoorbrug +STR_LAI_BRIDGE_DESCRIPTION_RAIL_TUBULAR_STEEL :Buisvormige spoorbrug -STR_LAI_BRIDGE_DESCRIPTION_ROAD_SUSPENSION_STEEL :Stalen hangbrug (weg) -STR_LAI_BRIDGE_DESCRIPTION_ROAD_GIRDER_STEEL :Stalen kokerbrug (weg) -STR_LAI_BRIDGE_DESCRIPTION_ROAD_CANTILEVER_STEEL :Stalen cantileverbrug (weg) -STR_LAI_BRIDGE_DESCRIPTION_ROAD_SUSPENSION_CONCRETE :Hangbrug van gewapend beton (weg) -STR_LAI_BRIDGE_DESCRIPTION_ROAD_WOODEN :Houten brug (weg) -STR_LAI_BRIDGE_DESCRIPTION_ROAD_CONCRETE :Betonnen brug (weg) -STR_LAI_BRIDGE_DESCRIPTION_ROAD_TUBULAR_STEEL :Buisvormige brug (weg) +STR_LAI_BRIDGE_DESCRIPTION_ROAD_SUSPENSION_STEEL :Stalen hangende wegbrug +STR_LAI_BRIDGE_DESCRIPTION_ROAD_GIRDER_STEEL :Wegbrug met stalen koker +STR_LAI_BRIDGE_DESCRIPTION_ROAD_CANTILEVER_STEEL :Stalen vrijdragende wegbrug +STR_LAI_BRIDGE_DESCRIPTION_ROAD_SUSPENSION_CONCRETE :Hangende wegbrug van gewapend beton +STR_LAI_BRIDGE_DESCRIPTION_ROAD_WOODEN :Houten wegbrug +STR_LAI_BRIDGE_DESCRIPTION_ROAD_CONCRETE :Betonnen wegbrug +STR_LAI_BRIDGE_DESCRIPTION_ROAD_TUBULAR_STEEL :Buisvormige wegbrug STR_LAI_BRIDGE_DESCRIPTION_AQUEDUCT :Aquaduct @@ -2690,9 +2696,59 @@ STR_LAI_OBJECT_DESCRIPTION_COMPANY_OWNED_LAND :Terrein in bedr # About OpenTTD window STR_ABOUT_OPENTTD :{WHITE}Over OpenTTD STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Originele copyright {COPYRIGHT} 1995 Chris Sawyer, alle rechten voorbehouden -STR_ABOUT_VERSION :{BLACK}OpenTTD versie {REV} +STR_ABOUT_VERSION :{BLACK}OpenTTD-versie {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 Het OpenTTD-team +# Framerate display window +STR_FRAMERATE_CAPTION :{WHITE}Frame rate +STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) +STR_FRAMERATE_RATE_GAMELOOP :{WHITE}Simulatiesnelheid: {STRING} +STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Aantal gesimuleerde gameticks per seconde. +STR_FRAMERATE_RATE_BLITTER :{WHITE}Graphics frame rate: {STRING} +STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Aantal videoframes die weergegeven worden per seconde. +STR_FRAMERATE_SPEED_FACTOR :{WHITE}Huidige spelsnelheidsfactor: {DECIMAL}x +STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Hoe snel het spel momenteel draait, vergeleken met de verwachte snelheid bij een normale simulatiesnelheid. +STR_FRAMERATE_CURRENT :{WHITE}Huidig +STR_FRAMERATE_AVERAGE :{WHITE}Gemiddelde +STR_FRAMERATE_DATA_POINTS :{WHITE}Gegevens gebaseerd op {COMMA} metingen +STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL}{WHITE} ms +STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL}{WHITE} ms +STR_FRAMERATE_MS_BAD :{RED}{DECIMAL}{WHITE} ms +STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL}{WHITE} frames/s +STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL}{WHITE} frames/s +STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL}{WHITE} frames/s +STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms +STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s +############ Leave those lines in this order!! +STR_FRAMERATE_GAMELOOP :{WHITE}Gamelooptotaal: +STR_FRAMERATE_GL_ECONOMY :{WHITE} Cargoafhandeling: +STR_FRAMERATE_GL_TRAINS :{WHITE} Treinticks: +STR_FRAMERATE_GL_ROADVEHS :{WHITE} Wegvoertuigticks: +STR_FRAMERATE_GL_SHIPS :{WHITE} Schipticks: +STR_FRAMERATE_GL_AIRCRAFT :{WHITE} Vliegtuigticks: +STR_FRAMERATE_GL_LANDSCAPE :{WHITE} Wereldticks: +STR_FRAMERATE_GL_LINKGRAPH :{WHITE} Link grafiekvertraging: +STR_FRAMERATE_DRAWING :{WHITE}Graphics weergeven: +STR_FRAMERATE_DRAWING_VIEWPORTS :{WHITE} Wereldkijkvensters: +STR_FRAMERATE_VIDEO :{WHITE}Video-output: +STR_FRAMERATE_SOUND :{WHITE}Geluid mixen: +############ End of leave-in-this-order +############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_GAMELOOP :Gameloop +STR_FRAMETIME_CAPTION_GL_ECONOMY :Cargoafhandeling +STR_FRAMETIME_CAPTION_GL_TRAINS :Treinticks +STR_FRAMETIME_CAPTION_GL_ROADVEHS :Wegvoertuigticks +STR_FRAMETIME_CAPTION_GL_SHIPS :Schipticks +STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Vliegtuigticks +STR_FRAMETIME_CAPTION_GL_LANDSCAPE :Wereldticks +STR_FRAMETIME_CAPTION_GL_LINKGRAPH :Link grafiekvertraging +STR_FRAMETIME_CAPTION_DRAWING :Graphics weergeven +STR_FRAMETIME_CAPTION_DRAWING_VIEWPORTS :Wereldkijkvenster weergeven +STR_FRAMETIME_CAPTION_VIDEO :Video-output +STR_FRAMETIME_CAPTION_SOUND :Geluid mixen +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Spel Opslaan STR_SAVELOAD_LOAD_CAPTION :{WHITE}Spel Laden @@ -2710,7 +2766,7 @@ STR_SAVELOAD_SAVE_BUTTON :{BLACK}Opslaan STR_SAVELOAD_SAVE_TOOLTIP :{BLACK}Sla het huidige spel op onder de gekozen naam STR_SAVELOAD_LOAD_BUTTON :{BLACK}Laad STR_SAVELOAD_LOAD_TOOLTIP :{BLACK}Laad het geselecteerde spel -STR_SAVELOAD_LOAD_HEIGHTMAP_TOOLTIP :{BLACK}Laad de geselecteerd hoogtekaart +STR_SAVELOAD_LOAD_HEIGHTMAP_TOOLTIP :{BLACK}Laad de geselecteerde hoogtekaart STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Spel details STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Geen informatie beschikbaar STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} @@ -2730,8 +2786,8 @@ STR_MAPGEN_MAX_HEIGHTLEVEL :{BLACK}Maximum STR_MAPGEN_MAX_HEIGHTLEVEL_UP :{BLACK}Verhoog de maximum hoogte van bergen op de kaart met één STR_MAPGEN_MAX_HEIGHTLEVEL_DOWN :{BLACK}Verklein de maximum hoogte van bergen op de kaart met één STR_MAPGEN_SNOW_LINE_HEIGHT :{BLACK}Hoogte van sneeuwgrens: -STR_MAPGEN_SNOW_LINE_UP :{BLACK}Verschuif de sneeuwgrens één omhoog -STR_MAPGEN_SNOW_LINE_DOWN :{BLACK}Verschuif de sneeuwgrens één omlaag +STR_MAPGEN_SNOW_LINE_UP :{BLACK}Verhoog de sneeuwgrens met één +STR_MAPGEN_SNOW_LINE_DOWN :{BLACK}Verlaag de sneeuwgrens met één STR_MAPGEN_LAND_GENERATOR :{BLACK}Landgenerator: STR_MAPGEN_TREE_PLACER :{BLACK}Bosalgoritme: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Terreintype: @@ -2760,7 +2816,7 @@ STR_MAPGEN_HEIGHTMAP_SIZE :{ORANGE}{NUM} x STR_MAPGEN_MAX_HEIGHTLEVEL_QUERY_CAPT :{WHITE}Wijzig maximum kaarthoogte STR_MAPGEN_SNOW_LINE_QUERY_CAPT :{WHITE}Verander hoogte van sneeuwgrens -STR_MAPGEN_START_DATE_QUERY_CAPT :{WHITE}Verander beginjaar +STR_MAPGEN_START_DATE_QUERY_CAPT :{WHITE}Verander startjaar # SE Map generation STR_SE_MAPGEN_CAPTION :{WHITE}Scenariotype @@ -2768,8 +2824,8 @@ STR_SE_MAPGEN_FLAT_WORLD :{WHITE}Vlak lan STR_SE_MAPGEN_FLAT_WORLD_TOOLTIP :{BLACK}Genereer een vlakke kaart STR_SE_MAPGEN_RANDOM_LAND :{WHITE}Willekeurig land STR_SE_MAPGEN_FLAT_WORLD_HEIGHT :{BLACK}Hoogte van vlak land: -STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Maak de hoogte van vlak land één lager -STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_UP :{BLACK}Maak de hoogte van vlak land één hoger +STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Verlaag de hoogte van vlak land met één +STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_UP :{BLACK}Verhoog de hoogte van vlak land met één STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Verander hoogte van vlak land @@ -2792,11 +2848,11 @@ STR_GENERATION_PREPARING_GAME :{BLACK}Voorbere # NewGRF settings STR_NEWGRF_SETTINGS_CAPTION :{WHITE}NewGRF-instellingen -STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Gedetaileerde NewGRF informatie -STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Actieve NewGRF bestanden -STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Inactieve NewGRF bestanden +STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Gedetaileerde NewGRF-informatie +STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Actieve NewGRF-bestanden +STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Inactieve NewGRF-bestanden STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Kies voorkeur: -STR_NEWGRF_FILTER_TITLE :{ORANGE}Filter tekst: +STR_NEWGRF_FILTER_TITLE :{ORANGE}Filtertekst: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Laad de geselecteerde voorkeursinstelling STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Bewaar voorkeursinstelling STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Bewaar de huidige lijst als voorkeursinstelling @@ -2843,17 +2899,17 @@ STR_NEWGRF_SETTINGS_INCOMPATIBLE :{RED}Niet compa STR_SAVE_PRESET_CAPTION :{WHITE}Preset opslaan STR_SAVE_PRESET_LIST_TOOLTIP :{BLACK}Lijst met beschikbare presets, Kies er één om deze te kopiëren naar de opslagnaam hieronder STR_SAVE_PRESET_TITLE :{BLACK}Voer een naam in voor de preset -STR_SAVE_PRESET_EDITBOX_TOOLTIP :{BLACK}Nu gekozen naam voor de preset opslag +STR_SAVE_PRESET_EDITBOX_TOOLTIP :{BLACK}Huidig gekozen naam voor de preset om op te slaan STR_SAVE_PRESET_CANCEL :{BLACK}Annuleren STR_SAVE_PRESET_CANCEL_TOOLTIP :{BLACK}Preset niet wijzigen STR_SAVE_PRESET_SAVE :{BLACK}Opslaan -STR_SAVE_PRESET_SAVE_TOOLTIP :{BLACK}Sla de huidige preset op naar de nu gekozen naam +STR_SAVE_PRESET_SAVE_TOOLTIP :{BLACK}Sla de huidige preset op naar de huidig gekozen naam # NewGRF parameters window -STR_NEWGRF_PARAMETERS_CAPTION :{WHITE}NewGRF parameters wijzigen +STR_NEWGRF_PARAMETERS_CAPTION :{WHITE}NewGRF-parameters wijzigen STR_NEWGRF_PARAMETERS_CLOSE :{BLACK}Sluiten STR_NEWGRF_PARAMETERS_RESET :{BLACK}Reset -STR_NEWGRF_PARAMETERS_RESET_TOOLTIP :{BLACK}Zet alle parameters naar de standaard waarde +STR_NEWGRF_PARAMETERS_RESET_TOOLTIP :{BLACK}Zet alle parameters naar de standaardwaarde STR_NEWGRF_PARAMETERS_DEFAULT_NAME :Parameter {NUM} STR_NEWGRF_PARAMETERS_SETTING :{STRING}: {ORANGE}{STRING} STR_NEWGRF_PARAMETERS_NUM_PARAM :{LTBLUE}Aantal parameters: {ORANGE}{NUM} @@ -2865,7 +2921,7 @@ STR_NEWGRF_INSPECT_PARENT_TOOLTIP :{BLACK}Inspecte STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT :{STRING} bij {HEX} STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_OBJECT :Object -STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_RAIL_TYPE :Spoor type +STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_RAIL_TYPE :Spoortype STR_NEWGRF_INSPECT_QUERY_CAPTION :{WHITE}NewGRF variable 60+x parameter (hexadecimaal) @@ -2900,19 +2956,19 @@ STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} is o STR_NEWGRF_ERROR_INVALID_PARAMETER :Ongeldige parameter voor {1:STRING}: parameter {STRING} ({NUM}) STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} moet geladen zijn voor {STRING} STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} moet geladen zijn na {STRING} -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} heeft OpenTTD versie {STRING} of beter nodig +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} heeft OpenTTD-versie {STRING} of beter nodig STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :het GRF-bestand die het probeert te vertalen STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Er zijn te veel NewGRFs geladen STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Laden van {1:STRING} als statische NewGRF met {STRING} kan desynchronisatiefouten (desyncs) veroorzaken STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Onverwachte sprite (sprite {3:NUM}) -STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Onbekende Actie 0 eigenschap {4:HEX} (sprite {3:NUM}) +STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Onbekende Action 0-eigenschap {4:HEX} (sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Poging om ongeldig ID te gebruiken (sprite {3:NUM}) STR_NEWGRF_ERROR_CORRUPT_SPRITE :{YELLOW}{STRING} bevat een ongeldige afbeelding. Alle ongeldige afbeeldingen worden getoond als een rood vraagteken (?) -STR_NEWGRF_ERROR_MULTIPLE_ACTION_8 :Bevat meerdere acties 8 (sprite {3:NUM}) +STR_NEWGRF_ERROR_MULTIPLE_ACTION_8 :Bevat meerdere Action 8-invoer (sprite {3:NUM}) STR_NEWGRF_ERROR_READ_BOUNDS :Voorbij het einde van pseudo-sprite gelezen (sprite {3:NUM}) -STR_NEWGRF_ERROR_GRM_FAILED :Gevraagde GRF middelen niet beschikbaar (sprite {3:NUM}) +STR_NEWGRF_ERROR_GRM_FAILED :Gevraagde GRF-middelen niet beschikbaar (sprite {3:NUM}) STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING} is uitgeschakeld door {STRING} -STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Ongeldig/onbekend sprite lay-out-formaat (sprite {3:NUM}) +STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Ongeldig/onbekend spritelay-outformaat (sprite {3:NUM}) # NewGRF related 'general' warnings STR_NEWGRF_POPUP_CAUTION_CAPTION :{WHITE}Waarschuwing! @@ -2920,7 +2976,7 @@ STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Je staa STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Kan bestand niet toevoegen: identieke GRF-ID STR_NEWGRF_COMPATIBLE_LOADED :{ORANGE}Bijbehorend bestand niet gevonden (compatibele GRF geladen) -STR_NEWGRF_TOO_MANY_NEWGRFS :{WHITE}Kan bestand niet toevoegen: NewGRF bestandslimiet bereikt +STR_NEWGRF_TOO_MANY_NEWGRFS :{WHITE}Kan bestand niet toevoegen: NewGRF-bestandslimiet bereikt STR_NEWGRF_COMPATIBLE_LOAD_WARNING :{WHITE}Compatibele GRF(s) geladen voor ontbrekende bestanden STR_NEWGRF_DISABLED_WARNING :{WHITE}Missend(e) GRF-bestand(en) zijn uitgeschakeld @@ -2936,13 +2992,13 @@ STR_NEWGRF_LIST_MISSING :{RED}Ontbrekend # NewGRF 'it's broken' warnings STR_NEWGRF_BROKEN :{WHITE}Gedrag van NewGRF '{0:STRING}' zal waarschijnlijk desynchronisatiefouten (desyncs) en/of crashes veroorzaken STR_NEWGRF_BROKEN_POWERED_WAGON :{WHITE}Wagon '{1:ENGINE}' gewijzigde status van aandrijfeenheid wanneer niet in een depot -STR_NEWGRF_BROKEN_VEHICLE_LENGTH :{WHITE}Het verandert de lengte van voertuig '{1:ENGINE}' terwijl het niet in een depot is +STR_NEWGRF_BROKEN_VEHICLE_LENGTH :{WHITE}Het veranderde de lengte van voertuig '{1:ENGINE}' wanneer het niet in een depot is STR_NEWGRF_BROKEN_CAPACITY :{WHITE}Het wijzigde voertuigcapaciteit voor '{1:ENGINE}' wanneer niet in een depot of ombouwen STR_BROKEN_VEHICLE_LENGTH :{WHITE}Trein '{VEHICLE}' behorend bij '{COMPANY}' heeft een ongeldige lengte. Het is waarschijnlijk veroorzaakt door problemen met NewGRF's. Het spel kan desynchroniseren of vastlopen STR_NEWGRF_BUGGY :{WHITE}NewGRF '{0:STRING}' geeft onjuiste informatie -STR_NEWGRF_BUGGY_ARTICULATED_CARGO :{WHITE}Vracht-/ombouwinformatie voor '{1:ENGINE}' wijkt af van aanschaflijst na het bouwen. Dit kan resulteren in problemen bij ombouwen door automatisch vernieuwen/vervangen -STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' heeft een eindeloze loop veroorzaakt in de productie-callback +STR_NEWGRF_BUGGY_ARTICULATED_CARGO :{WHITE}Vracht- of ombouwinformatie voor '{1:ENGINE}' wijkt af van aanschaflijst na het bouwen. Dit kan resulteren in problemen bij ombouwen door automatisch vernieuwen/vervangen +STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' heeft een eindeloze loop veroorzaakt in de productiecallback STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT :{WHITE}Callback {1:HEX} gaf onbekend/ongeldig resultaat {2:HEX} # 'User removed essential NewGRFs'-placeholders for stuff without specs @@ -2958,13 +3014,13 @@ STR_INVALID_VEHICLE : -STR_WARNING_LOADGAME_REMOVED_TRAMS :{WHITE}Spel was opgeslagen in een versie zonder tram-ondersteuning. Alle trams zijn verwijderd +STR_WARNING_LOADGAME_REMOVED_TRAMS :{WHITE}Spel was opgeslagen in een versie zonder tramondersteuning. Alle trams zijn verwijderd # Map generation messages STR_ERROR_COULD_NOT_CREATE_TOWN :{WHITE}Kaartmaken afgebroken...{}... geen geschikte dorpslocaties @@ -4108,13 +4164,13 @@ STR_WARNING_HEIGHTMAP_SCALE_CAPTION :{WHITE}Schaalwa STR_WARNING_HEIGHTMAP_SCALE_MESSAGE :{YELLOW}Het aanpassen van de grootte van een bronkaart is niet aan te bevelen. Toch doorgaan? # Soundset messages -STR_WARNING_FALLBACK_SOUNDSET :{WHITE}Alleen backup geluid is gevonden. Als je geluid wilt, installeer dan een geluiddsset via het downloadsysteem +STR_WARNING_FALLBACK_SOUNDSET :{WHITE}Alleen back-upgeluid is gevonden. Als u geluid wilt, installeer dan een geluiddsset via het downloadsysteem # Screenshot related messages STR_WARNING_SCREENSHOT_SIZE_CAPTION :{WHITE}Grote schermafdruk STR_WARNING_SCREENSHOT_SIZE_MESSAGE :{YELLOW}De schermafdruk heeft een resolutie van {COMMA} x {COMMA} pixels. De schermafdruk maken kan even duren. Verder gaan? -STR_MESSAGE_SCREENSHOT_SUCCESSFULLY :{WHITE}Schermprint succesvol opgeslagen als '{STRING}' +STR_MESSAGE_SCREENSHOT_SUCCESSFULLY :{WHITE}Schermafbeelding succesvol opgeslagen als '{STRING}' STR_ERROR_SCREENSHOT_FAILED :{WHITE}Schermprint mislukt! # Error message titles @@ -4224,7 +4280,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Te veel STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Te veel treinstationsdelen STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Te veel bushaltes STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Te veel vrachtwagenlaadstations -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Te dicht bij een ander (laad)station STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Te dicht bij een andere haven STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Te dicht bij een ander vliegveld STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Kan stationsnaam niet veranderen... @@ -4232,6 +4287,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... deze STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... weg is in de verkeerde richting STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... doorrij haltes kunnen geen bochten hebben STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... doorrij haltes kunnen geen kruisingen hebben +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... weg is eenrichtingsverkeer of geblokkeerd # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Kan deel van station niet weghalen... @@ -4310,7 +4366,7 @@ STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE :{WHITE}Kan sein STR_ERROR_THERE_IS_NO_RAILROAD_TRACK :{WHITE}...er is hier geen spoorlijn STR_ERROR_THERE_ARE_NO_SIGNALS :{WHITE}...er zijn geen seinen -STR_ERROR_CAN_T_CONVERT_RAIL :{WHITE}Kan railtype hier niet veranderen... +STR_ERROR_CAN_T_CONVERT_RAIL :{WHITE}Kan spoortype hier niet veranderen... # Road construction errors STR_ERROR_MUST_REMOVE_ROAD_FIRST :{WHITE}Moet weg eerst weghalen @@ -4483,6 +4539,8 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Originele gelui STR_BASESOUNDS_WIN_DESCRIPTION :Originele geluiden van de Transport Tycoon Deluxe Windows-versie. STR_BASESOUNDS_NONE_DESCRIPTION :Een geluidset zonder geluid. STR_BASEMUSIC_WIN_DESCRIPTION :Originele muziek van de Transport Tycoon Deluxe Windows-versie. +STR_BASEMUSIC_DOS_DESCRIPTION :Originele Transport Tycoon Deluxe DOS-editiemuziek. +STR_BASEMUSIC_TTO_DESCRIPTION :Originele Transport Tycoon (Original/World Editor) DOS-editiemuziek. STR_BASEMUSIC_NONE_DESCRIPTION :Een muziekset zonder muziek. ##id 0x2000 @@ -4497,7 +4555,7 @@ STR_TOWN_BUILDING_NAME_HOTEL_1 :Hotel STR_TOWN_BUILDING_NAME_STATUE_1 :Standbeeld STR_TOWN_BUILDING_NAME_FOUNTAIN_1 :Fontein STR_TOWN_BUILDING_NAME_PARK_1 :Park -STR_TOWN_BUILDING_NAME_OFFICE_BLOCK_2 :Kantorenblok +STR_TOWN_BUILDING_NAME_OFFICE_BLOCK_2 :Kantoorgebouw STR_TOWN_BUILDING_NAME_SHOPS_AND_OFFICES_1 :Winkels en kantoren STR_TOWN_BUILDING_NAME_MODERN_OFFICE_BUILDING_1 :Modern kantoorgebouw STR_TOWN_BUILDING_NAME_WAREHOUSE_1 :Warenhuis @@ -4518,7 +4576,7 @@ STR_TOWN_BUILDING_NAME_CINEMA_1 :Bioscoop STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1 :Winkelcentrum STR_TOWN_BUILDING_NAME_IGLOO_1 :Iglo STR_TOWN_BUILDING_NAME_TEPEES_1 :Tepees -STR_TOWN_BUILDING_NAME_TEAPOT_HOUSE_1 :Theepothuis +STR_TOWN_BUILDING_NAME_TEAPOT_HOUSE_1 :Theehuis STR_TOWN_BUILDING_NAME_PIGGY_BANK_1 :Spaarvarken ##id 0x4800 @@ -4581,13 +4639,13 @@ STR_SV_STNAME_TRANSFER :{STRING} Transf STR_SV_STNAME_HALT :{STRING} Halte STR_SV_STNAME_VALLEY :{STRING} Vallei STR_SV_STNAME_HEIGHTS :{STRING} Hoogte -STR_SV_STNAME_WOODS :{STRING} Bossen +STR_SV_STNAME_WOODS :{STRING} Woud STR_SV_STNAME_LAKESIDE :{STRING} Meerkant STR_SV_STNAME_EXCHANGE :{STRING} Uitwisseling STR_SV_STNAME_AIRPORT :{STRING} Vliegveld STR_SV_STNAME_OILFIELD :{STRING} Olieveld STR_SV_STNAME_MINES :{STRING} Mijnen -STR_SV_STNAME_DOCKS :{STRING} Haven +STR_SV_STNAME_DOCKS :{STRING} Dokken STR_SV_STNAME_BUOY :{STRING} STR_SV_STNAME_WAYPOINT :{STRING} ##id 0x6020 diff --git a/src/lang/english.txt b/src/lang/english.txt index 258c02c6d6..cb4e685c46 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -475,6 +475,7 @@ STR_ABOUT_MENU_SCREENSHOT :Screenshot STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Fully zoomed in screenshot STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Default zoom screenshot STR_ABOUT_MENU_GIANT_SCREENSHOT :Whole map screenshot +STR_ABOUT_MENU_SHOW_FRAMERATE :Show frame rate STR_ABOUT_MENU_ABOUT_OPENTTD :About 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite aligner STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Toggle bounding boxes @@ -650,6 +651,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}No music available STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{RAW_STRING}" STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Track STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Title @@ -669,15 +671,15 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Select ' STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Toggle programme shuffle on/off STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Show music track selection window -STR_ERROR_NO_SONGS :{WHITE}A music set without songs has been selected. No songs will be played - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Music Programme Selection +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Music Programme - '{RAW_STRING}' STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{RAW_STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Track Index STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programme - '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Clear +STR_PLAYLIST_CHANGE_SET :{BLACK}Change set STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Clear current programme (Custom1 or Custom2 only) +STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Change music selection to another installed set STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Click on music track to add to current programme (Custom1 or Custom2 only) STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Click on music track to remove it from current programme (Custom1 or Custom2 only) @@ -813,6 +815,7 @@ STR_NEWS_MERGER_TAKEOVER_TITLE :{BIG_FONT}{BLAC STR_PRESIDENT_NAME_MANAGER :{BLACK}{PRESIDENT_NAME}{}(Manager) STR_NEWS_NEW_TOWN :{BLACK}{BIG_FONT}{RAW_STRING} sponsored construction of new town {TOWN}! +STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK}{BIG_FONT}A new town called {TOWN} has been constructed! STR_NEWS_INDUSTRY_CONSTRUCTION :{BIG_FONT}{BLACK}New {STRING} under construction near {TOWN}! STR_NEWS_INDUSTRY_PLANTED :{BIG_FONT}{BLACK}New {STRING} being planted near {TOWN}! @@ -880,10 +883,10 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC # Extra view window STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Viewport {COMMA} -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Copy to viewport +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Change viewport STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Copy the location of the main view to this viewport -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Paste from viewport -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Paste the location of this viewport to the main view +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Change main view +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Copy the location of this viewport to the main view # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Game Options @@ -925,6 +928,7 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :South African R STR_GAME_OPTIONS_CURRENCY_CUSTOM :Custom... STR_GAME_OPTIONS_CURRENCY_GEL :Georgian Lari (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :Iranian Rial (IRR) +STR_GAME_OPTIONS_CURRENCY_RUB :New Russian Ruble (RUB) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Road vehicles @@ -1337,8 +1341,12 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Colour of the t STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Green STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Dark green STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Violet -STR_CONFIG_SETTING_REVERSE_SCROLLING :Reverse scroll direction: {STRING2} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Behaviour when scrolling the map with the right mouse button. When disabled, the mouse moves the camera. When enabled, the mouse moves the map +STR_CONFIG_SETTING_SCROLLMODE :Viewport scroll behaviour: {STRING2} +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Behaviour when scrolling the map +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Move viewport with RMB, mouse position locked +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Move map with RMB, mouse position locked +STR_CONFIG_SETTING_SCROLLMODE_RMB :Move map with RMB +STR_CONFIG_SETTING_SCROLLMODE_LMB :Move map with LMB STR_CONFIG_SETTING_SMOOTH_SCROLLING :Smooth viewport scrolling: {STRING2} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Control how the main view scrolls to a specific position when clicking on the smallmap or when issuing a command to scroll to a specific object on the map. If enabled, the viewport scrolls smoothly, if disabled it jumps directly to the targeted spot STR_CONFIG_SETTING_MEASURE_TOOLTIP :Show a measurement tooltip when using various build-tools: {STRING2} @@ -1370,8 +1378,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command+Click STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+Click STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Off -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Left-click scrolling: {STRING2} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Enable scrolling the map by dragging it with the left mouse button. This is especially useful when using a touch-screen for scrolling STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Close window on right-click: {STRING2} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Closes a window by right-clicking inside it. Disables the tooltip on right-click! @@ -2285,6 +2291,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Cargo Fl STR_LINKGRAPH_LEGEND_ALL :{BLACK}All STR_LINKGRAPH_LEGEND_NONE :{BLACK}None STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Select companies to be displayed +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}unused @@ -2693,6 +2700,56 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Original STR_ABOUT_VERSION :{BLACK}OpenTTD version {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 The OpenTTD team +# Framerate display window +STR_FRAMERATE_CAPTION :{WHITE}Frame rate +STR_FRAMERATE_CAPTION_SMALL :{STRING2}{WHITE} ({DECIMAL}x) +STR_FRAMERATE_RATE_GAMELOOP :{BLACK}Simulation rate: {STRING2} +STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Number of game ticks simulated per second. +STR_FRAMERATE_RATE_BLITTER :{BLACK}Graphics frame rate: {STRING2} +STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Number of video frames rendered per second. +STR_FRAMERATE_SPEED_FACTOR :{BLACK}Current game speed factor: {DECIMAL}x +STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}How fast the game is currently running, compared to the expected speed at normal simulation rate. +STR_FRAMERATE_CURRENT :{WHITE}Current +STR_FRAMERATE_AVERAGE :{WHITE}Average +STR_FRAMERATE_DATA_POINTS :{BLACK}Data based on {COMMA} measurements +STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms +STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms +STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} ms +STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} frames/s +STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} frames/s +STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} frames/s +STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms +STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s +############ Leave those lines in this order!! +STR_FRAMERATE_GAMELOOP :{BLACK}Game loop total: +STR_FRAMERATE_GL_ECONOMY :{BLACK} Cargo handling: +STR_FRAMERATE_GL_TRAINS :{BLACK} Train ticks: +STR_FRAMERATE_GL_ROADVEHS :{BLACK} Road vehicle ticks: +STR_FRAMERATE_GL_SHIPS :{BLACK} Ship ticks: +STR_FRAMERATE_GL_AIRCRAFT :{BLACK} Aircraft ticks: +STR_FRAMERATE_GL_LANDSCAPE :{BLACK} World ticks: +STR_FRAMERATE_GL_LINKGRAPH :{BLACK} Link graph delay: +STR_FRAMERATE_DRAWING :{BLACK}Graphics rendering: +STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK} World viewports: +STR_FRAMERATE_VIDEO :{BLACK}Video output: +STR_FRAMERATE_SOUND :{BLACK}Sound mixing: +############ End of leave-in-this-order +############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_GAMELOOP :Game loop +STR_FRAMETIME_CAPTION_GL_ECONOMY :Cargo handling +STR_FRAMETIME_CAPTION_GL_TRAINS :Train ticks +STR_FRAMETIME_CAPTION_GL_ROADVEHS :Road vehicle ticks +STR_FRAMETIME_CAPTION_GL_SHIPS :Ship ticks +STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Aircraft ticks +STR_FRAMETIME_CAPTION_GL_LANDSCAPE :World ticks +STR_FRAMETIME_CAPTION_GL_LINKGRAPH :Link graph delay +STR_FRAMETIME_CAPTION_DRAWING :Graphics rendering +STR_FRAMETIME_CAPTION_DRAWING_VIEWPORTS :World viewport rendering +STR_FRAMETIME_CAPTION_VIDEO :Video output +STR_FRAMETIME_CAPTION_SOUND :Sound mixing +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Save Game STR_SAVELOAD_LOAD_CAPTION :{WHITE}Load Game @@ -2715,6 +2772,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Game Det STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}No information available STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING1} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} +STR_SAVELOAD_FILTER_TITLE :{BLACK}Filter string: STR_SAVELOAD_OSKTITLE :{BLACK}Enter a name for the savegame @@ -2913,6 +2971,8 @@ STR_NEWGRF_ERROR_READ_BOUNDS :Read past end o STR_NEWGRF_ERROR_GRM_FAILED :Requested GRF resources not available (sprite {3:NUM}) STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:RAW_STRING} was disabled by {2:RAW_STRING} STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Invalid/unknown sprite layout format (sprite {3:NUM}) +STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG :Too many elements in property value list (sprite {3:NUM}, property {4:HEX}) +STR_NEWGRF_ERROR_INDPROD_CALLBACK :Invalid industry production callback (sprite {3:NUM}, "{1:RAW_STRING}") # NewGRF related 'general' warnings STR_NEWGRF_POPUP_CAUTION_CAPTION :{WHITE}Caution! @@ -2977,6 +3037,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Enter a STR_TOWN_DIRECTORY_CAPTION :{WHITE}Towns STR_TOWN_DIRECTORY_NONE :{ORANGE}- None - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (City){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Town names - click on name to centre main view on town. Ctrl+Click opens a new viewport on town location STR_TOWN_POPULATION :{BLACK}World population: {COMMA} @@ -2984,8 +3045,7 @@ STR_TOWN_POPULATION :{BLACK}World po STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (City) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Population: {ORANGE}{COMMA}{BLACK} Houses: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passengers last month: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Mail last month: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} +STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} last month: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Cargo needed for town growth: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} required STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} required in winter @@ -3799,6 +3859,7 @@ STR_ORDER_CONDITIONAL_AGE :Age (years) STR_ORDER_CONDITIONAL_REQUIRES_SERVICE :Requires service STR_ORDER_CONDITIONAL_UNCONDITIONALLY :Always STR_ORDER_CONDITIONAL_REMAINING_LIFETIME :Remaining lifetime (years) +STR_ORDER_CONDITIONAL_MAX_RELIABILITY :Maximum reliability STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP :{BLACK}How to compare the vehicle data to the given value STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS :is equal to @@ -4224,7 +4285,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Too many STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Too many railway station parts STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Too many bus stops STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Too many lorry stations -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Too close to another station/loading area STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Too close to another dock STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Too close to another airport STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Can't rename station... @@ -4232,6 +4292,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... this STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... road facing in the wrong direction STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... drive through stops can't have corners STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... drive through stops can't have junctions +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... road is one way or blocked # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Can't remove part of station... @@ -4483,6 +4544,8 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Original Transp STR_BASESOUNDS_WIN_DESCRIPTION :Original Transport Tycoon Deluxe Windows edition sounds. STR_BASESOUNDS_NONE_DESCRIPTION :A sound pack without any sounds. STR_BASEMUSIC_WIN_DESCRIPTION :Original Transport Tycoon Deluxe Windows edition music. +STR_BASEMUSIC_DOS_DESCRIPTION :Original Transport Tycoon Deluxe DOS edition music. +STR_BASEMUSIC_TTO_DESCRIPTION :Original Transport Tycoon (Original/World Editor) DOS edition music. STR_BASEMUSIC_NONE_DESCRIPTION :A music pack without actual music. ##id 0x2000 diff --git a/src/lang/english_AU.txt b/src/lang/english_AU.txt index 8d51d06660..8e001d956a 100644 --- a/src/lang/english_AU.txt +++ b/src/lang/english_AU.txt @@ -660,10 +660,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Select ' STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Toggle programme shuffle on/off STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Show music track selection window -STR_ERROR_NO_SONGS :{WHITE}A music set without songs has been selected. No songs will be played - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Music Programme Selection STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Track Index STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programme - '{STRING}' @@ -1316,8 +1313,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Colour of the t STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Green STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Dark green STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Violet -STR_CONFIG_SETTING_REVERSE_SCROLLING :Reverse scroll direction: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Behaviour when scrolling the map with the right mouse button. When disabled, the mouse moves the camera. When enabled, the mouse moves the map STR_CONFIG_SETTING_SMOOTH_SCROLLING :Smooth viewport scrolling: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Control how the main view scrolls to a specific position when clicking on the smallmap or when issuing a command to scroll to a specific object on the map. If enabled, the viewport scrolls smoothly, if disabled it jumps directly to the targeted spot STR_CONFIG_SETTING_MEASURE_TOOLTIP :Show a measurement tooltip when using various build-tools: {STRING} @@ -1349,8 +1344,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command+Click STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+Click STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Off -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Left-click scrolling: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Enable scrolling the map by dragging it with the left mouse button. This is especially useful when using a touch-screen for scrolling STR_CONFIG_SETTING_AUTOSAVE :Autosave: {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :Select interval between automatic game saves @@ -2664,6 +2657,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Original STR_ABOUT_VERSION :{BLACK}OpenTTD version {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 The OpenTTD team +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Save Game STR_SAVELOAD_LOAD_CAPTION :{WHITE}Load Game @@ -2947,8 +2947,6 @@ STR_TOWN_POPULATION :{BLACK}World po STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (City) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Population: {ORANGE}{COMMA}{BLACK} Houses: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passengers last month: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Mail last month: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Cargo needed for town growth: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} required STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} required in winter @@ -4155,7 +4153,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Too many STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Too many railway station parts STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Too many bus stops STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Too many Truck stations -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Too close to another station/loading area STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Too close to another dock STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Too close to another airport STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Can't rename station... diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index 86519ddc61..b93ecb6836 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -650,6 +650,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}No music available STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Track STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Title @@ -669,15 +670,15 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Select ' STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Toggle program shuffle on/off STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Show music track selection window -STR_ERROR_NO_SONGS :{WHITE}A music set without songs has been selected. No songs will be played - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Music Program Selection +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Music Program - '{STRING}' STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Track Index STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Program - '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Clear +STR_PLAYLIST_CHANGE_SET :{BLACK}Change set STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Clear current program (Custom1 or Custom2 only) +STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Change music selection to another installed set STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Click on music track to add to current program (Custom1 or Custom2 only) STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Click on music track to remove it from current program (Custom1 or Custom2 only) @@ -880,10 +881,10 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC # Extra view window STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Viewport {COMMA} -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Copy to viewport +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Change viewport STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Copy the location of the main view to this viewport -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Paste from viewport -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Paste the location of this viewport to the main view +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Change main view +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Copy the location of this viewport to the main view # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Game Options @@ -1337,8 +1338,12 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Color of the te STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Green STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Dark green STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Purple -STR_CONFIG_SETTING_REVERSE_SCROLLING :Reverse scroll direction: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Behavior when scrolling the map with the right mouse button. When disabled, the mouse moves the camera. When enabled, the mouse moves the map +STR_CONFIG_SETTING_SCROLLMODE :Viewport scroll behaviour: {STRING} +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Behavior when scrolling the map +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Move viewport with RMB, mouse position locked +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Move map with RMB, mouse position locked +STR_CONFIG_SETTING_SCROLLMODE_RMB :Move map with RMB +STR_CONFIG_SETTING_SCROLLMODE_LMB :Move map with LMB STR_CONFIG_SETTING_SMOOTH_SCROLLING :Smooth viewport scrolling: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Control how the main view scrolls to a specific position when clicking on the smallmap or when issuing a command to scroll to a specific object on the map. If enabled, the viewport scrolls smoothly, if disabled it jumps directly to the targeted spot STR_CONFIG_SETTING_MEASURE_TOOLTIP :Show a measurement tooltip when using various build-tools: {STRING} @@ -1370,8 +1375,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command+Click STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+Click STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Off -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Left-click scrolling: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Enable scrolling the map by dragging it with the left mouse button. This is especially useful when using a touch-screen for scrolling STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Close window on right-click: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Closes a window by right-clicking inside it. Disables the tooltip on right-click! @@ -2285,6 +2288,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Cargo Fl STR_LINKGRAPH_LEGEND_ALL :{BLACK}All STR_LINKGRAPH_LEGEND_NONE :{BLACK}None STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Select companies to be displayed +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}unused @@ -2693,6 +2697,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Original STR_ABOUT_VERSION :{BLACK}OpenTTD version {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 The OpenTTD team +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Save Game STR_SAVELOAD_LOAD_CAPTION :{WHITE}Load Game @@ -2977,6 +2988,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Enter a STR_TOWN_DIRECTORY_CAPTION :{WHITE}Towns STR_TOWN_DIRECTORY_NONE :{ORANGE}- None - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (City){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Town names - click on name to center main view on town. Ctrl+Click opens a new viewport on town location STR_TOWN_POPULATION :{BLACK}World population: {COMMA} @@ -2984,8 +2996,7 @@ STR_TOWN_POPULATION :{BLACK}World po STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (City) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Population: {ORANGE}{COMMA}{BLACK} Houses: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passengers last month: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Mail last month: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} +STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} last month: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Cargo needed for town growth: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} required STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} required in winter @@ -4224,7 +4235,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Too many STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Too many railroad station parts STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Too many bus stops STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Too many truck stations -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Too close to another station/loading area STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Too close to another dock STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Too close to another airport STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Can't rename station... @@ -4232,6 +4242,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... this STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... road facing in the wrong direction STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... drive through stops can't have corners STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... drive through stops can't have junctions +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... road is one way or blocked # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Can't remove part of station... @@ -4483,6 +4494,8 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Original Transp STR_BASESOUNDS_WIN_DESCRIPTION :Original Transport Tycoon Deluxe Windows edition sounds. STR_BASESOUNDS_NONE_DESCRIPTION :A sound pack without any sounds. STR_BASEMUSIC_WIN_DESCRIPTION :Original Transport Tycoon Deluxe Windows edition music. +STR_BASEMUSIC_DOS_DESCRIPTION :Original Transport Tycoon Deluxe DOS edition music. +STR_BASEMUSIC_TTO_DESCRIPTION :Original Transport Tycoon (Original/World Editor) DOS edition music. STR_BASEMUSIC_NONE_DESCRIPTION :A music pack without actual music. ##id 0x2000 diff --git a/src/lang/esperanto.txt b/src/lang/esperanto.txt index 949fdb0d2c..49149b638f 100644 --- a/src/lang/esperanto.txt +++ b/src/lang/esperanto.txt @@ -663,10 +663,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Elektu l STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Miksu/ne miksu STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Montru muziker-elektan fenestron -STR_ERROR_NO_SONGS :{WHITE}Senkanta muzikaro estas elektita. Neniu kanto ludos. - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Elekto de Muzikprogramo STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Numera Indekso STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programo - '{STRING}' @@ -1199,7 +1196,6 @@ STR_CONFIG_SETTING_LINK_TERRAFORM_TOOLBAR :Ligu landaspekt STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Verda STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Malhele verda STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Viola -STR_CONFIG_SETTING_REVERSE_SCROLLING :Inversigu skroldirekton: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING :Glata rulumado de vidujo: {STRING} STR_CONFIG_SETTING_MEASURE_TOOLTIP :Montru mezuran konsilbalonon ĉe uzo de konstruiloj: {STRING} STR_CONFIG_SETTING_LIVERIES :Montru veturiltipe specifajn liverojn: {STRING} @@ -1223,7 +1219,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Komando+Klako STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+Klako STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Ne -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Maldekstr-klak-rulumado: {STRING} STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES :Uzu la {STRING} datformon por nomoj de konservludoj. @@ -2267,6 +2262,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Origina STR_ABOUT_VERSION :{BLACK}OpenTTD-versio {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2018 La teamo de OpenTTD +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Konservu Ludon STR_SAVELOAD_LOAD_CAPTION :{WHITE}Ŝarĝu Ludon @@ -2514,8 +2516,6 @@ STR_TOWN_POPULATION :{BLACK}Monda en STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Urbo) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Enloĝantoj: {ORANGE}{COMMA}{BLACK} Domoj: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Pasaĝeroj lastmonate: {ORANGE}{COMMA}{BLACK} maksimume: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Poŝto lastmonate: {ORANGE}{COMMA}{BLACK} maksimume: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Kargo bezonata por kreskigi urbon: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} bezonatas STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} bezonatas en vintro @@ -3579,7 +3579,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Tro da s STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Tro da partoj de stacidomo STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Tro da bushaltejoj STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Tro da ŝarĝaŭtaj stacioj -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Tro proksime al alia stacioj/ŝarĝejoj STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Tro proksime al alia haveno STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Tro proksime al alia flughaveno STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Ne povas alinomi stacion... diff --git a/src/lang/estonian.txt b/src/lang/estonian.txt index 344f099741..771994978b 100644 --- a/src/lang/estonian.txt +++ b/src/lang/estonian.txt @@ -726,10 +726,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Vali 'om STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Lülita lugude segamine sisse ja välja STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Näita muusikalugude valimise akent -STR_ERROR_NO_SONGS :{WHITE}Valitud muusikakomplekt ei sisalda ühtegi lugu. Ühtegi lugu ei esitata - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Muusikaprogrammi valimine STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Loo number STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programm - '{STRING}' @@ -1394,8 +1391,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Maa värv väik STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Roheline STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Tumeroheline STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Violetne -STR_CONFIG_SETTING_REVERSE_SCROLLING :Vaade liigub vastassuunas: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Vaate liigutamine parema hiireklahviga. Kui see on välja lülitatud, siis hiireosuti juhib vaatepunkti. Kui sisse, siis kaarti STR_CONFIG_SETTING_SMOOTH_SCROLLING :Vaade keskendatakse sujuvalt: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Vaateakna asukohale keskendamise viis, kui vajutatakse väikesele kaardile, või kui vaade keskendatakse mõnele rekvisiidile. Sisse lülitades on liikumine sujuv, välja lülitades läheb vaade kohe sihtpunkti STR_CONFIG_SETTING_MEASURE_TOOLTIP :Ehitamisel mõõtude arvesti näitamine: {STRING} @@ -1427,8 +1422,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command+klõps STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+klõps STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Väljas -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Vaate liigutamine vasaku hiireklahviga: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Lubab kaardi liigutamise vasaku hiireklahvi abil. See lihtsustab mängimist puutetundlikul ekraanil STR_CONFIG_SETTING_AUTOSAVE :Automaatne salvestamine: {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :Vali automaatse salvestamise intervall @@ -2747,6 +2740,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Algne au STR_ABOUT_VERSION :{BLACK}OpenTTD osa {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2018 OpenTTD meeskond +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Mängu salvestamine STR_SAVELOAD_LOAD_CAPTION :{WHITE}Mängu jätkamine @@ -3038,8 +3038,6 @@ STR_TOWN_POPULATION :{BLACK}Maailma STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Linn) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Rahvaarv: {ORANGE}{COMMA}{BLACK} Ehitisi: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Reisijaid eelmisel kuul: {ORANGE}{COMMA}{BLACK} Enim: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Posti eelmisel kuul: {ORANGE}{COMMA}{BLACK} Enim: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Veoseid linna kasvamiseks: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} vajalik STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} on talvel vajalik @@ -4263,7 +4261,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Liiga pa STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Liiga palju raudteejaama osasid STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Liiga palju bussipeatusi STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Liiga palju laadimisplatvorme -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Mõnele teisele jaamale liiga lähedal STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Liiga lähedal teisele dokile STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Liiga lähedal teisele lennuväljale STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Jaama nime ei saa vahetada... diff --git a/src/lang/faroese.txt b/src/lang/faroese.txt index 4d90facad2..ae2729c216 100644 --- a/src/lang/faroese.txt +++ b/src/lang/faroese.txt @@ -647,10 +647,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Vel 'Sj STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Tendra/sløkk bland av skránni STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Vís tónleika spor úrvals glugga -STR_ERROR_NO_SONGS :{WHITE}Eitt tónleika sett uttan sangir er valt. Engir sangir vera spældir - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Úrval av tónleika skráðum STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Spor yvirlit STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Skrá - '{STRING}' @@ -1273,8 +1270,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Liturin av lend STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Grønt STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Myrka grønt STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Blákollulitur -STR_CONFIG_SETTING_REVERSE_SCROLLING :Umvend skrull ætt: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Atburður tá tú skrullar korti við høgra músa knøtti. Um ógilda flytir músin kamerai. Um gilda flytir músin korti. STR_CONFIG_SETTING_SMOOTH_SCROLLING :Mjúka sýnisglugga skrulling: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Stýr hvussu høvuðs sýni skrullar til eitt ávíst stað tá tú trýstir á lítlakorti ella tú tú gevur eini boð um at skrulla til ein ávísan lut á kortinum. Um gilda, skrullar sýni mjúgdliga, um ógilda leypur sýni beint til staði STR_CONFIG_SETTING_MEASURE_TOOLTIP :Vís eina mátingar vegleiðing tá tú brúkar ymisku byggji amboðini: {STRING} @@ -1306,8 +1301,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command+trýst STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+trýst STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Sløkt -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Vinstra-trýst skrulling: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Gilda skrulling av kortinum við at toga ta við vinstra músa knøtti. Hetta er serstakliga hent um tú nýtur ein fingraskugga at skrulla vi STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES :Nýt {STRING} dato sniði til nøvnini á goymdum spølum @@ -2429,6 +2422,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Upprunal STR_ABOUT_VERSION :{BLACK}OpenTTD útgáva {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 OpenTTD toymi +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Goym spæl STR_SAVELOAD_LOAD_CAPTION :{WHITE}Heinta spæl @@ -2650,8 +2650,6 @@ STR_TOWN_POPULATION :{BLACK}Heims f STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Býur) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Fólkatal: {ORANGE}{COMMA}{BLACK} Hús: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Ferðafólk síðsta mánað: {ORANGE}{COMMA}{BLACK} maks: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Postur síðsta mánað: {ORANGE}{COMMA}{BLACK} maks: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Farmur ið tørvast fyri bygda menning: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} krevst STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} krevst um veturin @@ -3725,7 +3723,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Ov nógv STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Ov nógvir tok støð deilir STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Ov nógvir buss steðgir STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Ov nógvar lastbila støðir -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Ov tætt við eina aðra støð/lessi øki STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Ov tætt við eina aðra havn STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Ov tætt við eina aðra floghavn STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Kann ikki navngeva støð... diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index b53a762c9b..e7f5d9d651 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -246,7 +246,7 @@ STR_TOOLTIP_RESIZE :{BLACK}Napsauta STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Suurenna/pienennä ikkuna STR_TOOLTIP_VSCROLL_BAR_SCROLLS_LIST :{BLACK}Vierityspalkki - luettelon vieritys ylös/alas STR_TOOLTIP_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Vierityspalkki - luettelon vieritys vasemmalle/oikealle. -STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC :{BLACK}Tuhoa rakennuksia jne. ruudulta. Ctrl valitsee alueen vinottain. Shift vaihtaa tuhoamistilan ja kustannearvion välillä +STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC :{BLACK}Tuhoa rakennuksia jne. ruudulta. Ctrl valitsee alueen vinottain. Shift vaihtaa tuhoamistilan ja kustannusarvion välillä # Show engines button STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN :{BLACK}Näytä piilotetut @@ -350,15 +350,15 @@ STR_SCENEDIT_TOOLBAR_OPENTTD :{YELLOW}OpenTTD STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR :{YELLOW}Skenaariomuokkain STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD :{BLACK}Siirrä aloituspäivää vuodella taaksepäin STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD :{BLACK}Siirrä aloituspäivää vuodella eteenpäin -STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE :{BLACK}Klikkaa asettaaksesi aloitusvuoden +STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE :{BLACK}Aseta aloitusvuosi napsauttamalla STR_SCENEDIT_TOOLBAR_TOOLTIP_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Näytä kartta, kaupunkihakemisto STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Maaston luonti STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Kaupunkien luonti STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Teollisuuden luonti STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Tienrakennus -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Istuta puita. Shift vaihtaa istutustilan ja kustannearvion välillä +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Istuta puita. Shift vaihtaa istutustilan ja kustannusarvion välillä STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Sijoita kyltti -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Sijoita objekti. Shift vaihtaa rakennustilan ja kustannearvion välillä +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Sijoita objekti. Shift vaihtaa rakennustilan ja kustannusarvion välillä ############ range for SE file menu starts STR_SCENEDIT_FILE_MENU_SAVE_SCENARIO :Tallenna skenaario @@ -475,7 +475,8 @@ STR_ABOUT_MENU_SCREENSHOT :Kuvakaappaus STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Täysin lähennetty kuvakaappaus STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Kuvakaappaus oletuslähennystasolla STR_ABOUT_MENU_GIANT_SCREENSHOT :Koko kartan kuvakaappaus -STR_ABOUT_MENU_ABOUT_OPENTTD :Tietoja 'OpenTTD':stä +STR_ABOUT_MENU_SHOW_FRAMERATE :Näytä kuvataajuus +STR_ABOUT_MENU_ABOUT_OPENTTD :Tietoja OpenTTD:stä STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite-kohdistaja STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Reunat päälle/pois STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS :Likaisten ruutujen värjäys päälle/pois @@ -534,15 +535,15 @@ STR_DAY_NUMBER_31ST :31. ############ range for days ends ############ range for months starts -STR_MONTH_ABBREV_JAN :01. -STR_MONTH_ABBREV_FEB :02. -STR_MONTH_ABBREV_MAR :03. -STR_MONTH_ABBREV_APR :04. -STR_MONTH_ABBREV_MAY :05. -STR_MONTH_ABBREV_JUN :06. -STR_MONTH_ABBREV_JUL :07. -STR_MONTH_ABBREV_AUG :08. -STR_MONTH_ABBREV_SEP :09. +STR_MONTH_ABBREV_JAN :{NBSP}1. +STR_MONTH_ABBREV_FEB :{NBSP}2. +STR_MONTH_ABBREV_MAR :{NBSP}3. +STR_MONTH_ABBREV_APR :{NBSP}4. +STR_MONTH_ABBREV_MAY :{NBSP}5. +STR_MONTH_ABBREV_JUN :{NBSP}6. +STR_MONTH_ABBREV_JUL :{NBSP}7. +STR_MONTH_ABBREV_AUG :{NBSP}8. +STR_MONTH_ABBREV_SEP :{NBSP}9. STR_MONTH_ABBREV_OCT :10. STR_MONTH_ABBREV_NOV :11. STR_MONTH_ABBREV_DEC :12. @@ -650,6 +651,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}Musiikkia ei ole saatavilla STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Raita STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Nimi @@ -669,17 +671,15 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Valitse STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Sekoittaminen päälle/pois STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Näytä musiikkiraitojen valintaikkuna -STR_ERROR_NO_SONGS :{WHITE}Musiikkipaketti jossa ei ole kappaleita on valittu. Musiikkia ei soiteta - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Soittolistan valinta +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Soittolista - '{STRING}' STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Raita STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Soittolista - '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Tyhjennä STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Tyhjennä nykyinen soittolista (vain Oma1 tai Oma2) STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Valitse musiikkiraita lisätäksesi sen nykyiseen soittolistaan (vain Oma1 tai Oma2). -STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Klikkaa raitaa poistaaksesi se nykyisestä ohjelmasta (ainoastaan Custom1 tai Custom2) +STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Poista musiikkiraita nykyseiltä soittolistalta napsauttamalla (ainoastaan Custom1 tai Custom2) # Highscore window STR_HIGHSCORE_TOP_COMPANIES_WHO_REACHED :{BIG_FONT}{BLACK}Parhaat yhtiöt, jotka saavuttivat vuoden {NUM} @@ -714,9 +714,9 @@ STR_SMALLMAP_TOOLTIP_SHOW_LINK_STATS_ON_MAP :{BLACK}Näytä STR_SMALLMAP_TOOLTIP_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Näytä kuljetusreitit kartalla. STR_SMALLMAP_TOOLTIP_SHOW_VEGETATION_ON_MAP :{BLACK}Näytä kasvillisuus kartalla. STR_SMALLMAP_TOOLTIP_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Näytä maanomistajat kartalla. -STR_SMALLMAP_TOOLTIP_INDUSTRY_SELECTION :{BLACK}Klikkaa teollisuustyyppiä näyttääksesi sen. Ctrl+Klik näyttää valitun tyypin. Ctrl+Klik uudestaan näyttää kaikki teollisuustyypit -STR_SMALLMAP_TOOLTIP_COMPANY_SELECTION :{BLACK}Klikkaa yhtiötä näyttääksesi sen omaisuuden. Ctrl+Klik näyttää ainoastaan valitun yhtiön. Ctrl+Klik uudestaan näyttää kaikki yhtiöt -STR_SMALLMAP_TOOLTIP_CARGO_SELECTION :{BLACK}Klikkaa rahtia näyttääksesi tai piilottaaksesi sen. Ctrl+Klik piilottaa kaikki paitsi valitun rahdin. Ctrl+Klik uudelleen palauttaa kaikki rahdit näkyviin +STR_SMALLMAP_TOOLTIP_INDUSTRY_SELECTION :{BLACK}Napsauta teollisuustyyppiä näyttääksesi sen. Ctrl+Klik näyttää valitun tyypin. Ctrl+Klik uudestaan näyttää kaikki teollisuustyypit +STR_SMALLMAP_TOOLTIP_COMPANY_SELECTION :{BLACK}Napsauta yhtiötä näyttääksesi sen omaisuuden. Ctrl+Klik näyttää ainoastaan valitun yhtiön. Ctrl+Klik uudestaan näyttää kaikki yhtiöt +STR_SMALLMAP_TOOLTIP_CARGO_SELECTION :{BLACK}Napsauta rahtia näyttääksesi tai piilottaaksesi sen. Ctrl+Klik piilottaa kaikki paitsi valitun rahdin. Ctrl+Klik uudelleen palauttaa kaikki rahdit näkyviin STR_SMALLMAP_LEGENDA_ROADS :{TINY_FONT}{BLACK}Tiet STR_SMALLMAP_LEGENDA_RAILROADS :{TINY_FONT}{BLACK}Rautatiet @@ -780,12 +780,12 @@ STR_NEWS_MESSAGE_CAPTION :{WHITE}Viesti STR_NEWS_CUSTOM_ITEM :{BIG_FONT}{BLACK}{STRING} STR_NEWS_FIRST_TRAIN_ARRIVAL :{BIG_FONT}{BLACK}Kaupunkilaiset juhlivat . . .{}Ensimmäinen juna saapuu asemalle {STATION}! -STR_NEWS_FIRST_BUS_ARRIVAL :{BIG_FONT}{BLACK}Kaupunkilaiset juhlivat . . .{}Ensimmäinen linja-auto saapuu asemalle {STATION}! -STR_NEWS_FIRST_TRUCK_ARRIVAL :{BIG_FONT}{BLACK}Kaupunkilaiset juhlivat . . .{}Ensimmäinen kuorma-auto saapuu asemalle {STATION}! -STR_NEWS_FIRST_PASSENGER_TRAM_ARRIVAL :{BIG_FONT}{BLACK}Kaupunkilaiset juhlivat . . .{}Ensimmäinen raitiovaunu saapuu asemalle {STATION}! -STR_NEWS_FIRST_CARGO_TRAM_ARRIVAL :{BIG_FONT}{BLACK}Kaupunkilaiset juhlivat . . .{}Ensimmäinen rahtiraitiovaunu saapuu asemalle {STATION}! -STR_NEWS_FIRST_SHIP_ARRIVAL :{BIG_FONT}{BLACK}Kaupunkilaiset juhlivat . . .{}Ensimmäinen laiva saapuu asemalle {STATION}! -STR_NEWS_FIRST_AIRCRAFT_ARRIVAL :{BIG_FONT}{BLACK}Kaupunkilaiset juhlivat . . .{}Ensimmäinen lentokone saapuu asemalle {STATION}! +STR_NEWS_FIRST_BUS_ARRIVAL :{BIG_FONT}{BLACK}Kaupunkilaiset juhlivat . . .{}{STATION} vastaanottaa ensimmäisen linja-auton! +STR_NEWS_FIRST_TRUCK_ARRIVAL :{BIG_FONT}{BLACK}Kaupunkilaiset juhlivat . . .{}{STATION} vastaanottaa ensimmäisen kuorma-auton! +STR_NEWS_FIRST_PASSENGER_TRAM_ARRIVAL :{BIG_FONT}{BLACK}Kaupunkilaiset juhlivat . . .{}{STATION} vastaanottaa ensimmäisen raitiovaunun! +STR_NEWS_FIRST_CARGO_TRAM_ARRIVAL :{BIG_FONT}{BLACK}Kaupunkilaiset juhlivat . . .{}{STATION} vastaanottaa ensimmäisen rahtiraitiovaunun! +STR_NEWS_FIRST_SHIP_ARRIVAL :{BIG_FONT}{BLACK}Kaupunkilaiset juhlivat . . .{}{STATION} vastaanottaa ensimmäisen laivan! +STR_NEWS_FIRST_AIRCRAFT_ARRIVAL :{BIG_FONT}{BLACK}Kaupunkilaiset juhlivat . . .{}{STATION} vastaanottaa ensimmäisen lentokoneen! STR_NEWS_TRAIN_CRASH :{BIG_FONT}{BLACK}Junaonnettomuus!{}{COMMA} kuolee törmäyksen jälkeisessä tulipallossa. STR_NEWS_ROAD_VEHICLE_CRASH_DRIVER :{BIG_FONT}{BLACK}Tasoristeysturma!{}Kuljettaja kuolee junan ja auton törmäyksen jälkeisessä tulipallossa @@ -809,10 +809,11 @@ STR_NEWS_COMPANY_BANKRUPT_TITLE :{BIG_FONT}{BLAC STR_NEWS_COMPANY_BANKRUPT_DESCRIPTION :{BIG_FONT}{BLACK}{STRING} on suljettu velkojien toimesta ja kaikki omaisuus on myyty pois! STR_NEWS_COMPANY_LAUNCH_TITLE :{BIG_FONT}{BLACK}Uusi kuljetusyhtiö perustettu! STR_NEWS_COMPANY_LAUNCH_DESCRIPTION :{BIG_FONT}{BLACK}{STRING} aloittaa rakentamisen kaupungin {TOWN} lähistölle! -STR_NEWS_MERGER_TAKEOVER_TITLE :{BIG_FONT}{BLACK}Yhtiön {STRING} on ottanut haltuun {STRING}! +STR_NEWS_MERGER_TAKEOVER_TITLE :{BIG_FONT}{BLACK}{1:STRING} on ottanut haltuunsa yhtiön {0:STRING}! STR_PRESIDENT_NAME_MANAGER :{BLACK}{PRESIDENT_NAME}{}(pääjohtaja) STR_NEWS_NEW_TOWN :{BLACK}{BIG_FONT}{STRING} rahoitti uuden kaupungin, {TOWN}, rakentamista! +STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK}{BIG_FONT}Uusi kaupunki {TOWN} rakennettu! STR_NEWS_INDUSTRY_CONSTRUCTION :{BIG_FONT}{BLACK}Uusi {STRING} rakennetaan kaupungin {TOWN} lähistölle! STR_NEWS_INDUSTRY_PLANTED :{BIG_FONT}{BLACK}Uusi {STRING} istutetaan kaupungin {TOWN} lähistölle! @@ -834,9 +835,9 @@ STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL :{BIG_FONT}{BLAC STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM :{BIG_FONT}{BLACK}{INDUSTRY}: hyönteisparvet aiheuttavat tuhoa!{}Tuotanto vähenee 50{NBSP}%:lla. STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_SMOOTH :{BIG_FONT}{BLACK}{1:INDUSTRY} tuottaa {0:STRING} {2:COMMA}{NBSP}% entistä vähemmän! -STR_NEWS_TRAIN_IS_WAITING :{WHITE}{VEHICLE} odottaa varikolla +STR_NEWS_TRAIN_IS_WAITING :{WHITE}{VEHICLE} odottaa veturitallilla STR_NEWS_ROAD_VEHICLE_IS_WAITING :{WHITE}{VEHICLE} odottaa varikolla -STR_NEWS_SHIP_IS_WAITING :{WHITE}{VEHICLE} odottaa varikolla +STR_NEWS_SHIP_IS_WAITING :{WHITE}{VEHICLE} odottaa telakalla STR_NEWS_AIRCRAFT_IS_WAITING :{WHITE}{VEHICLE} odottaa lentokonehallissa # Order review system / warnings @@ -868,7 +869,7 @@ STR_NEWS_STATION_NOW_ACCEPTS_CARGO_AND_CARGO :{WHITE}{STATION STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED :{BIG_FONT}{BLACK}Tuki päättynyt:{}{}{STRING} väli {STRING} - {STRING} ei ole enää tuettu STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE :{BIG_FONT}{BLACK}Tuki vedetty pois:{}{}{STRING} kuljetuspalvelu välille {STRING}-{STRING} ei ole enää tuettu -STR_NEWS_SERVICE_SUBSIDY_OFFERED :{BIG_FONT}{BLACK}Tuki tarjottu:{}{}Ensimmäinen {STRING}kuljetus välillä {STRING} - {STRING} saa vuoden mittaisen tuen paikallisviranomaisilta! +STR_NEWS_SERVICE_SUBSIDY_OFFERED :{BIG_FONT}{BLACK}Tuki tarjottu:{}{}Ensimmäinen {STRING}kuljetus välillä {STRING} – {STRING} saa vuoden mittaisen tuen paikallisviranomaisilta! STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF :{BIG_FONT}{BLACK}Tuki myönnetty yhtiölle {STRING}!{}{}{STRING}kuljetus välillä {STRING}-{STRING} tuottaa 50{NBSP}% enemmän seuraavan vuoden ajan! STR_NEWS_SERVICE_SUBSIDY_AWARDED_DOUBLE :{BIG_FONT}{BLACK}Tuki myönnetty yhtiölle {STRING}!{}{}{STRING}kuljetus välillä {STRING}-{STRING} tuottaa tuplaten seuraavan vuoden ajan! STR_NEWS_SERVICE_SUBSIDY_AWARDED_TRIPLE :{BIG_FONT}{BLACK}Tuki myönnetty yhtiölle {STRING}!{}{}{STRING}kuljetus välillä {STRING}-{STRING} tuottaa kolminkertaisesti seuraavan vuoden ajan! @@ -876,7 +877,7 @@ STR_NEWS_SERVICE_SUBSIDY_AWARDED_QUADRUPLE :{BIG_FONT}{BLAC STR_NEWS_ROAD_REBUILDING :{BIG_FONT}{BLACK}{TOWN}: liikennekaaos!{}{}{STRING} rahoittaa katujen kunnostuksen; autoilijoille odotettavissa kuusi kuukautta kurjuutta! STR_NEWS_EXCLUSIVE_RIGHTS_TITLE :{BIG_FONT}{BLACK}Kuljetusmonopoli! -STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLACK}Kaupungin {TOWN} paikallisviranomaiset allekirjoittavat sopimuksen yhtiön {STRING} kanssa vuoden pituisesta kuljetusyksinoikeudesta! +STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLACK}{TOWN} ja {STRING} allekirjoittavat sopimuksen vuoden pituisesta kuljetusyksinoikeudesta! # Extra view window STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Näkymä {COMMA} @@ -895,10 +896,10 @@ STR_GAME_OPTIONS_CURRENCY_GBP :Englannin punta STR_GAME_OPTIONS_CURRENCY_USD :Yhdysvaltain dollari (USD) STR_GAME_OPTIONS_CURRENCY_EUR :Euro (EUR) STR_GAME_OPTIONS_CURRENCY_JPY :Japanin jeni (JPY) -STR_GAME_OPTIONS_CURRENCY_ATS :Itävallan shillinki (ATS) +STR_GAME_OPTIONS_CURRENCY_ATS :Itävallan šillinki (ATS) STR_GAME_OPTIONS_CURRENCY_BEF :Belgian frangi (BEF) STR_GAME_OPTIONS_CURRENCY_CHF :Sveitsin frangi (CHF) -STR_GAME_OPTIONS_CURRENCY_CZK :Tsekin koruna (CZK) +STR_GAME_OPTIONS_CURRENCY_CZK :Tšekin koruna (CZK) STR_GAME_OPTIONS_CURRENCY_DEM :Saksan markka (DEM) STR_GAME_OPTIONS_CURRENCY_DKK :Tanskan kruunu (DKK) STR_GAME_OPTIONS_CURRENCY_ESP :Espanjan peseta (ESP) @@ -912,7 +913,7 @@ STR_GAME_OPTIONS_CURRENCY_NLG :Hollannin gulde STR_GAME_OPTIONS_CURRENCY_NOK :Norjan kruunu (NOK) STR_GAME_OPTIONS_CURRENCY_PLN :Puolan złoty (PLN) STR_GAME_OPTIONS_CURRENCY_RON :Romanian leu (RON) -STR_GAME_OPTIONS_CURRENCY_RUR :Venjän rupla (RUR) +STR_GAME_OPTIONS_CURRENCY_RUR :Venäjän rupla (RUR) STR_GAME_OPTIONS_CURRENCY_SIT :Slovenian tolari (SIT) STR_GAME_OPTIONS_CURRENCY_SEK :Ruotsin kruunu (SEK) STR_GAME_OPTIONS_CURRENCY_TRY :Turkin liira (TRY) @@ -925,12 +926,13 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :Etelä-Afrikan STR_GAME_OPTIONS_CURRENCY_CUSTOM :Oma... STR_GAME_OPTIONS_CURRENCY_GEL :Georgian lari (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :Iranin rial (IRR) +STR_GAME_OPTIONS_CURRENCY_RUB :Uusi Venäjän rupla (RUB) ############ end of currency region -STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Ajoneuvot +STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Kulkuneuvot STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_TOOLTIP :{BLACK}Valitse kummalla puolella tietä ajetaan. -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Vasemmalla kaistalla -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Oikealla kaistalla +STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Vasemmanpuolinen liikenne +STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Oikeanpuolinen liikenne STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Kaupunkien nimet STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Valitse kaupunkien nimien tyyli. @@ -951,7 +953,7 @@ STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norjalainen STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Unkarilainen STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Itävaltalainen STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Romanialainen -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Tsekkiläinen +STR_GAME_OPTIONS_TOWN_NAME_CZECH :Tšekkiläinen STR_GAME_OPTIONS_TOWN_NAME_SWISS :Sveitsiläinen STR_GAME_OPTIONS_TOWN_NAME_DANISH :Tanskalainen STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turkkilainen @@ -1096,11 +1098,11 @@ STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Sulje ka STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT :(selitystä ei saatavilla) STR_CONFIG_SETTING_DEFAULT_VALUE :{LTBLUE}Oletusarvo: {ORANGE}{STRING} STR_CONFIG_SETTING_TYPE :{LTBLUE}Asetuksen tyyppi: {ORANGE}{STRING} -STR_CONFIG_SETTING_TYPE_CLIENT :Yleinen asetus (ei tallenneta tallenteisiin; vaikuttaa kaikkiin peleihin) +STR_CONFIG_SETTING_TYPE_CLIENT :Yleinen asetus (ei tallenneta tallennuksiin; vaikuttaa kaikkiin peleihin) STR_CONFIG_SETTING_TYPE_GAME_MENU :Pelin asetus (tallennetaan tallenteisiin; vaikuttaa vain uusiin peleihin) STR_CONFIG_SETTING_TYPE_GAME_INGAME :Pelin asetus (tallennetaan tallenteeseen; vaikuttaa vain nykyiseen peliin) STR_CONFIG_SETTING_TYPE_COMPANY_MENU :Yhtiön asetus (tallennetaan tallenteisiin; vaikuttaa vain uusiin peleihin) -STR_CONFIG_SETTING_TYPE_COMPANY_INGAME :Yhtiön asetus (tallennetaan tallenteeseen; vaikuttaa vain nykyiseen yhtiöön) +STR_CONFIG_SETTING_TYPE_COMPANY_INGAME :Yhtiön asetus (tallennetaan tallennukseen; vaikuttaa vain nykyiseen yhtiöön) STR_CONFIG_SETTING_RESTRICT_CATEGORY :{BLACK}Kategoria: STR_CONFIG_SETTING_RESTRICT_TYPE :{BLACK}Tyyppi: @@ -1280,9 +1282,9 @@ STR_CONFIG_SETTING_ERRMSG_DURATION :Virheilmoituste STR_CONFIG_SETTING_ERRMSG_DURATION_HELPTEXT :Aika virheilmoitusten näyttämiseen punaisessa ikkunassa. Huomaa, että jotkut (kriittiset) virheilmoitukset eivät sulkeudu automaattisesti tämän ajan jälkeen, vaan ne on suljettava käsin STR_CONFIG_SETTING_ERRMSG_DURATION_VALUE :{COMMA} sekunti{P 0 "" a} STR_CONFIG_SETTING_HOVER_DELAY :Näytä työkaluvihjeet: {STRING} -STR_CONFIG_SETTING_HOVER_DELAY_HELPTEXT :Viive ennen työkaluvihjeen näyttämistä, kun hiiren kursoria pidetään käyttöliittymäelementin päällä. Vaihtoehtoisesti työkaluvihjeen saa myös näkymiin painamalla hiiren oikeaa näppäintä jos arvoksi on määritetty 0. +STR_CONFIG_SETTING_HOVER_DELAY_HELPTEXT :Viive ennen työkaluvihjeen näyttämistä, kun hiiren kursoria pidetään käyttöliittymäelementin päällä. Vaihtoehtoisesti työkaluvihjeen saa myös näkymiin painamalla hiiren oikeata painiketta, kun arvoksi on määritetty 0. STR_CONFIG_SETTING_HOVER_DELAY_VALUE :Pidä hiirtä päällä {COMMA} millisekunti{P 0 "" a} -STR_CONFIG_SETTING_HOVER_DELAY_DISABLED :Hiiren oikea näppäin +STR_CONFIG_SETTING_HOVER_DELAY_DISABLED :Hiiren oikea painike STR_CONFIG_SETTING_POPULATION_IN_LABEL :Näytä kaupungin asukasluku kaupungin nimessä: {STRING} STR_CONFIG_SETTING_POPULATION_IN_LABEL_HELPTEXT :Näytä kaupunkien asukasluku kartalla STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS :Viivojen paksuus kuvaajissa: {STRING} @@ -1337,8 +1339,12 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Maaston väri k STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Vihreä STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Tummanvihreä STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Violetti -STR_CONFIG_SETTING_REVERSE_SCROLLING :Käänteinen vierityssuunta: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Käyttäytyminen siirrettäessä näkymää oikealla hiiren näppäimellä. Mikäli pois käytöstä, hiiri liikuttaa kameraa. Mikäli käytössä, hiiri liikuttaa karttaa +STR_CONFIG_SETTING_SCROLLMODE :Näkymän vieritystapa: {STRING} +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Toiminta karttaa vieritettäessä +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Siirrä näkymää hiiren oikealla painikkeella, hiiren sijainti lukiten +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Siirrä karttaa hiiren oikealla painikkeella, hiiren sijainti lukiten +STR_CONFIG_SETTING_SCROLLMODE_RMB :Siirrä karttaa hiiren oikealla painikkeella +STR_CONFIG_SETTING_SCROLLMODE_LMB :Siirrä karttaa hiiren vasemmalla painikkeella STR_CONFIG_SETTING_SMOOTH_SCROLLING :Näkymän tasainen vieritys: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Hallitse miten päänäkymä siirtyy valittuun paikkaan karttaa klikattaessa tai käytettäessä komentoa joka muuttaa näkymän sijaintia. Mikäli käytössä, päänäkymä siirtyy uuteen sijaintiin pehmeäesti, muutoin se hyppää suoraan valittuun sijaintiin STR_CONFIG_SETTING_MEASURE_TOOLTIP :Näytä mittauksen työkaluvihje, kun käytetään rakennustyökaluja: {STRING} @@ -1360,18 +1366,16 @@ STR_CONFIG_SETTING_SCROLLWHEEL_MULTIPLIER_HELPTEXT :Määritä hiir STR_CONFIG_SETTING_OSK_ACTIVATION :Virtuaalinäppäimistö: {STRING} STR_CONFIG_SETTING_OSK_ACTIVATION_HELPTEXT :Valitse tapa, jolla virtuaalinäppäimistö avataan syötettäessä tekstiä kun käytössä on ainoastaan osoitinlaite. Tämä on tarkoitettu pienille laitteille, joissa ei ole fyysistä näppäimistöä STR_CONFIG_SETTING_OSK_ACTIVATION_DISABLED :Pois käytöstä -STR_CONFIG_SETTING_OSK_ACTIVATION_DOUBLE_CLICK :Tuplaklikkaus -STR_CONFIG_SETTING_OSK_ACTIVATION_SINGLE_CLICK_FOCUS :Yksi klikkaus (kun kohdistettuna) -STR_CONFIG_SETTING_OSK_ACTIVATION_SINGLE_CLICK :Yksi klikkaus (välittömästi) +STR_CONFIG_SETTING_OSK_ACTIVATION_DOUBLE_CLICK :Kaksoisnapsautus +STR_CONFIG_SETTING_OSK_ACTIVATION_SINGLE_CLICK_FOCUS :Yksi napsautus (kun kohdistettuna) +STR_CONFIG_SETTING_OSK_ACTIVATION_SINGLE_CLICK :Yksi napsautus (välitön) STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU :Oikean painikkeen emulointi: {STRING} -STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_HELPTEXT :Määritä kuinka hiiren oikean näppäimen painalluksia emuloidaan +STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_HELPTEXT :Valitse, miten hiiren oikean painikkeen painalluksia emuloidaan STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+Klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Pois -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Vasemmalla hiiren painikkeella liikkuminen: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Salli näkymän siirtäminen vetämällä hiiren vasemmalla näppäimellä. Hyödyllinen erityisesti kosketusnäyttöä käytettäessä STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Sulje ikkuna hiiren oikealla painikkeella napsauttamalla: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Ikkunat sulkeutuvat, kun niitä napsautetaan hiiren oikealla painikkeella. Tämä korvaa tavallisesti näkyvän työkaluvihjeen! @@ -1386,9 +1390,9 @@ STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_ISO :ISO (2008-12-31 STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME :Uusi peli alkaa pysäytettynä: {STRING} STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME_HELPTEXT :Mikäli käytössä, peli pysäytetään automaattisesti uuden pelin alussa, mahdollistaen esimerkiksi kartan tarkemman tutkimisen -STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL :Pelin ollessa pysäytetty, salli: {STRING} +STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL :Salli pelin ollessa pysäytettynä: {STRING} STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_HELPTEXT :Valitse käytössä olevat toiminnot pelin ollessa pysäytettynä -STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_NO_ACTIONS :Ei mitkään toiminnot +STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_NO_ACTIONS :Ei mitään toimintoja STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_ALL_NON_CONSTRUCTION :Kaikki ei-rakennustoiminnot STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_ALL_NON_LANDSCAPING :Kaikki paitsi maastonmuokkaustoiminnot STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_ALL_ACTIONS :Kaikki toiminnot @@ -1396,8 +1400,8 @@ STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS :Käytä ryhmiä STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS_HELPTEXT :Salli kehittyneiden kulkuneuvolistojen käyttö kulkuneuvojen ryhmittelyssä STR_CONFIG_SETTING_LOADING_INDICATORS :Lastausilmaisimet: {STRING} STR_CONFIG_SETTING_LOADING_INDICATORS_HELPTEXT :Määritä näytetäänkö lastausilmaisimet kulkuneuvojen yläpuolella lastatessa ja purettaessa rahtia -STR_CONFIG_SETTING_TIMETABLE_IN_TICKS :Näytä aikataulu tickseissä päivien sijaan: {STRING} -STR_CONFIG_SETTING_TIMETABLE_IN_TICKS_HELPTEXT :Näytä aikataulun ajat päivien sijasta tickeinä +STR_CONFIG_SETTING_TIMETABLE_IN_TICKS :Näytä aikataulu askelina päivien sijaan: {STRING} +STR_CONFIG_SETTING_TIMETABLE_IN_TICKS_HELPTEXT :Näytä aikataulun ajat päivien sijasta askelina STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE :Näytä saapuminen ja lähtö aikatauluissa: {STRING} STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE_HELPTEXT :Näytä odotetut saapumis- ja lähtemisajat aikatauluissa STR_CONFIG_SETTING_QUICKGOTO :Nopea kulkuneuvon käskyjen luominen: {STRING} @@ -1422,8 +1426,8 @@ STR_CONFIG_SETTING_SOUND_NEW_YEAR :Vuoden loppu: { STR_CONFIG_SETTING_SOUND_NEW_YEAR_HELPTEXT :Toista ääni vuoden lopussa verrattaessa yhtiön tulosta edelliseen vuoteen STR_CONFIG_SETTING_SOUND_CONFIRM :Rakentaminen: {STRING} STR_CONFIG_SETTING_SOUND_CONFIRM_HELPTEXT :Toista ääni onnistuneen rakennus- tai muun toiminnon jälkeen -STR_CONFIG_SETTING_SOUND_CLICK :Painikkeiden klikkaus: {STRING} -STR_CONFIG_SETTING_SOUND_CLICK_HELPTEXT :Piippaa klikattaessa painikkeita +STR_CONFIG_SETTING_SOUND_CLICK :Painikkeiden napsautus: {STRING} +STR_CONFIG_SETTING_SOUND_CLICK_HELPTEXT :Piippaa painikkeita napsauttaessa STR_CONFIG_SETTING_SOUND_DISASTER :Vahingot/onnettomuudet: {STRING} STR_CONFIG_SETTING_SOUND_DISASTER_HELPTEXT :Toista vahinkojen ja onnettomuuksien äänet STR_CONFIG_SETTING_SOUND_VEHICLE :Ajoneuvot: {STRING} @@ -1549,8 +1553,8 @@ STR_CONFIG_SETTING_TOWN_LAYOUT :Uusissa kaupung STR_CONFIG_SETTING_TOWN_LAYOUT_HELPTEXT :Kaupunkien käyttämä tieverkon kaava STR_CONFIG_SETTING_TOWN_LAYOUT_DEFAULT :Alkuperäinen STR_CONFIG_SETTING_TOWN_LAYOUT_BETTER_ROADS :Parempia teitä -STR_CONFIG_SETTING_TOWN_LAYOUT_2X2_GRID :2x2-ruudukko -STR_CONFIG_SETTING_TOWN_LAYOUT_3X3_GRID :3x3-ruudukko +STR_CONFIG_SETTING_TOWN_LAYOUT_2X2_GRID :2×2-ruudukko +STR_CONFIG_SETTING_TOWN_LAYOUT_3X3_GRID :3×3-ruudukko STR_CONFIG_SETTING_TOWN_LAYOUT_RANDOM :Satunnainen STR_CONFIG_SETTING_ALLOW_TOWN_ROADS :Kaupungit saavat rakentaa teitä: {STRING} STR_CONFIG_SETTING_ALLOW_TOWN_ROADS_HELPTEXT :Salli kaupunkien rakentaa teitä kasvaessaan. Mikäli pois käytöstä, kaupungit eivät voi rakentaa teitä itse @@ -1571,9 +1575,9 @@ STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_RAINFOREST :Vain sademetsii STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_ALL :Kaikkialle STR_CONFIG_SETTING_TOOLBAR_POS :Päätyökalupalkin sijainti: {STRING} -STR_CONFIG_SETTING_TOOLBAR_POS_HELPTEXT :Ruudun yläreunassa olevan työkalupalkin sijainti leveyssuunnassa +STR_CONFIG_SETTING_TOOLBAR_POS_HELPTEXT :Ruudun yläreunassa olevan työkalupalkin sijainti vaakasuunnassa STR_CONFIG_SETTING_STATUSBAR_POS :Tilarivin sijainti: {STRING} -STR_CONFIG_SETTING_STATUSBAR_POS_HELPTEXT :Ruudun alareunassa olevan tilapalkin sijanti leveyssuunnassa +STR_CONFIG_SETTING_STATUSBAR_POS_HELPTEXT :Ruudun alareunassa olevan tilapalkin sijanti vaakasuunnassa STR_CONFIG_SETTING_SNAP_RADIUS :Ikkunoiden kiinnittymisetäisyys: {STRING} STR_CONFIG_SETTING_SNAP_RADIUS_HELPTEXT :Ikkunoiden välinen etäisyys ennen niiden kohdistamista toistensa kanssa STR_CONFIG_SETTING_SNAP_RADIUS_VALUE :{COMMA} pikseli{P 0 "" ä} @@ -1600,7 +1604,7 @@ STR_CONFIG_SETTING_TOWN_GROWTH_NORMAL :Tavallinen STR_CONFIG_SETTING_TOWN_GROWTH_FAST :Nopea STR_CONFIG_SETTING_TOWN_GROWTH_VERY_FAST :Erittäin nopea STR_CONFIG_SETTING_LARGER_TOWNS :Suurkaupunkien osuus: {STRING} -STR_CONFIG_SETTING_LARGER_TOWNS_HELPTEXT :Suurkaupungiksi muuttuvien kaupunkien määrä, eli kaupungit jotka ovat suurempia ja kasvavat nopeammin +STR_CONFIG_SETTING_LARGER_TOWNS_HELPTEXT :Suurkaupungiksi muuttuvien kaupunkien määrä, eli suurempana aloittavat ja nopeammin kasvavat kaupungit STR_CONFIG_SETTING_LARGER_TOWNS_VALUE :1 / {COMMA} STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Ei yhtään STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Kasvukerroin alussa: {STRING} @@ -1785,7 +1789,7 @@ STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS # Abandon game -STR_ABANDON_GAME_CAPTION :{WHITE}Lopeta peli +STR_ABANDON_GAME_CAPTION :{WHITE}Pelin lopetus STR_ABANDON_GAME_QUERY :{YELLOW}Lopetetaanko peli? STR_ABANDON_SCENARIO_QUERY :{YELLOW}Lopetetaanko skenaario? @@ -1988,7 +1992,7 @@ STR_NETWORK_LANG_ANY :mikä tahansa STR_NETWORK_LANG_ENGLISH :englanti STR_NETWORK_LANG_GERMAN :saksa STR_NETWORK_LANG_FRENCH :ranska -STR_NETWORK_LANG_BRAZILIAN :brasilia +STR_NETWORK_LANG_BRAZILIAN :brasilianportugali STR_NETWORK_LANG_BULGARIAN :bulgaria STR_NETWORK_LANG_CHINESE :kiina STR_NETWORK_LANG_CZECH :tšekki @@ -2015,7 +2019,7 @@ STR_NETWORK_LANG_TURKISH :turkki STR_NETWORK_LANG_UKRAINIAN :ukraina STR_NETWORK_LANG_AFRIKAANS :afrikaans STR_NETWORK_LANG_CROATIAN :kroatia -STR_NETWORK_LANG_CATALAN :katalan +STR_NETWORK_LANG_CATALAN :katalaani STR_NETWORK_LANG_ESTONIAN :viro STR_NETWORK_LANG_GALICIAN :galego STR_NETWORK_LANG_GREEK :kreikka @@ -2190,7 +2194,7 @@ STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} on STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} on poistunut pelistä ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} on muuttanut nimekseen {STRING} STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} antoi yhtiöllesi {2:CURRENCY_LONG} -STR_NETWORK_MESSAGE_GAVE_MONEY_AWAY :*** Annoit henkilölle {1:STRING} {2:CURRENCY_LONG} +STR_NETWORK_MESSAGE_GAVE_MONEY_AWAY :*** Annoit yhtiölle {1:STRING} {2:CURRENCY_LONG} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Palvelin sulki istunnon STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Palvelin käynnistyy uudelleen...{}Odota, ole hyvä... @@ -2200,7 +2204,7 @@ STR_CONTENT_TYPE_CAPTION :{BLACK}Tyyppi STR_CONTENT_TYPE_CAPTION_TOOLTIP :{BLACK}Sisällön tyyppi STR_CONTENT_NAME_CAPTION :{BLACK}Nimi STR_CONTENT_NAME_CAPTION_TOOLTIP :{BLACK}Sisällön nimi -STR_CONTENT_MATRIX_TOOLTIP :{BLACK}Klikkaa kohtaa nähdäkesi lisätiedot{}Klikkaa valintaruutua valitaksesi sen ladattavaksi +STR_CONTENT_MATRIX_TOOLTIP :{BLACK}Katso lisätiedot napsauttamalla riviä{}Valitse ladattavaksi valintaruutua napsauttamalla STR_CONTENT_SELECT_ALL_CAPTION :{BLACK}Valitse kaikki STR_CONTENT_SELECT_ALL_CAPTION_TOOLTIP :{BLACK}Merkitse kaikki sisältö ladattavaksi STR_CONTENT_SELECT_UPDATES_CAPTION :{BLACK}Valitse päivitykset @@ -2285,6 +2289,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Rahtivir STR_LINKGRAPH_LEGEND_ALL :{BLACK}Kaikki STR_LINKGRAPH_LEGEND_NONE :{BLACK}Ei mitään STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Valitse näytettävät yhtiöt +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}käyttämätön @@ -2313,16 +2318,16 @@ STR_RAIL_TOOLBAR_ELRAIL_CONSTRUCTION_CAPTION :Sähköradan ra STR_RAIL_TOOLBAR_MONORAIL_CONSTRUCTION_CAPTION :Yksiraiteisen rakentaminen STR_RAIL_TOOLBAR_MAGLEV_CONSTRUCTION_CAPTION :Maglevin rakentaminen -STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Rakenna rautateitä. Ctrl vaihtaa rakennus/poistotilan välillä. Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}Rakenna rautatiet käyttäen Autorail-tilaa. Ctrl vaihtaa rakennus/poistotilan välillä. Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Rakenna veturitalli (junien ostamista ja huoltoa varten). Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}Muunna raide reittipisteeksi. Ctrl liittää reittipisteet. Shift vaihtaa muuntotilan ja kustannearvion välillä -STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}Rakenna rautatieasema. Ctrl liittää asemat. Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Rakenna opastimia. Ctrl vaihtaa joko siipiopastimet tai valo-opastimet{}Vetäminen rakentaa opastimia suoralle rautatielle. Ctrl rakentaa opastimia seuraavaan risteykseen saakka{}Ctrl+Click avaa opastimenvalintaikkunan. Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE :{BLACK}Rakenna rautatiesilta. Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL :{BLACK}Rakenna rautatietunneli. Shift vaihtaa rakennustilan ja kustannearvion välillä +STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Rakenna rautateitä. Ctrl vaihtaa rakennus-/poistotilan välillä. Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}Rakenna rautatietä automaattisesti valittuun suuntaan. Ctrl vaihtaa rakennus-/poistotilan välillä. Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Rakenna veturitalli (junien ostamista ja huoltoa varten). Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}Muunna raide reittipisteeksi. Ctrl liittää reittipisteet. Shift vaihtaa muuntotilan ja kustannusarvion välillä +STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}Rakenna rautatieasema. Ctrl liittää asemat. Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Rakenna opastimia. Ctrl vaihtaa joko siipiopastimet tai valo-opastimet{}Vetäminen rakentaa opastimia suoralle rautatielle. Ctrl rakentaa opastimia seuraavaan risteykseen saakka{}Ctrl+Click avaa opastimenvalintaikkunan. Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE :{BLACK}Rakenna rautatiesilta. Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL :{BLACK}Rakenna rautatietunneli. Shift vaihtaa rakennustilan ja kustannusarvion välillä STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Rautatien, opastimien, reittipisteiden ja asemien rakentaminen/poisto päälle/pois. Pidä pohjassa Ctrl-näppäintä poistaaksesi myös aseman tai reittipisteen alla olevat raiteet. -STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL :{BLACK}Muunna/päivitä raidetyyppi. Shift vaihtaa muuntotilan ja kustannearvion välillä +STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL :{BLACK}Muunna/päivitä raidetyyppi. Shift vaihtaa muuntotilan ja kustannusarvion välillä STR_RAIL_NAME_RAILROAD :Rautatie STR_RAIL_NAME_ELRAIL :Sähköistetty rautatie @@ -2368,7 +2373,7 @@ STR_BUILD_SIGNAL_ELECTRIC_EXIT_TOOLTIP :{BLACK}Poistumi STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Yhdistelmäopastin (valo-opastin){}Yhdistelmäopastin toimii yhtä aikaa tulo- ja poistumisopastimena. Tämän avulla on mahdollista luoda suuria "opastinpuita" STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}Reittiopastin (valo-opastin){}Reittiopastin varmistaa junille turvallisen reitin ja siten mahdollistaa useampien junien yhtäaikaisen liikenteen moniraiteisissa risteyksissä. Tavalliset reittiopastimet voi ohittaa takakautta STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP :{BLACK}Yksisuuntainen reittiopastin (valo-opastin){}Reittiopastin varmistaa junille turvallisen reitin ja siten mahdollistaa useampien junien yhtäaikaisen liikenteen moniraiteisissa risteyksissä. Yksisuuntaisia opastimia ei voi ohittaa takakautta -STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Opastinten muuntaminen{}Kun tämä on valittu, olemassaolevan opastimen klikkaaminen muuntaa siitä valituntyyppisen ja -muotoisen. Ctrl+Klik vaihtaa nykyistä opastimen muotoa. Shift+Klik näyttää muuntamisen kustannearvion +STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Opastinten muuntaminen{}Kun tämä on valittu, olemassaolevan opastimen napsauttaminen muuntaa siitä valituntyyppisen ja -muotoisen. Ctrl+Klik vaihtaa nykyistä opastimen muotoa. Shift+Klik näyttää muuntamisen kustannusarvion STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP :{BLACK}Opastimien väli vetämällä lisättäessä STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP :{BLACK}Pienennä opastimien väliä vetämällä lisättäessä STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Suurenna opastimien väliä vetämällä lisättäessä @@ -2392,29 +2397,29 @@ STR_BRIDGE_TUBULAR_SILICON :Putkirakenne, p # Road construction toolbar STR_ROAD_TOOLBAR_ROAD_CONSTRUCTION_CAPTION :{WHITE}Tien rakentaminen STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION :{WHITE}Raitiotien rakentaminen -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION :{BLACK}Rakenna tieosuus. Ctrl vaihtaa rakennus/poistotilan välillä. Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION :{BLACK}Rakenna raitiotietä. Ctrl vaihtaa rakennus/poistotilan välillä. Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD :{BLACK}Rakenna tieosuus käyttäen Autoroad-tilaa. Ctrl vaihtaa rakennus/poistotilan välillä. Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM :{BLACK}Rakenna raitiotieosuus käyttäen Autotram-tilaa. Ctrl vaihtaa rakennus/poistotilan välillä. Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Rakenna autovarikko (ajoneuvojen ostamista ja huoltoa varten). Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT :{BLACK}Rakenna raitiotievarikko (vaunujen ostamiseen ja korjaamiseen). Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION :{BLACK}Rakenna linja-autoasema. Ctrl liittää asemat. Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION :{BLACK}Rakenna matkustaja-asema. Ctrl liittää asemat. Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY :{BLACK}Rakenna lastauslaituri. Ctrl liittää asemat. Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_CARGO_TRAM_STATION :{BLACK}Rakenna rahtiasema. Ctrl liittää asemat. Shift vaihtaa rakennustilan ja kustannearvion välillä +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION :{BLACK}Rakenna tieosuus. Ctrl vaihtaa rakennus-/poistotilan välillä. Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION :{BLACK}Rakenna raitiotietä. Ctrl vaihtaa rakennus-/poistotilan välillä. Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD :{BLACK}Rakenna tieosuus automaattisesti valittuun suuntaan. Ctrl vaihtaa rakennus-/poistotilan välillä. Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM :{BLACK}Rakenna raitiotieosuus automaattisesti valittuun suuntaan. Ctrl vaihtaa rakennus-/poistotilan välillä. Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Rakenna autovarikko (ajoneuvojen ostamista ja huoltoa varten). Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT :{BLACK}Rakenna raitiotievarikko (vaunujen ostamiseen ja korjaamiseen). Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION :{BLACK}Rakenna linja-autoasema. Ctrl liittää asemat. Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION :{BLACK}Rakenna raitiotien matkustaja-asema. Ctrl liittää asemat. Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY :{BLACK}Rakenna lastauslaituri. Ctrl liittää asemat. Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_CARGO_TRAM_STATION :{BLACK}Rakenna raitiotien rahtiasema. Ctrl liittää asemat. Shift vaihtaa rakennustilan ja kustannusarvion välillä STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD :{BLACK}Ota yksisuuntaiset tiet käyttöön/pois käytöstä -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE :{BLACK}Rakenna maantiesilta. Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE :{BLACK}Rakenna raitiotiesilta. Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Rakenna maantietunneli. Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Rakenna raitiotietunneli. Shift vaihtaa rakennustilan ja kustannearvion välillä +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE :{BLACK}Rakenna maantiesilta. Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE :{BLACK}Rakenna raitiotiesilta. Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Rakenna maantietunneli. Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Rakenna raitiotietunneli. Shift vaihtaa rakennustilan ja kustannusarvion välillä STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Tien rakentaminen/siirtäminen päälle/pois STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Vaihda raitiotien rakentamisen ja purkamisen välillä # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Autovarikon suunta STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Valitse autovarikon suunta. -STR_BUILD_DEPOT_TRAM_ORIENTATION_CAPTION :{WHITE}Varikon suunta -STR_BUILD_DEPOT_TRAM_ORIENTATION_SELECT_TOOLTIP :{BLACK}Valitse varikon suunta +STR_BUILD_DEPOT_TRAM_ORIENTATION_CAPTION :{WHITE}Raitiotievarikon suunta +STR_BUILD_DEPOT_TRAM_ORIENTATION_SELECT_TOOLTIP :{BLACK}Valitse raitiotievarikon suunta # Road vehicle station construction window STR_STATION_BUILD_BUS_ORIENTATION :{WHITE}Linja-autoaseman suunta @@ -2429,12 +2434,12 @@ STR_STATION_BUILD_CARGO_TRAM_ORIENTATION_TOOLTIP :{BLACK}Valitse # Waterways toolbar (last two for SE only) STR_WATERWAYS_TOOLBAR_CAPTION :{WHITE}Vesireittien rakentaminen STR_WATERWAYS_TOOLBAR_CAPTION_SE :{WHITE}Vesireitit -STR_WATERWAYS_TOOLBAR_BUILD_CANALS_TOOLTIP :{BLACK}Rakenna kanavia. Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_WATERWAYS_TOOLBAR_BUILD_LOCKS_TOOLTIP :{BLACK}Rakenna sulku. Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_WATERWAYS_TOOLBAR_BUILD_DEPOT_TOOLTIP :{BLACK}Rakenna telakka (laivojen ostamista ja huoltamista varten). Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_WATERWAYS_TOOLBAR_BUILD_DOCK_TOOLTIP :{BLACK}Rakenna satama. Ctrl liittää asemat. Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_WATERWAYS_TOOLBAR_BUOY_TOOLTIP :{BLACK}Sijoita poiju: voidaan käyttää reittipisteenä. Shift vaihtaa rakennustilan ja kustannearvion välillä -STR_WATERWAYS_TOOLBAR_BUILD_AQUEDUCT_TOOLTIP :{BLACK}Rakenna akvedukti. Shift vaihtaa rakennustilan ja kustannearvion välillä +STR_WATERWAYS_TOOLBAR_BUILD_CANALS_TOOLTIP :{BLACK}Rakenna kanavia. Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_WATERWAYS_TOOLBAR_BUILD_LOCKS_TOOLTIP :{BLACK}Rakenna sulku. Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_WATERWAYS_TOOLBAR_BUILD_DEPOT_TOOLTIP :{BLACK}Rakenna telakka (laivojen ostamista ja huoltamista varten). Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_WATERWAYS_TOOLBAR_BUILD_DOCK_TOOLTIP :{BLACK}Rakenna satama. Ctrl liittää asemat. Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_WATERWAYS_TOOLBAR_BUOY_TOOLTIP :{BLACK}Sijoita poiju, jota voi käyttää reittipisteenä. Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_WATERWAYS_TOOLBAR_BUILD_AQUEDUCT_TOOLTIP :{BLACK}Rakenna akvedukti. Shift vaihtaa rakennustilan ja kustannusarvion välillä STR_WATERWAYS_TOOLBAR_CREATE_LAKE_TOOLTIP :{BLACK}Määrittele vesialue.{}Tee kanava, paitsi jos Ctrl on painettuna merenpinnalla. Tällöin meri laajenee ympäristöön. STR_WATERWAYS_TOOLBAR_CREATE_RIVER_TOOLTIP :{BLACK}Sijoita jokia @@ -2447,7 +2452,7 @@ STR_STATION_BUILD_DOCK_CAPTION :{WHITE}Satama # Airport toolbar STR_TOOLBAR_AIRCRAFT_CAPTION :{WHITE}Lentokentät -STR_TOOLBAR_AIRCRAFT_BUILD_AIRPORT_TOOLTIP :{BLACK}Rakenna lentokenttä. Ctrl liittää asemat. Shift vaihtaa rakennustilan ja kustannearvion välillä +STR_TOOLBAR_AIRCRAFT_BUILD_AIRPORT_TOOLTIP :{BLACK}Rakenna lentokenttä. Ctrl liittää asemat. Shift vaihtaa rakennustilan ja kustannusarvion välillä # Airport construction window STR_STATION_BUILD_AIRPORT_CAPTION :{WHITE}Lentokentän valinta @@ -2474,17 +2479,17 @@ STR_STATION_BUILD_NOISE :{BLACK}Aiheutet # Landscaping toolbar STR_LANDSCAPING_TOOLBAR :{WHITE}Maastonmuokkaus -STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Laske ruudun kulmaa. Vetäminen laskee ensimmäistä valittua kulmaa ja tasoittaa valitun alueen kulman korkeudelle. Ctrl valitsee alueen vinottain. Shift vaihtaa muokkaustilan ja kustannearvion välillä -STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Nosta ruudun kulmaa. Vetäminen nostaa ensimmäistä valittua kulmaa ja tasoittaa valitun alueen kulman korkeudelle. Ctrl valitsee alueen vinottain. Shift vaihtaa muokkaustilan ja kustannearvion välillä -STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Tasoita maata ensimmäisen valitun kulman korkeudelle. Ctrl valitsee alueen vinottain. Shift vaihtaa muokkaustilan ja kustannearvion välillä -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Osta maata tulevaa käyttöä varten. Shift vaihtaa ostotilan ja kustannearvion välillä +STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Laske ruudun kulmaa. Vetäminen laskee ensimmäistä valittua kulmaa ja tasoittaa valitun alueen kulman korkeudelle. Ctrl valitsee alueen vinottain. Shift vaihtaa muokkaustilan ja kustannusarvion välillä +STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Nosta ruudun kulmaa. Vetäminen nostaa ensimmäistä valittua kulmaa ja tasoittaa valitun alueen kulman korkeudelle. Ctrl valitsee alueen vinottain. Shift vaihtaa muokkaustilan ja kustannusarvion välillä +STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Tasoita maata ensimmäisen valitun kulman korkeudelle. Ctrl valitsee alueen vinottain. Shift vaihtaa muokkaustilan ja kustannusarvion välillä +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Osta maata tulevaa käyttöä varten. Shift vaihtaa ostotilan ja kustannusarvion välillä # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Objektin valinta -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Valitse rakennettava objekti. Shift vaihtaa rakennustilan ja kustannearvion välillä +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Valitse rakennettava objekti. Shift vaihtaa rakennustilan ja kustannusarvion välillä STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Valitse rakennettavan objektin luokka STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Objektin esikatselu -STR_OBJECT_BUILD_SIZE :{BLACK}Koko: {GOLD}{NUM} x {NUM} ruutua +STR_OBJECT_BUILD_SIZE :{BLACK}Koko: {GOLD}{NUM} × {NUM} ruutua STR_OBJECT_CLASS_LTHS :Majakat STR_OBJECT_CLASS_TRNS :Lähettimet @@ -2493,7 +2498,7 @@ STR_OBJECT_CLASS_TRNS :Lähettimet STR_PLANT_TREE_CAPTION :{WHITE}Puita STR_PLANT_TREE_TOOLTIP :{BLACK}Valitse istutettava puutyyppi. Jos ruudussa on jo puu, tämä lisää uusia puita riippumatta valitun puun tyypistä STR_TREES_RANDOM_TYPE :{BLACK}Sattumanvaraisia puita -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Aseta sattumanvaraisia puita. Shift vaihtaa istutustilan ja kustannearvion välillä +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Aseta sattumanvaraisia puita. Shift vaihtaa istutustilan ja kustannusarvion välillä STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Satunnaisia puita. STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Istuta puita satunnaisesti maastoon @@ -2514,7 +2519,7 @@ STR_RESET_LANDSCAPE_CONFIRMATION_TEXT :{WHITE}Haluatko # Town generation window (SE) STR_FOUND_TOWN_CAPTION :{WHITE}Luo kaupunkeja STR_FOUND_TOWN_NEW_TOWN_BUTTON :{BLACK}Uusi kaupunki -STR_FOUND_TOWN_NEW_TOWN_TOOLTIP :{BLACK}Perusta uusi kaupunki. Shift+Klik näyttää vain kustannearvion +STR_FOUND_TOWN_NEW_TOWN_TOOLTIP :{BLACK}Perusta uusi kaupunki. Shift+Klik näyttää vain kustannusarvion STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Satunnainen kaupunki STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Perusta kaupunki satunnaiseen paikkaan STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Monta satunnaista kaupunkia @@ -2522,7 +2527,7 @@ STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Peitä k STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Kaupungin nimi: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Syötä kaupungin nimi -STR_FOUND_TOWN_NAME_EDITOR_HELP :{BLACK}Klikkaa syöttääksesi kaupungin nimen +STR_FOUND_TOWN_NAME_EDITOR_HELP :{BLACK}Syötä kaupungin nimi napsauttamalla STR_FOUND_TOWN_NAME_RANDOM_BUTTON :{BLACK}Satunnainen nimi STR_FOUND_TOWN_NAME_RANDOM_TOOLTIP :{BLACK}Arvo uusi satunnainen nimi @@ -2539,8 +2544,8 @@ STR_FOUND_TOWN_ROAD_LAYOUT :{YELLOW}Kaupung STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT :{BLACK}Valitse tiekaava tälle kaupungille STR_FOUND_TOWN_SELECT_LAYOUT_ORIGINAL :{BLACK}Alkuperäinen STR_FOUND_TOWN_SELECT_LAYOUT_BETTER_ROADS :{BLACK}Parempia teitä -STR_FOUND_TOWN_SELECT_LAYOUT_2X2_GRID :{BLACK}2x2-ruudukko -STR_FOUND_TOWN_SELECT_LAYOUT_3X3_GRID :{BLACK}3x3-ruudukko +STR_FOUND_TOWN_SELECT_LAYOUT_2X2_GRID :{BLACK}2×2-ruudukko +STR_FOUND_TOWN_SELECT_LAYOUT_3X3_GRID :{BLACK}3×3-ruudukko STR_FOUND_TOWN_SELECT_LAYOUT_RANDOM :{BLACK}Sattumanvarainen # Fund new industry window @@ -2559,8 +2564,8 @@ STR_INDUSTRY_CARGOES_CARGO_CAPTION :{WHITE}Teollisu STR_INDUSTRY_CARGOES_PRODUCERS :{WHITE}Tuottavia teollisuuksia STR_INDUSTRY_CARGOES_CUSTOMERS :{WHITE}Hyväksyviä teollisuuksia STR_INDUSTRY_CARGOES_HOUSES :{WHITE}Taloja -STR_INDUSTRY_CARGOES_INDUSTRY_TOOLTIP :{BLACK}Klikkaa teollisuutta nähdäksesi sen tuottajat ja kuluttajat -STR_INDUSTRY_CARGOES_CARGO_TOOLTIP :{BLACK}{STRING}{}Klikkaa rahtia nähdäksesi sen tuottajat ja kuluttajat +STR_INDUSTRY_CARGOES_INDUSTRY_TOOLTIP :{BLACK}Napsauta teollisuutta nähdäksesi sen tuottajat ja kuluttajat +STR_INDUSTRY_CARGOES_CARGO_TOOLTIP :{BLACK}{STRING}{}Napsauta rahtia nähdäksesi sen tuottajat ja kuluttajat STR_INDUSTRY_DISPLAY_CHAIN :{BLACK}Näytä ketju STR_INDUSTRY_DISPLAY_CHAIN_TOOLTIP :{BLACK}Näytä rahdin tuottajat ja hyväksyvät teollisuudet STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP :{BLACK}Yhdistä karttaan @@ -2693,6 +2698,36 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Alkuper STR_ABOUT_VERSION :{BLACK}OpenTTD-versio {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 The OpenTTD team +# Framerate display window +STR_FRAMERATE_CAPTION :{WHITE}Kuvataajuus +STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}×) +STR_FRAMERATE_RATE_GAMELOOP :{WHITE}Simulaationopeus: {STRING} +STR_FRAMERATE_RATE_BLITTER :{WHITE}Grafiikan kuvataajuus: {STRING} +STR_FRAMERATE_SPEED_FACTOR :{WHITE}Pelin nykyinen nopeuskerroin: {DECIMAL}× +STR_FRAMERATE_CURRENT :{WHITE}Nykyinen +STR_FRAMERATE_DATA_POINTS :{BLACK}Data perustuu {COMMA} mittaukseen +STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL}{WHITE} ms +STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL}{WHITE} ms +STR_FRAMERATE_MS_BAD :{RED}{DECIMAL}{WHITE} ms +STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL}{WHITE} kuvaa/s +STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL}{WHITE} kuvaa/s +STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL}{WHITE} kuvaa/s +STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms +STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s +############ Leave those lines in this order!! +STR_FRAMERATE_GL_ROADVEHS :{BLACK} Ajoneuvoaskeleet: +STR_FRAMERATE_GL_SHIPS :{BLACK} Laiva-askeleet: +STR_FRAMERATE_GL_LANDSCAPE :{BLACK} Maailma-askeleet: +STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK} Maailmanäkymät: +STR_FRAMERATE_VIDEO :{WHITE}Videolähtö: +############ End of leave-in-this-order +############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_GL_SHIPS :Laiva-askeleet +STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Ilma-alusaskeleet +STR_FRAMETIME_CAPTION_VIDEO :Videolähtö +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Tallenna peli STR_SAVELOAD_LOAD_CAPTION :{WHITE}Lataa peli @@ -2715,6 +2750,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Tietoja STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Tietoja ei ole saatavilla STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} +STR_SAVELOAD_FILTER_TITLE :{BLACK}Suodatinteksti: STR_SAVELOAD_OSKTITLE :{BLACK}Syötä nimi tallennustiedostolle @@ -2723,9 +2759,9 @@ STR_MAPGEN_WORLD_GENERATION_CAPTION :{WHITE}Maailman STR_MAPGEN_MAPSIZE :{BLACK}Kartan koko: STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Valitse kartan koko ruutuina. Saatavilla olevien ruutujen määrä on hieman alhaisempi STR_MAPGEN_BY :{BLACK}× -STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Kaupungit: +STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Kaupunkien määrä: STR_MAPGEN_DATE :{BLACK}Päivämäärä: -STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Teollisuus: +STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Teollisuuden määrä: STR_MAPGEN_MAX_HEIGHTLEVEL :{BLACK}Suurin sallittu kartan korkeus: STR_MAPGEN_MAX_HEIGHTLEVEL_UP :{BLACK}Kasvata suurinta sallittua vuorten korkeutta yhdellä STR_MAPGEN_MAX_HEIGHTLEVEL_DOWN :{BLACK}Vähennä suurinta sallittua vuorten korkeutta yhdellä @@ -2977,15 +3013,14 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Syötä STR_TOWN_DIRECTORY_CAPTION :{WHITE}Kaupungit STR_TOWN_DIRECTORY_NONE :{ORANGE}- Ei mitään - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Kaupunkien nimet - nimen klikkaaminen keskittää päänäkymän kaupunkiin. Ctrl+Klik avaa uuden näkymäikkunan kaupungin sijaintiin +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (suurkaup.){BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Kaupunkien nimet - keskitä päänäkymä kaupunkiin napsauttamalla nimeä. Ctrl+Klik avaa uuden näkymäikkunan kaupungin sijaintiin STR_TOWN_POPULATION :{BLACK}Maailman asukasluku: {COMMA} # Town view window STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (City) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Asukasluku: {ORANGE}{COMMA}{BLACK} Taloja: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Matkustajia viime kuussa: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Postia viime kuussa: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Kaupungin kasvuun tarvittava rahti: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} vaadittu STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} vaaditaan talvella @@ -3045,7 +3080,7 @@ STR_GOALS_SPECTATOR_NONE :{ORANGE}- Ei sa STR_GOALS_PROGRESS :{ORANGE}{STRING} STR_GOALS_PROGRESS_COMPLETE :{GREEN}{STRING} STR_GOALS_COMPANY_TITLE :{BLACK}Yhtiön tavoitteet: -STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Klikkaa tavoitetta keskittääksesi päänäkymän teollisuuteen/kaupunkiin/ruutuun. Ctrl+Klik avaa uuden näkymän teollisuuden/kaupungin/ruudun sijaintiin +STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Keskitä päänäkymä teollisuuteen/kaupunkiin/ruutuun napsauttamalla tavoitetta. Ctrl+Klik avaa uuden näkymän teollisuuden/kaupungin/ruudun sijaintiin # Goal question window STR_GOAL_QUESTION_CAPTION_QUESTION :Kysymys @@ -3084,7 +3119,7 @@ STR_SUBSIDIES_SUBSIDISED_FROM_TO :{ORANGE}{STRING STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Napsauta palvelua keskittääksesi päänäkymän teollisuuteen/kaupunkiin. Ctrl+Klik avaa uuden näkymäikkunan teollisuuden/kaupungin sijaintiin # Story book window -STR_STORY_BOOK_CAPTION :{WHITE}Yhtiön {COMPANY} historia +STR_STORY_BOOK_CAPTION :{WHITE}{COMPANY}: historia STR_STORY_BOOK_SPECTATOR_CAPTION :{WHITE}Yleinen yhtiöhistoria STR_STORY_BOOK_TITLE :{YELLOW}{STRING} STR_STORY_BOOK_GENERIC_PAGE_ITEM :Sivu {NUM} @@ -3162,7 +3197,7 @@ STR_STATION_VIEW_CENTER_TOOLTIP :{BLACK}Keskitä STR_STATION_VIEW_RENAME_TOOLTIP :{BLACK}Muuta aseman nimi. STR_STATION_VIEW_SCHEDULED_TRAINS_TOOLTIP :{BLACK}Näytä kaikki junat, joilla on tämä asema käskyissään. -STR_STATION_VIEW_SCHEDULED_ROAD_VEHICLES_TOOLTIP :{BLACK}Näytä kaikki autot, joilla on tämä asema käskyissään. +STR_STATION_VIEW_SCHEDULED_ROAD_VEHICLES_TOOLTIP :{BLACK}Näytä kaikki ajoneuvot, joilla on tämä asema käskyissään. STR_STATION_VIEW_SCHEDULED_AIRCRAFT_TOOLTIP :{BLACK}Näytä kaikki lentokoneet, joilla on tämä asema käskyissään. STR_STATION_VIEW_SCHEDULED_SHIPS_TOOLTIP :{BLACK}Näytä kaikki laivat, joilla on tämä asema käskyissään. @@ -3202,10 +3237,10 @@ STR_FINANCES_POSITIVE_INCOME :{BLACK}+{CURREN STR_FINANCES_TOTAL_CAPTION :{WHITE}Yhteensä: STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Tilin saldo STR_FINANCES_LOAN_TITLE :{WHITE}Laina -STR_FINANCES_MAX_LOAN :{WHITE}Laina enimmillään: {BLACK}{CURRENCY_LONG} +STR_FINANCES_MAX_LOAN :{WHITE}Laina enintään: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} -STR_FINANCES_BORROW_BUTTON :{BLACK}Ota lainaa {CURRENCY_LONG} -STR_FINANCES_BORROW_TOOLTIP :{BLACK}Ota lisää lainaa. Ctrl+Klik lisää lainaa niin paljon kuin mahdollista +STR_FINANCES_BORROW_BUTTON :{BLACK}Nosta lainaa {CURRENCY_LONG} +STR_FINANCES_BORROW_TOOLTIP :{BLACK}Ota lisää lainaa. Ctrl+Klik nostaa lainaa niin paljon kuin mahdollista STR_FINANCES_REPAY_BUTTON :{BLACK}Lyhennä lainaa {CURRENCY_LONG} STR_FINANCES_REPAY_TOOLTIP :{BLACK}Lyhennä lainaa. Ctrl+Klik lyhentää lainaa niin paljon kuin mahdollista STR_FINANCES_INFRASTRUCTURE_BUTTON :{BLACK}Infrastruktuuri @@ -3236,8 +3271,8 @@ STR_COMPANY_VIEW_BUILD_HQ_BUTTON :{BLACK}Rakenna STR_COMPANY_VIEW_BUILD_HQ_TOOLTIP :{BLACK}Rakenna yhtiön päämaja STR_COMPANY_VIEW_VIEW_HQ_BUTTON :{BLACK}Näytä päämaja STR_COMPANY_VIEW_VIEW_HQ_TOOLTIP :{BLACK}Näytä yhtiön päämaja -STR_COMPANY_VIEW_RELOCATE_HQ :{BLACK}Sijoita päämaja -STR_COMPANY_VIEW_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Rakenna yhtiön päärakennus muualle, kustannus 1{NBSP}% yhtiön arvosta. Shift+Klik näyttää kustannearvion sijoittamatta päärakennusta uudelleen +STR_COMPANY_VIEW_RELOCATE_HQ :{BLACK}Siirrä päämaja +STR_COMPANY_VIEW_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Rakenna yhtiön päärakennus muualle, kustannus 1{NBSP}% yhtiön arvosta. Shift+Klik näyttää kustannusarvion sijoittamatta päärakennusta uudelleen STR_COMPANY_VIEW_INFRASTRUCTURE_BUTTON :{BLACK}Yksityiskohdat STR_COMPANY_VIEW_INFRASTRUCTURE_TOOLTIP :{BLACK}Näytä tarkka infrastruktuurin määrä @@ -3252,7 +3287,7 @@ STR_COMPANY_VIEW_PRESIDENT_NAME_TOOLTIP :{BLACK}Muuta p STR_COMPANY_VIEW_BUY_SHARE_BUTTON :{BLACK}Osta 25{NBSP}%:n osuus yhtiöstä STR_COMPANY_VIEW_SELL_SHARE_BUTTON :{BLACK}Myy 25{NBSP}%:n osuus yhtiöstä -STR_COMPANY_VIEW_BUY_SHARE_TOOLTIP :{BLACK}Osta 25{NBSP}%:n osuus tästä yhtiöstä. Shift+Klik näyttää kustannearvion ostamatta osuuksia +STR_COMPANY_VIEW_BUY_SHARE_TOOLTIP :{BLACK}Osta 25{NBSP}%:n osuus tästä yhtiöstä. Shift+Klik näyttää kustannusarvion ostamatta osuuksia STR_COMPANY_VIEW_SELL_SHARE_TOOLTIP :{BLACK}Myy 25{NBSP}%:n osuus tästä yhtiöstä. Shift+Klik näyttää tuottoarvion myymättä osuuksia STR_COMPANY_VIEW_COMPANY_NAME_QUERY_CAPTION :Yhtiön nimi @@ -3261,7 +3296,7 @@ STR_COMPANY_VIEW_PRESIDENT_S_NAME_QUERY_CAPTION :Pääjohtajan n STR_BUY_COMPANY_MESSAGE :{WHITE}Etsimme kuljetusyhtiötä, joka ottaisi haltuunsa yhtiömme{}{}Haluatko ostaa yhtiön {COMPANY} hintaan {CURRENCY_LONG}? # Company infrastructure window -STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Yhtiön {COMPANY} infrastruktuuri +STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}{COMPANY}: Infrastruktuuri STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Rautatiepalat: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Opastimet STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Teiden palat: @@ -3280,7 +3315,7 @@ STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Ei mi STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% kuljetettu) STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% kuljetettu) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} -STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Teollisuusmuotojen nimet - klikkaa nimeä kohdistaaksesi päänäkymän teollisuuslaitokseen. Ctrl+Klik avaa uuden näkymäikkunan teollisuuslaitoksen sijaintiin +STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Teollisuusmuotojen nimet - kohdista päänäkymä teollisuuslaitokseen napsauttamalla nimeä. Ctrl+Klik avaa uuden näkymäikkunan teollisuuslaitoksen sijaintiin # Industry view STR_INDUSTRY_VIEW_CAPTION :{WHITE}{INDUSTRY} @@ -3306,13 +3341,13 @@ STR_INDUSTRY_VIEW_PRODUCES_CARGO_CARGO :{BLACK}Tuottaa: ############ range for produces ends STR_CONFIG_GAME_PRODUCTION :{WHITE}Muokkaa tuotantoa (8:n kerroin, 2040 asti) -STR_CONFIG_GAME_PRODUCTION_LEVEL :{WHITE}Muuta tuotantotasoa (prosentteina, 800% asti) +STR_CONFIG_GAME_PRODUCTION_LEVEL :{WHITE}Muuta tuotantotasoa (prosentteina, 800{NBSP}% asti) # Vehicle lists -STR_VEHICLE_LIST_TRAIN_CAPTION :{WHITE}{STRING} - {COMMA} junaa -STR_VEHICLE_LIST_ROAD_VEHICLE_CAPTION :{WHITE}{STRING} - {COMMA} ajoneuvoa -STR_VEHICLE_LIST_SHIP_CAPTION :{WHITE}{STRING} - {COMMA} laivaa -STR_VEHICLE_LIST_AIRCRAFT_CAPTION :{WHITE}{STRING} - {COMMA} lentokonetta +STR_VEHICLE_LIST_TRAIN_CAPTION :{WHITE}{STRING} - {COMMA} juna{P "" a} +STR_VEHICLE_LIST_ROAD_VEHICLE_CAPTION :{WHITE}{STRING} - {COMMA} ajoneuvo{P "" a} +STR_VEHICLE_LIST_SHIP_CAPTION :{WHITE}{STRING} - {COMMA} laiva{P "" a} +STR_VEHICLE_LIST_AIRCRAFT_CAPTION :{WHITE}{STRING} - {COMMA} lentokone{P "" tta} STR_VEHICLE_LIST_TRAIN_LIST_TOOLTIP :{BLACK}Junat - napsauta junaa saadaksesi tietoja. STR_VEHICLE_LIST_ROAD_VEHICLE_TOOLTIP :{BLACK}Ajoneuvot - napsauta ajoneuvoa saadaksesi tietoja. @@ -3337,23 +3372,23 @@ STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Lähetä variko STR_VEHICLE_LIST_SEND_SHIP_TO_DEPOT :Lähetä telakalle STR_VEHICLE_LIST_SEND_AIRCRAFT_TO_HANGAR :Lähetä varikolle -STR_VEHICLE_LIST_MASS_STOP_LIST_TOOLTIP :{BLACK}Pysäytä kaikki listalla olevat kulkuneuvot klikkaamalla -STR_VEHICLE_LIST_MASS_START_LIST_TOOLTIP :{BLACK}Käynnistä kaikki listalla olevat ajoneuvot klikkaamalla +STR_VEHICLE_LIST_MASS_STOP_LIST_TOOLTIP :{BLACK}Pysäytä kaikki listalla olevat kulkuneuvot napsauttamalla +STR_VEHICLE_LIST_MASS_START_LIST_TOOLTIP :{BLACK}Käynnistä kaikki listalla olevat ajoneuvot napsauttamalla STR_VEHICLE_LIST_SHARED_ORDERS_LIST_CAPTION :{WHITE}{COMMA} ajoneuvon jaetut käskyt # Group window STR_GROUP_ALL_TRAINS :Kaikki junat -STR_GROUP_ALL_ROAD_VEHICLES :Kaikki autot +STR_GROUP_ALL_ROAD_VEHICLES :Kaikki ajoneuvot STR_GROUP_ALL_SHIPS :Kaikki laivat STR_GROUP_ALL_AIRCRAFTS :Kaikki lentoalukset STR_GROUP_DEFAULT_TRAINS :Muut junat -STR_GROUP_DEFAULT_ROAD_VEHICLES :Muut autot +STR_GROUP_DEFAULT_ROAD_VEHICLES :Muut ajoneuvot STR_GROUP_DEFAULT_SHIPS :Muut laivat STR_GROUP_DEFAULT_AIRCRAFTS :Muut lentokoneet -STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Ryhmät - klikkaa ryhmää nähdäksesi kaikki kulkuneuvot tässä ryhmässä. Järjestä ryhmiä vetämällä ja pudottamalla. +STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Ryhmät - napsauta ryhmää nähdäksesi kaikki kulkuneuvot tässä ryhmässä. Järjestä ryhmiä vetämällä ja pudottamalla. STR_GROUP_CREATE_TOOLTIP :{BLACK}Luo ryhmä STR_GROUP_DELETE_TOOLTIP :{BLACK}Poista valittu ryhmä STR_GROUP_RENAME_TOOLTIP :{BLACK}Nimeä valittu ryhmä @@ -3369,6 +3404,7 @@ STR_GROUP_RENAME_CAPTION :{BLACK}Nimeä r STR_GROUP_PROFIT_THIS_YEAR :Tuotto tänä vuonna: STR_GROUP_PROFIT_LAST_YEAR :Tuotto viime vuonna: +STR_GROUP_OCCUPANCY :Nykyinen käyttö: STR_GROUP_OCCUPANCY_VALUE :{NUM} % # Build vehicle window @@ -3414,10 +3450,10 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Osta ajo STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Osta laiva STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Osta lentokone -STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Osta valittu yksikkö. Shift+Klik näyttää kustannearvion ostamatta kopiota -STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Osta valittu ajoneuvo.. Shift+Klik näyttää kustannearvion ostamatta kopiota -STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Osta valittu laiva. Shift+Klik näyttää kustannearvion ostamatta kopiota -STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Osta korostettu lentokone. Shift+Klik näyttää kustannearvion ostamatta kopiota +STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Osta valittu yksikkö. Shift+Klik näyttää kustannusarvion ostamatta +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Osta valittu ajoneuvo. Shift+Klik näyttää kustannusarvion ostamatta +STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Osta valittu laiva. Shift+Klik näyttää kustannusarvion ostamatta +STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Osta korostettu lentokone. Shift+Klik näyttää kustannusarvion ostamatta STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Nimeä STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Nimeä @@ -3460,10 +3496,10 @@ STR_DEPOT_VEHICLE_TOOLTIP :{BLACK}{ENGINE} STR_DEPOT_VEHICLE_TOOLTIP_CHAIN :{BLACK}{NUM} kulkuneuvo{P "" a}{STRING} STR_DEPOT_VEHICLE_TOOLTIP_CARGO :{}{CARGO_LONG} ({CARGO_SHORT}) -STR_DEPOT_TRAIN_LIST_TOOLTIP :{BLACK}Junat - vedä kulkuneuvoa vasemmalla hiiren painikkella lisätäksesi/poistaaksesi junasta, oikealla näppäimellä lisätietoja, Pidä pohjassa Ctrl-näppäintä toteuttaaksesi molemmat toiminnot seuraavaan ketjuun -STR_DEPOT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Ajoneuvot - napsauta ajoneuvoa oikealla hiiren näppäimellä saadaksesi tietoja. -STR_DEPOT_SHIP_LIST_TOOLTIP :{BLACK}Laivat - napsauta laivaa oikealla hiiren näppäimellä saadaksesi tietoja. -STR_DEPOT_AIRCRAFT_LIST_TOOLTIP :{BLACK}Lentokoneet - napsauta lentokonetta oikealla hiiren näppäimellä saadaksesi tietoja. +STR_DEPOT_TRAIN_LIST_TOOLTIP :{BLACK}Junat - vedä kulkuneuvoa vasemmalla hiiren painikkella lisätäksesi/poistaaksesi junasta, oikealla painikkeella lisätietoja. Pidä pohjassa Ctrl-näppäintä toteuttaaksesi molemmat toiminnot seuraavaan ketjuun +STR_DEPOT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Ajoneuvot - napsauta ajoneuvoa oikealla hiiren painikkeella saadaksesi tietoja. +STR_DEPOT_SHIP_LIST_TOOLTIP :{BLACK}Laivat - napsauta laivaa oikealla hiiren painikkeella saadaksesi tietoja. +STR_DEPOT_AIRCRAFT_LIST_TOOLTIP :{BLACK}Lentokoneet - napsauta lentokonetta oikealla hiiren painikkeella saadaksesi tietoja. STR_DEPOT_TRAIN_SELL_TOOLTIP :{BLACK}Vedä yksikkö tähän myydäksesi sen. STR_DEPOT_ROAD_VEHICLE_SELL_TOOLTIP :{BLACK}Vedä ajoneuvo tähän myydäksesi sen. @@ -3472,12 +3508,12 @@ STR_DEPOT_AIRCRAFT_SELL_TOOLTIP :{BLACK}Vedä le STR_DEPOT_DRAG_WHOLE_TRAIN_TO_SELL_TOOLTIP :{BLACK}Vedä junan veturi tähän myydäksesi koko junan. -STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TOOLTIP :{BLACK}Myy kaikki varikolla olevat junat +STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TOOLTIP :{BLACK}Myy kaikki veturitallilla olevat junat STR_DEPOT_SELL_ALL_BUTTON_ROAD_VEHICLE_TOOLTIP :{BLACK}Myy kaikki varikolla olevat ajoneuvot STR_DEPOT_SELL_ALL_BUTTON_SHIP_TOOLTIP :{BLACK}Myy kaikki telakalla olevat laivat STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TOOLTIP :{BLACK}Myy kaikki hallissa olevat ilma-alukset -STR_DEPOT_AUTOREPLACE_TRAIN_TOOLTIP :{BLACK}Korvaa kaikki varikolla olevat junat automaattisesti +STR_DEPOT_AUTOREPLACE_TRAIN_TOOLTIP :{BLACK}Korvaa kaikki veturitallilla olevat junat automaattisesti STR_DEPOT_AUTOREPLACE_ROAD_VEHICLE_TOOLTIP :{BLACK}Korvaa kaikki varikolla olevat ajoneuvot automaattisesti STR_DEPOT_AUTOREPLACE_SHIP_TOOLTIP :{BLACK}Korvaa kaikki telakalla olevat laivat automaattisesti STR_DEPOT_AUTOREPLACE_AIRCRAFT_TOOLTIP :{BLACK}Korvaa kaikki hallissa olevat lento-alukset automaattisesti @@ -3497,10 +3533,10 @@ STR_DEPOT_CLONE_ROAD_VEHICLE :{BLACK}Kloonaa STR_DEPOT_CLONE_SHIP :{BLACK}Kloonaa laiva STR_DEPOT_CLONE_AIRCRAFT :{BLACK}Kloonaa lentokone -STR_DEPOT_CLONE_TRAIN_DEPOT_INFO :{BLACK}Tämä ostaa kopion junasta ja kaikista sen vaunuista. Paina tätä nappia ja sen jälkeen junaa varikon sisä- tai ulkopuolella. Ctrl+Klik jakaa komennot. Shift+Klik näyttää kustannearvion ostamatta kopiota -STR_DEPOT_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Tämä ostaa kopion ajoneuvosta. Paina tätä nappia ja sen jälkeen ajoneuvoa varikon sisä- tai ulkopuolella. Ctrl+Klik jakaa komennot. Shift+Klik näyttää kustannearvion ostamatta kopiota -STR_DEPOT_CLONE_SHIP_DEPOT_INFO :{BLACK}Tämä ostaa kopion laivasta. Paina tätä nappia ja sen jälkeen laivaa telakan sisä- tai ulkopuolella. Ctrl+Klik jakaa komennot. Shift+Klik näyttää kustannearvion ostamatta kopiota -STR_DEPOT_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Tämä ostaa kopion lentokoneesta. Paina tätä nappia ja sen jälkeen lentokonetta lentokonehallin sisä- tai ulkopuolella. Ctrl+Klik jakaa komennot. Shift+Klik näyttää kustannearvion ostamatta kopiota +STR_DEPOT_CLONE_TRAIN_DEPOT_INFO :{BLACK}Tämä ostaa kopion junasta ja kaikista sen vaunuista. Napsauta tätä painiketta ja sen jälkeen junaa varikon sisä- tai ulkopuolella. Ctrl+Klik jakaa komennot. Shift+Klik näyttää kustannusarvion ostamatta kopiota +STR_DEPOT_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Tämä ostaa kopion ajoneuvosta. Napsauta tätä painiketta ja sen jälkeen ajoneuvoa varikon sisä- tai ulkopuolella. Ctrl+Klik jakaa komennot. Shift+Klik näyttää kustannusarvion ostamatta kopiota +STR_DEPOT_CLONE_SHIP_DEPOT_INFO :{BLACK}Tämä ostaa kopion laivasta. Napsauta tätä painiketta ja sen jälkeen laivaa telakan sisä- tai ulkopuolella. Ctrl+Klik jakaa komennot. Shift+Klik näyttää kustannusarvion ostamatta kopiota +STR_DEPOT_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Tämä ostaa kopion lentokoneesta. Napsauta tätä painiketta ja sen jälkeen lentokonetta lentokonehallin sisä- tai ulkopuolella. Ctrl+Klik jakaa komennot. Shift+Klik näyttää kustannusarvion ostamatta kopiota STR_DEPOT_TRAIN_LOCATION_TOOLTIP :{BLACK}Keskitä näkymä veturitallin sijaintiin. Ctrl+Klik avaa uuden näkymäikkunan veturitallin sijaintiin STR_DEPOT_ROAD_VEHICLE_LOCATION_TOOLTIP :{BLACK}Keskitä päänäkymä varikon sijaintiin. Ctrl+Klik avaa uuden näkymäikkunan varikon sijaintiin @@ -3512,15 +3548,15 @@ STR_DEPOT_VEHICLE_ORDER_LIST_ROAD_VEHICLE_TOOLTIP :{BLACK}Näytä STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TOOLTIP :{BLACK}Näytä tässä terminaalissa olevien laivojen käskyt STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TOOLTIP :{BLACK}Näytä tämän lentokentän ilma-alusten käskyistä hallista riippumatta -STR_DEPOT_MASS_STOP_DEPOT_TRAIN_TOOLTIP :{BLACK}Pysäytä kaikki varikolla olevat junat klikkaamalla -STR_DEPOT_MASS_STOP_DEPOT_ROAD_VEHICLE_TOOLTIP :{BLACK}Pysäytä kaikki varikolla olevat ajoneuvot klikkaamalla -STR_DEPOT_MASS_STOP_DEPOT_SHIP_TOOLTIP :{BLACK}Pysäytä kaikki telakalla olevat laivat klikkaamalla -STR_DEPOT_MASS_STOP_HANGAR_TOOLTIP :{BLACK}Pysäytä kaikki hallissa olevat ilma-alukset klikkaamalla +STR_DEPOT_MASS_STOP_DEPOT_TRAIN_TOOLTIP :{BLACK}Pysäytä kaikki veturitallilla olevat junat napsauttamalla +STR_DEPOT_MASS_STOP_DEPOT_ROAD_VEHICLE_TOOLTIP :{BLACK}Pysäytä kaikki varikolla olevat ajoneuvot napsauttamalla +STR_DEPOT_MASS_STOP_DEPOT_SHIP_TOOLTIP :{BLACK}Pysäytä kaikki telakalla olevat laivat napsauttamalla +STR_DEPOT_MASS_STOP_HANGAR_TOOLTIP :{BLACK}Pysäytä kaikki hallissa olevat ilma-alukset napsauttamalla -STR_DEPOT_MASS_START_DEPOT_TRAIN_TOOLTIP :{BLACK}Käynnistä kaikki varikolla olevat junat klikkaamalla -STR_DEPOT_MASS_START_DEPOT_ROAD_VEHICLE_TOOLTIP :{BLACK}Käynnistä kaikki varikolla olevat ajoneuvot klikkaamalla -STR_DEPOT_MASS_START_DEPOT_SHIP_TOOLTIP :{BLACK}Käynnistä kaikki telakalla olevat laivat klikkaamalla -STR_DEPOT_MASS_START_HANGAR_TOOLTIP :{BLACK}Käynnistä kaikki hallissa olevat ilma-alukset klikkaamalla +STR_DEPOT_MASS_START_DEPOT_TRAIN_TOOLTIP :{BLACK}Käynnistä kaikki veturitallilla olevat junat napsauttamalla +STR_DEPOT_MASS_START_DEPOT_ROAD_VEHICLE_TOOLTIP :{BLACK}Käynnistä kaikki varikolla olevat ajoneuvot napsauttamalla +STR_DEPOT_MASS_START_DEPOT_SHIP_TOOLTIP :{BLACK}Käynnistä kaikki telakalla olevat laivat napsauttamalla +STR_DEPOT_MASS_START_HANGAR_TOOLTIP :{BLACK}Käynnistä kaikki hallissa olevat ilma-alukset napsauttamalla STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Olet myymässä kaikki varikon ajoneuvot. Oletko varma? @@ -3595,10 +3631,10 @@ STR_VEHICLE_VIEW_ROAD_VEHICLE_SEND_TO_DEPOT_TOOLTIP :{BLACK}Lähetä STR_VEHICLE_VIEW_SHIP_SEND_TO_DEPOT_TOOLTIP :{BLACK}Lähetä laiva telakalle. Ctrl+Klik suorittaa vain huollon STR_VEHICLE_VIEW_AIRCRAFT_SEND_TO_DEPOT_TOOLTIP :{BLACK}Lähetä lentokone lentokonehalliin. Ctrl+Klik suorittaa vain huollon -STR_VEHICLE_VIEW_CLONE_TRAIN_INFO :{BLACK}Tämä ostaa kopion junasta ja kaikista sen vaunuista. Ctrl+Klik jakaa komennot. Shift+Klik näyttää kustannearvion ostamatta kopiota -STR_VEHICLE_VIEW_CLONE_ROAD_VEHICLE_INFO :{BLACK}Tämä ostaa kopion ajoneuvosta. Ctrl+Klik jakaa komennot. Shift+Klik näyttää kustannearvion ostamatta kopiota -STR_VEHICLE_VIEW_CLONE_SHIP_INFO :{BLACK}Tämä ostaa kopion laivasta. Ctrl+Klik jakaa komennot. Shift+Klik näyttää kustannearvion ostamatta kopiota -STR_VEHICLE_VIEW_CLONE_AIRCRAFT_INFO :{BLACK}Tämä ostaa kopion lentokoneesta. Ctrl+Klik jakaa komennot. Shift+Klik näyttää kustannearvion ostamatta kopiota +STR_VEHICLE_VIEW_CLONE_TRAIN_INFO :{BLACK}Tämä ostaa kopion junasta vaunuineen. Ctrl+Klik jakaa komennot. Shift+Klik näyttää kustannusarvion ostamatta kopiota +STR_VEHICLE_VIEW_CLONE_ROAD_VEHICLE_INFO :{BLACK}Tämä ostaa kopion ajoneuvosta. Ctrl+Klik jakaa komennot. Shift+Klik näyttää kustannusarvion ostamatta kopiota +STR_VEHICLE_VIEW_CLONE_SHIP_INFO :{BLACK}Tämä ostaa kopion laivasta. Ctrl+Klik jakaa komennot. Shift+Klik näyttää kustannusarvion ostamatta kopiota +STR_VEHICLE_VIEW_CLONE_AIRCRAFT_INFO :{BLACK}Tämä ostaa kopion lentokoneesta. Ctrl+Klik jakaa komennot. Shift+Klik näyttää kustannusarvion ostamatta kopiota STR_VEHICLE_VIEW_TRAIN_IGNORE_SIGNAL_TOOLTIP :{BLACK}Anna junalle lupa ohittaa punainen opastin. @@ -3724,7 +3760,7 @@ STR_REFIT_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Uusi kap STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT :{BLACK}Uusi kapasiteetti: {GOLD}{CARGO_LONG}{}{BLACK}Tulot sovittamisesta: {GREEN}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}Uusi kapasiteetti: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Sovituksen kustannus: {RED}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT :{BLACK}Uusi kapasiteetti: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Tulot sovittamisesta: {GREEN}{CURRENCY_LONG} -STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}Valitse sovitettavat kulkuneuvot. Hiirellä vetäminen sallii useamman kulkuneuvon valinnan. Tyhjän alueen klikkaus valitsee koko kulkuneuvon. Ctrl+Klik valitsee kulkuneuvon ja sitä seuraavan ketjun +STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}Valitse sovitettavat kulkuneuvot. Hiirellä vetäminen sallii useamman kulkuneuvon valinnan. Tyhjän alueen napsautus valitsee koko kulkuneuvon. Ctrl+Klik valitsee kulkuneuvon ja sitä seuraavan ketjun STR_REFIT_TRAIN_LIST_TOOLTIP :{BLACK}Valitse junan rahtityyppi STR_REFIT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Valitse ajoneuvolla ajettava rahti @@ -3754,7 +3790,7 @@ STR_ORDERS_END_OF_ORDERS :- - Käskyjen l STR_ORDERS_END_OF_SHARED_ORDERS :- - Jaettujen käskyjen loppu - - # Order bottom buttons -STR_ORDER_NON_STOP :{BLACK}Nonstop +STR_ORDER_NON_STOP :{BLACK}Välipysähdyksetön STR_ORDER_GO_TO :Mene STR_ORDER_GO_NON_STOP_TO :Mene pysähtymättä STR_ORDER_GO_VIA :Mene kautta @@ -3826,7 +3862,7 @@ STR_ORDER_GO_TO_NEAREST_DEPOT :Mene lähimmäl STR_ORDER_GO_TO_NEAREST_HANGAR :Mene lähimmälle varikolle STR_ORDER_CONDITIONAL :Ehdollinen hyppykäsky STR_ORDER_SHARE :Jaa käskyt -STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Lisää uusi käsky ennen valittua, tai lisää listan viimeiseksi. Ctrl tekee asemakäskyistä 'lastaa täyteen kaikki rahti', reittipistekäskyistä 'non-stop' ja veturitallikäskyistä 'huolto'. 'Jaa käskyt' jakaa käskyt valitun kulkuneuvon kanssa. Kulkuneuvon klikkaaminen kopioi käskyt siitä kulkuneuvosta. Varikkokäsky poistaa käytöstä automaattisen huollon +STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Lisää uusi käsky ennen valittua, tai lisää listan viimeiseksi. Ctrl tekee asemakäskyistä 'lastaa täyteen kaikki rahti', reittipistekäskyistä 'non-stop' ja veturitallikäskyistä 'huolto'. 'Jaa käskyt' jakaa käskyt valitun kulkuneuvon kanssa. Kulkuneuvon napsauttaminen kopioi käskyt kyseisestä kulkuneuvosta. Varikkokäsky poistaa käytöstä automaattisen huollon STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP :{BLACK}Näytä kaikki ajoneuvot, jotka jakavat nämä käskyt @@ -3835,11 +3871,11 @@ STR_ORDER_GO_TO_WAYPOINT :Kierrä reittip STR_ORDER_GO_NON_STOP_TO_WAYPOINT :Mene pysäht. pisteen {WAYPOINT} kautta STR_ORDER_SERVICE_AT :Huolto -STR_ORDER_SERVICE_NON_STOP_AT :Nonstop-huolto +STR_ORDER_SERVICE_NON_STOP_AT :Huolto pysäytyksettä STR_ORDER_NEAREST_DEPOT :lähin STR_ORDER_NEAREST_HANGAR :lähin varikko -STR_ORDER_TRAIN_DEPOT :Junavarikko +STR_ORDER_TRAIN_DEPOT :Veturitalli STR_ORDER_ROAD_VEHICLE_DEPOT :Varikko STR_ORDER_SHIP_DEPOT :Telakka STR_ORDER_GO_TO_NEAREST_DEPOT_FORMAT :{STRING} {STRING} {STRING} @@ -3901,7 +3937,7 @@ STR_TIMETABLE_TITLE :{WHITE}{VEHICLE STR_TIMETABLE_ORDER_VIEW :{BLACK}Käskyt STR_TIMETABLE_ORDER_VIEW_TOOLTIP :{BLACK}Vaihda käskynäkymään -STR_TIMETABLE_TOOLTIP :{BLACK}Aikataulu - klikkaa käskyä valitaksesi sen +STR_TIMETABLE_TOOLTIP :{BLACK}Aikataulu - valitse käsky sitä napsauttamalla STR_TIMETABLE_NO_TRAVEL :Ei kulkua STR_TIMETABLE_NOT_TIMETABLEABLE :Kulje (automaattinen; aikataulu seuraavan manuaalisen käskyn mukaisesti) @@ -3916,7 +3952,7 @@ STR_TIMETABLE_AND_TRAVEL_FOR_ESTIMATED :(matkusta {STRI STR_TIMETABLE_STAY_FOR :ja odota {STRING} STR_TIMETABLE_AND_TRAVEL_FOR :ja kulje {STRING} STR_TIMETABLE_DAYS :{COMMA}{NBSP}päivä{P "" ä} -STR_TIMETABLE_TICKS :{COMMA}{NBSP}tick{P "" iä} +STR_TIMETABLE_TICKS :{COMMA}{NBSP}askel{P "" ta} STR_TIMETABLE_TOTAL_TIME :{BLACK}Aikataulun kesto on {STRING} STR_TIMETABLE_TOTAL_TIME_INCOMPLETE :{BLACK}Aikataulun kesto on vähintään {STRING} @@ -4223,7 +4259,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Liian mo STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Rautatieasema on jakautunut liian moneen osaan STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Liian monta linja-autopysäkkiä. STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Liian monta lastauslaituria. -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Liian lähellä toista asemaa tai lastausaluetta. STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Liian lähellä toista satamaa. STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Liian lähellä toista lentokenttää. STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Asemaa ei voi nimetä uudelleen. @@ -4231,6 +4266,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... kaup STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... tie on väärin päin STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... läpiajettavissa pysäkeissä ei voi olla mutkia STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... läpiajettavissa pysäkeissä ei voi olla risteyksiä +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... tie on yksisuuntainen tai suljettu # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Aseman osaa ei voi poistaa... @@ -4259,7 +4295,7 @@ STR_ERROR_CAN_T_POSITION_BUOY_HERE :{WHITE}Poijua e STR_ERROR_CAN_T_CHANGE_WAYPOINT_NAME :{WHITE}Reittipisteen nimeä ei voi muuttaa... STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT :{WHITE}Junien reittipistettä ei voi poistaa... -STR_ERROR_MUST_REMOVE_RAILWAYPOINT_FIRST :{WHITE}Junaradan reittipiste täytyy poistaa ensin +STR_ERROR_MUST_REMOVE_RAILWAYPOINT_FIRST :{WHITE}Rautatien reittipiste täytyy poistaa ensin STR_ERROR_BUOY_IN_THE_WAY :{WHITE}... poiju on tiellä STR_ERROR_BUOY_IS_IN_USE :{WHITE}... poiju on toisen yhtiön käytössä! @@ -4272,7 +4308,7 @@ STR_ERROR_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Telakkaa STR_ERROR_CAN_T_RENAME_DEPOT :{WHITE}Varikon nimeä ei voi vaihtaa... STR_ERROR_TRAIN_MUST_BE_STOPPED_INSIDE_DEPOT :{WHITE}... täytyy olla pysähdyksissä veturitallin sisällä -STR_ERROR_ROAD_VEHICLE_MUST_BE_STOPPED_INSIDE_DEPOT :{WHITE}... täytyy olla pysähtyneenä varikolla +STR_ERROR_ROAD_VEHICLE_MUST_BE_STOPPED_INSIDE_DEPOT :{WHITE}... täytyy olla pysäytettynä varikolla STR_ERROR_SHIP_MUST_BE_STOPPED_INSIDE_DEPOT :{WHITE}... täytyy olla pysähdyksissä telakalla STR_ERROR_AIRCRAFT_MUST_BE_STOPPED_INSIDE_HANGAR :{WHITE}... täytyy olla pysähdyksissä lentokonehallissa @@ -4482,6 +4518,7 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Alkuperäiset T STR_BASESOUNDS_WIN_DESCRIPTION :Alkuperäiset Transport Tycoon Deluxen Windows-version äänet. STR_BASESOUNDS_NONE_DESCRIPTION :Äänipaketti, jossa ei ole ääniä. STR_BASEMUSIC_WIN_DESCRIPTION :Alkuperäinen Transport Tycoon Deluxen Windows-version musiikki. +STR_BASEMUSIC_DOS_DESCRIPTION :Alkuperäinen Transport Tycoon Deluxen DOS-version musiikki. STR_BASEMUSIC_NONE_DESCRIPTION :Musiikkipaketti, jossa ei ole musiikkia. ##id 0x2000 @@ -4855,7 +4892,7 @@ STR_VEHICLE_NAME_AIRCRAFT_PLODDYPHUT_500 :Ploddyphut 500 STR_VEHICLE_NAME_AIRCRAFT_FLASHBANG_X1 :Flashbang X1 STR_VEHICLE_NAME_AIRCRAFT_JUGGERPLANE_M1 :Juggerplane M1 STR_VEHICLE_NAME_AIRCRAFT_FLASHBANG_WIZZER :Flashbang Wizzer -STR_VEHICLE_NAME_AIRCRAFT_TRICARIO_HELICOPTER :Tricario -helikopteri +STR_VEHICLE_NAME_AIRCRAFT_TRICARIO_HELICOPTER :Tricario-helikopteri STR_VEHICLE_NAME_AIRCRAFT_GURU_X2_HELICOPTER :Guru X2 -helikopteri STR_VEHICLE_NAME_AIRCRAFT_POWERNAUT_HELICOPTER :Powernaut-helikopteri diff --git a/src/lang/french.txt b/src/lang/french.txt index 2c57358046..b7729e5067 100644 --- a/src/lang/french.txt +++ b/src/lang/french.txt @@ -476,6 +476,7 @@ STR_ABOUT_MENU_SCREENSHOT :Copie d'écran STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Copie d'écran au zoom maximum STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Copie d'écran au zoom par défaut STR_ABOUT_MENU_GIANT_SCREENSHOT :Copie d'écran de la carte entière +STR_ABOUT_MENU_SHOW_FRAMERATE :Afficher la fréquence d'images STR_ABOUT_MENU_ABOUT_OPENTTD :À propos d'OpenTTD STR_ABOUT_MENU_SPRITE_ALIGNER :Alignement de sprite STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Afficher/Cacher les boites de dimensions maximum @@ -651,6 +652,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}Aucune musique disponible STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Piste STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Titre @@ -664,21 +666,21 @@ STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Faire gl STR_MUSIC_TOOLTIP_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Choisir le programme «{NBSP}Tout{NBSP}» STR_MUSIC_TOOLTIP_SELECT_OLD_STYLE_MUSIC :{BLACK}Choisir le programme musical «{NBSP}Ancien style{NBSP}» STR_MUSIC_TOOLTIP_SELECT_NEW_STYLE_MUSIC :{BLACK}Choisir le programme musical «{NBSP}Nouveau style{NBSP}» -STR_MUSIC_TOOLTIP_SELECT_EZY_STREET_STYLE :{BLACK}Sélectionner le programme musical «{NBSP}Ezy Street{NBSP}» +STR_MUSIC_TOOLTIP_SELECT_EZY_STREET_STYLE :{BLACK}Choisir le programme musical «{NBSP}Ezy Street{NBSP}» STR_MUSIC_TOOLTIP_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Choisir le programme personnalisé «{NBSP}Personnalisé 1{NBSP}» STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Choisir le programme personnalisé «{NBSP}Personnalisé 2{NBSP}» STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Activer/Désactiver le mode aléatoire STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Afficher la fenêtre de sélection de pistes -STR_ERROR_NO_SONGS :{WHITE}Un ensemble de musique vide a été choisi. Aucune musique ne sera jouée. - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Sélection du programme musical -STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Programme musical - «{NBSP}{STRING}{NBSP}» +STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} «{NBSP}{STRING}{NBSP}» STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Index des pistes -STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programme - '{STRING}' +STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programme - «{NBSP}{STRING}{NBSP}» STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Effacer +STR_PLAYLIST_CHANGE_SET :{BLACK}Changer d'ensemble STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Effacer le programme actuel (Personnalisé 1 ou Personnalisé 2 seulement) +STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Choisir un autre ensemble de musique STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Cliquer sur une piste pour l'ajouter au programme courant (Personnalisé 1 ou Personnalisé 2 seulement) STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Cliquer sur une piste pour la retirer du programme courant (Personnalisé 1 ou Personnalisé 2 seulement) @@ -881,10 +883,10 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC # Extra view window STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Vue {COMMA} -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Copier vers la vue -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Copier l'emplacement de la vue principale vers cette vue-ci -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Coller depuis la vue -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Coller l'emplacement de cette vue-ci vers la vue principale +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Modifier cette vue +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Copier l'emplacement de la vue principale vers cette vue +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Modifier la vue principale +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Copier l'emplacement de cette vue vers la vue principale # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Options @@ -926,6 +928,7 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :Rand sud-africa STR_GAME_OPTIONS_CURRENCY_CUSTOM :Personnalisée... STR_GAME_OPTIONS_CURRENCY_GEL :Lari Géorgien (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :Rial Iranien (IRR) +STR_GAME_OPTIONS_CURRENCY_RUB :Nouveau rouble russe (RUB) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Véhicules routiers @@ -1338,8 +1341,12 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Couleur du terr STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Vert STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Vert foncé STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Violet -STR_CONFIG_SETTING_REVERSE_SCROLLING :Inverser la direction lors du défilement avec la souris{NBSP}: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Comportement lors du défilement de la carte avec le bouton droit de la souris. Quand il est désactivé, la souris déplace la caméra. Quand il est activé, la souris déplace la carte +STR_CONFIG_SETTING_SCROLLMODE :Défilement de la vue{NBSP}: {STRING} +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Comportement lors du défilement de la carte +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Défilement de la vue par clic droit, position de la souris verrouillée +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Défilement de la carte par clic droit, position de la souris verrouillée +STR_CONFIG_SETTING_SCROLLMODE_RMB :Défilement de la carte par clic droit +STR_CONFIG_SETTING_SCROLLMODE_LMB :Défilement de la carte par clic gauche STR_CONFIG_SETTING_SMOOTH_SCROLLING :Défilement régulier de la vue{NBSP}: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Contrôle comment la vue principale défile jusqu'à une position spécifique lors d'un clic sur la mini-carte ou pour atteindre un objet précis sur la carte. Si activé, la vue défile doucement, si désactivé elle saute directement à la cible STR_CONFIG_SETTING_MEASURE_TOOLTIP :Montrer une infobulle de mesure lors de l'utilisation de divers outils de construction{NBSP}: {STRING} @@ -1371,8 +1378,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Commande-clic STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl-clic STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Désactivé -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Défilement par clic gauche{NBSP}: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Active le défilement de la carte en la glissant avec le bouton gauche de la souris. C'est surtout utile pour les écrans tactiles STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Fermer une fenêtre en cliquant droit{NBSP}: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Fermer une fenêtre en cliquant droit à l’intérieur de celle-ci. Désactive l'infobulle sur clic droit{NBSP}! @@ -2286,6 +2291,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Légende STR_LINKGRAPH_LEGEND_ALL :{BLACK}Toute STR_LINKGRAPH_LEGEND_NONE :{BLACK}Aucune STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Choisir les compagnies à afficher +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}inutilisé @@ -2694,6 +2700,56 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Copyrigh STR_ABOUT_VERSION :{BLACK}OpenTTD version {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 L'équipe OpenTTD +# Framerate display window +STR_FRAMERATE_CAPTION :{WHITE}Fréquence d'images +STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) +STR_FRAMERATE_RATE_GAMELOOP :{WHITE}Fréquence de simulation{NBSP}: {STRING} +STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Nombre de ticks simulés par seconde. +STR_FRAMERATE_RATE_BLITTER :{WHITE}Fréquence des graphismes{NBSP}: {STRING} +STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Nombre d'images rendues par seconde. +STR_FRAMERATE_SPEED_FACTOR :{WHITE}Facteur de vitesse actuel{NBSP}: {DECIMAL}x +STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}À quelle vitesse le jeu tourne actuellement, comparé à la vitesse attendue pour la simulation normale. +STR_FRAMERATE_CURRENT :{WHITE}Actuel +STR_FRAMERATE_AVERAGE :{WHITE}Moyen +STR_FRAMERATE_DATA_POINTS :{WHITE}Données basées sur {COMMA} mesures +STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL}{WHITE} ms +STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL}{WHITE} ms +STR_FRAMERATE_MS_BAD :{RED}{DECIMAL}{WHITE} ms +STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL}{WHITE} images/s +STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL}{WHITE} images/s +STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL}{WHITE} images/s +STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms +STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s +############ Leave those lines in this order!! +STR_FRAMERATE_GAMELOOP :{WHITE}Total de la boucle de jeu{NBSP}: +STR_FRAMERATE_GL_ECONOMY :{WHITE} Traitement des marchandises{NBSP}: +STR_FRAMERATE_GL_TRAINS :{WHITE} Ticks des trains{NBSP}: +STR_FRAMERATE_GL_ROADVEHS :{WHITE} Ticks des véhicules routiers{NBSP}: +STR_FRAMERATE_GL_SHIPS :{WHITE} Ticks des navires{NBSP}: +STR_FRAMERATE_GL_AIRCRAFT :{WHITE} Ticks des aéroplanes{NBSP}: +STR_FRAMERATE_GL_LANDSCAPE :{WHITE} Ticks du monde{NBSP}: +STR_FRAMERATE_GL_LINKGRAPH :{WHITE} Délai du flux des marchandises{NBSP}: +STR_FRAMERATE_DRAWING :{WHITE}Rendu des graphismes{NBSP}: +STR_FRAMERATE_DRAWING_VIEWPORTS :{WHITE} Vues{NBSP}: +STR_FRAMERATE_VIDEO :{WHITE}Sortie vidéo{NBSP}: +STR_FRAMERATE_SOUND :{WHITE}Mixage sonore{NBSP}: +############ End of leave-in-this-order +############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_GAMELOOP :Boucle de jeu +STR_FRAMETIME_CAPTION_GL_ECONOMY :Traitement des marchandises +STR_FRAMETIME_CAPTION_GL_TRAINS :Ticks des trains +STR_FRAMETIME_CAPTION_GL_ROADVEHS :Ticks des véhicules routiers +STR_FRAMETIME_CAPTION_GL_SHIPS :Ticks des navires +STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Ticks des aéroplanes +STR_FRAMETIME_CAPTION_GL_LANDSCAPE :Ticks du monde +STR_FRAMETIME_CAPTION_GL_LINKGRAPH :Délai du flux des marchandises +STR_FRAMETIME_CAPTION_DRAWING :Rendu des graphismes +STR_FRAMETIME_CAPTION_DRAWING_VIEWPORTS :Rendu des vues +STR_FRAMETIME_CAPTION_VIDEO :Sortie vidéo +STR_FRAMETIME_CAPTION_SOUND :Mixage sonore +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Sauvegarder la partie STR_SAVELOAD_LOAD_CAPTION :{WHITE}Charger une partie @@ -2978,6 +3034,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Entrer u STR_TOWN_DIRECTORY_CAPTION :{WHITE}Villes STR_TOWN_DIRECTORY_NONE :{ORANGE}− Aucune − STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Métropole){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Noms des villes - Cliquer sur un nom pour centrer la vue principale sur la ville. Ctrl-clic pour ouvrir une nouvelle vue sur la ville. STR_TOWN_POPULATION :{BLACK}Population mondiale{NBSP}: {COMMA} @@ -2985,8 +3042,7 @@ STR_TOWN_POPULATION :{BLACK}Populati STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Métropole) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Population{NBSP}: {ORANGE}{COMMA}{BLACK} − Maisons{NBSP}: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passagers le mois dernier{NBSP}: {ORANGE}{COMMA}{BLACK} − max.{NBSP}: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Courrier le mois dernier{NBSP}: {ORANGE}{COMMA}{BLACK} − max.{NBSP}: {ORANGE}{COMMA} +STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} le mois dernier{NBSP}: {ORANGE}{COMMA}{BLACK} - max.{NBSP}: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Cargaison nécessaire à la croissance de la ville{NBSP}: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} requis STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} requis en hiver @@ -4225,7 +4281,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Trop de STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Trop de parties de gare STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Trop d'arrêts d'autobus STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Trop d'aires de chargement -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Trop près d'une autre gare STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Trop près d'un autre port STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Trop près d'un autre aéroport STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Impossible de renommer la gare... @@ -4233,6 +4288,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... cett STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... mauvaise orientation de la route STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... les arrêts ne peuvent pas avoir de virages STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... les arrêts ne peuvent pas avoir de jonctions +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... la route est à sens unique ou bloquée # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Impossible de supprimer une partie de la gare... @@ -4484,6 +4540,8 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Sons originaux STR_BASESOUNDS_WIN_DESCRIPTION :Sons originaux de Transport Tycoon Deluxe (version Windows). STR_BASESOUNDS_NONE_DESCRIPTION :Un pack de sons sans sons. STR_BASEMUSIC_WIN_DESCRIPTION :Musiques originales de Transport Tycoon Deluxe (version Windows). +STR_BASEMUSIC_DOS_DESCRIPTION :Musiques originales de Transport Tycoon Deluxe (version DOS). +STR_BASEMUSIC_TTO_DESCRIPTION :Musiques originales de Transport Tycoon (version Originale/World Editor). STR_BASEMUSIC_NONE_DESCRIPTION :Un pack de musiques sans musiques. ##id 0x2000 diff --git a/src/lang/gaelic.txt b/src/lang/gaelic.txt index c06b81ecf7..139d775cd3 100644 --- a/src/lang/gaelic.txt +++ b/src/lang/gaelic.txt @@ -868,10 +868,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Tagh am STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Toglaich prògram air thuaiream air/dheth STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Seall uinneag taghadh tracaichean ciùil -STR_ERROR_NO_SONGS :{WHITE}Chaidh seata dhe cheòl às aonais òrain a thaghadh. Cha tèid òran sam bith a chluiche - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Taghadh prògram ciùil STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} “{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Clàr-amais nan traca STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Prògram - “{STRING}" @@ -1539,8 +1536,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Dath na crutha- STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Uaine STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Dorch-uaine STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Purpaidh -STR_CONFIG_SETTING_REVERSE_SCROLLING :Comhair sgrolaidh chontrarra: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Giùlan nuair a thèid am mapa a sgroladh le putan deas na luchaige. Nuair a bhios seo air, gluaisidh an luchag am mapa STR_CONFIG_SETTING_SMOOTH_SCROLLING :Sgroladh mìn nam port-seallaidh: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Tagh mar a ghluaiseas am prìomh-shealladh gu ionad sònraichte. Ma tha seo dheth, thèid leum dhan ionad a chaidh a thaghadh sa bhad STR_CONFIG_SETTING_MEASURE_TOOLTIP :Seall gliocasan-sgrìn tomhais le innealan togail: {STRING} @@ -1572,8 +1567,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command+Briogad STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+Briogadh STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Dheth -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Sgroladh le briogadh clì: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Cuir an comas gun tèid am mapa a sgroladh le slaodadh le putan clì na luchaige. Tha seo feumail gu h-àraidh nuair a chleachdas tu sgrìn-shuathaidh airson sgroladh STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Dùin an uinneag le briogadh deas: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Dùinidh seo uinneag le briogadh deas ’na broinn. Cuiridh e à comas an gliocas-sgrìn le briogadh deas! @@ -2934,6 +2927,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Còir-le STR_ABOUT_VERSION :{BLACK}OpenTTD tionndadh {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 An sgioba OpenTTD +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Sàbhail an geama STR_SAVELOAD_LOAD_CAPTION :{WHITE}Luchdaich geama @@ -3225,8 +3225,6 @@ STR_TOWN_POPULATION :{BLACK}Sluagh a STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Mòr-bhaile) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Sluagh: {ORANGE}{COMMA}{BLACK} Taighean: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Taistealaich am mìos mu dheireadh: {ORANGE}{COMMA}{BLACK} as motha: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Post am mìos mu dheireadh: {ORANGE}{COMMA}{BLACK} as motha: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Carago a tha a dhìth ach am fàs am baile: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{RED}Feum air {ORANGE}{STRING} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{BLACK}Feum air {ORANGE}{STRING}{BLACK} sa gheamhradh @@ -4465,7 +4463,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Cus stè STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Cus pàirtean dhe stèisean-rèile STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Gus stèiseanan bus STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Tha cus ionadan-luchdaidh nan làraidh ann -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Ro fhaisg air stèisean/ionad-luchdaidh eile STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Ro fhaisg air port eile STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Ro fhaisg air port-adhair eile STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Cha ghabh ainm an stèisein atharrachadh... diff --git a/src/lang/galician.txt b/src/lang/galician.txt index d87aa14abe..a40620073f 100644 --- a/src/lang/galician.txt +++ b/src/lang/galician.txt @@ -670,10 +670,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Seleccio STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Activar/desactivar programa aleatorio STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Amosar a fiestra de selección de pista musical -STR_ERROR_NO_SONGS :{WHITE}Seleccionouse unha lista de reprodución sen cancións. Non se reproducirá ningunha canción - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Selección do programa de música STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Índice de pistas STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programa - '{STRING}' @@ -1338,8 +1335,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Cor do terreo n STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Verde STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Verde escuro STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Violeta -STR_CONFIG_SETTING_REVERSE_SCROLLING :Inverti-la dirección de desprazamento: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Acción cando o mapa se despraza co botón dereito do rato. Cando se desactiva, o rato move a cámara. Cando se activa, o rato move o mapa STR_CONFIG_SETTING_SMOOTH_SCROLLING :Desprazamento de vista suave: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Controla como a vista principal se despraza a unah posición específica cando se fai clic no minimapa ou cando se emprega un comando para desprazarse a un obxecto específico sobre o mapa. Se se activa, a vista desprázase suavemente, se se desactiva salta directamente STR_CONFIG_SETTING_MEASURE_TOOLTIP :Mostrar medidas ao usar as ferramentas de construción: {STRING} @@ -1371,8 +1366,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Tecla Command+C STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+Clic STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Apagado -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Desprazamento con click esquerdo: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Habilitar o desprazamento do mapa arrastrándoo co botón esquerdo do rato. Isto é especialmente útil se se emprega unha pantalla táctil para desprazarse STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Pechar a fiestra con click dereito: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Pecha a fiestra facendo botón dereito dentro de ela. Deshabilita a axuda contextual facendo click-dereito! @@ -2694,6 +2687,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Copyrigh STR_ABOUT_VERSION :{BLACK}OpenTTD versión {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2018 O equipo de OpenTTD +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Gravar partida STR_SAVELOAD_LOAD_CAPTION :{WHITE}Cargar partida @@ -2985,8 +2985,6 @@ STR_TOWN_POPULATION :{BLACK}Poboaci STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Cidade) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Poboación: {ORANGE}{COMMA}{BLACK} Casas: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Pasaxeiros último mes: {ORANGE}{COMMA}{BLACK} máx: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Correo último mes: {ORANGE}{COMMA}{BLACK} máx: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Carga necesaria para o crecemento da cidade: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} necesario STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} necesarios en inverno @@ -4225,7 +4223,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Demasiad STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Demasiadas partes de estación de tren STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Demasiadas paradas de autobús STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Demasiadas estacións de camións -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Demasiado preto doutra estación ou área de carga STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Demasiado preto doutro peirao STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Demasiado preto doutro aeroporto STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Non se pode renomear a estación... diff --git a/src/lang/german.txt b/src/lang/german.txt index 128c516c62..cd117258b4 100644 --- a/src/lang/german.txt +++ b/src/lang/german.txt @@ -670,10 +670,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Programm STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Zufällige Wiedergabe ein/aus STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Zeige Musiktitelauswahl -STR_ERROR_NO_SONGS :{WHITE}Ein Musikset ohne Musikdateien wurde ausgewählt. Es kann folglich nichts abgespielt werden. - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Musik-Programmauswahl STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Track Inhalt STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programm - '{STRING}' @@ -1338,8 +1335,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Farbe von Landf STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Grün STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Dunkelgrün STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Lila -STR_CONFIG_SETTING_REVERSE_SCROLLING :Scrollrichtung invertieren: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Legt das Verhalten beim Scrollen der Karte mit der rechten Maustaste fest. Ist diese Option aktiviert, bewegt sich der sichtbare Kartenausschnitt in Mausrichtung. Ist sie deaktiviert, bewegt sich die Karte entgegen der Mausrichtung STR_CONFIG_SETTING_SMOOTH_SCROLLING :Weicher Bildlauf beim Springen zu einer Position: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Lege fest, auf welche Weise die Hauptansicht an eine bestimmte Position wechselt (z.B. wenn ein Punkt auf der Weltkarte angeklickt wird oder der Standort eines Bahnhofs angezeigt werden soll). Ist diese Option eingeschaltet, schwenkt die Ansicht über die Karte, bis sie am gewünschten Punkt angekommen ist. Ist sie ausgeschaltet, springt die Ansicht sofort an die gewünschte Position STR_CONFIG_SETTING_MEASURE_TOOLTIP :Beim Bauen Tooltip mit Abmessungen anzeigen: {STRING} @@ -1371,8 +1366,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Kommando+Klick STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Strg+Klick STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Aus -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Scrollen mit linker Maustaste: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Scrolle die Karte, indem mit der linken Maustaste gezogen wird. Dies ist besonders sinnvoll, wenn ein Touchscreen zum Scrollen genutzt wird STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Fenster mit Rechtsklick schließen: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Schließt ein Fenster mittels Rechts-Klick. Schaltet Tooltip mit Rechts-Klick ab! @@ -2694,6 +2687,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Transpor STR_ABOUT_VERSION :{BLACK}OpenTTD-Version {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 OpenTTD-Team +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Spiel speichern STR_SAVELOAD_LOAD_CAPTION :{WHITE}Spiel laden @@ -2985,8 +2985,6 @@ STR_TOWN_POPULATION :{BLACK}Weltbev STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Großstadt) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Einwohner: {ORANGE}{COMMA}{BLACK} Häuser: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passagiere im letzten Monat: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Postsäcke im letzten Monat: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Für Stadtwachstum benötigte Fracht: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} benötigt STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} im Winter benötigt @@ -4225,7 +4223,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Zu viele STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Zu viele Bahnsteigteile STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Zu viele Bushaltestellen STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Zu viele Lkw-Ladeplätze -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Stationen liegen zu dicht beisammen STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Zu dicht an einem anderen Hafen STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Zu dicht an einem anderen Flughafen STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Station kann nicht umbenannt werden... diff --git a/src/lang/greek.txt b/src/lang/greek.txt index 11d5755d78..5b5cd91621 100644 --- a/src/lang/greek.txt +++ b/src/lang/greek.txt @@ -731,7 +731,7 @@ STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Δάνε STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Σύνολο: ############ End of order list STR_PERFORMANCE_DETAIL_VEHICLES_TOOLTIP :{BLACK}Απαρίθμηση των οχημάτων που απέφεραν κέρδος πέρσι. Περιλαμβανομένων των επιγείων οχημάτων, τρένων, πλοίων και αεροσκαφών. -STR_PERFORMANCE_DETAIL_STATIONS_TOOLTIP :{BLACK}Αριθμός των πρόσφατα επισκευασμένων σταθμών. Σταθμοί τραίνων, στάσεις λεωφορείων, αεροδρόμια, κ.ο.κ. προσμετρώνται ξεχωριστά, ακόμα κι αν ανήκουν στον ίδιο σταθμό. +STR_PERFORMANCE_DETAIL_STATIONS_TOOLTIP :{BLACK}Αριθμός των πρόσφατα επισκευασμένων σταθμών. Σταθμοί τρένων, στάσεις λεωφορείων, αεροδρόμια, κ.ο.κ. προσμετρώνται ξεχωριστά, ακόμα κι αν ανήκουν στον ίδιο σταθμό. STR_PERFORMANCE_DETAIL_MIN_PROFIT_TOOLTIP :{BLACK}Το κέρδος του οχήματος με το μικρότερο εισόδημα (μόνο οχήματα παλιότερα των 2 ετών θα λαμβάνονται υπόψην) STR_PERFORMANCE_DETAIL_MIN_INCOME_TOOLTIP :{BLACK}Το ποσό των χρημάτων που έγιναν σε ένα τρίμηνο με το μικρότερο κέρδος των τελευταίων 12 τριμήνων STR_PERFORMANCE_DETAIL_MAX_INCOME_TOOLTIP :{BLACK}Το ποσό των χρημάτων που έγιναν σε ένα τρίμηνο με το μεγαλύτερο κέρδος των τελευταίων 12 τριμήνων @@ -757,6 +757,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}Δεν υπάρχει διαθέσιμη μουσική STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}«{STRING}» STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Κομμάτι STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Τίτλος @@ -776,15 +777,15 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Επιλ STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Εναλλαγή τυχαίας αναπαραγωγής on/off στο πρόγραμμα STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Εμφάνιση παραθύρου επιλογής μουσικού κομματιού -STR_ERROR_NO_SONGS :{WHITE}Επιλέχτηκε σετ μουσικής χωρίς τραγούδια. Κανένα τραγούδι δεν θα παιχτεί - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Επιλογή Μουσικού Προγράμματος +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Πρόγραμμα μουσικής - '{STRING}' STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} «{STRING}» STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Λίστα σιδηροτροχιών STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Πρόγραμμα - '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Καθαρισμός +STR_PLAYLIST_CHANGE_SET :{BLACK}Αλλαγή σετ STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Καθαρισμός τρέχοντος προγράμματος (μόνο Προσαρμοσμένο 1 ή Προσαρμοσμένο 2) +STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Αλλαγή μουσικής επιλογής σε άλλο εγκατεστημένο σετ STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Πατήστε στο μουσικό κομμάτι για προσθήκη στο τρέχον πρόγραμμα (Προσαρμοσμένο1 ή Προσαρμοσμένο2 μόνο) STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Πατήστε στο τραγούδι για να το αφαιρέσετε από το πρόγραμμα (Προσαρμοσμένο 1 ή 2 μόνο) @@ -987,9 +988,9 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC # Extra view window STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Εμφάνιση {COMMA} -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Αντιγραφή στην εμφάνιση +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Αντιγραφή στο παράθυρο εμφάνισης STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Αντιγραφή της τοποθεσίας της κύριας προβολής σε αυτό το παράθυρο εμφάνισης -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Επικόλληση από εμφάνιση +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Επικόλληση από παράθυρο εμφάνισης STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Επικόλληση της τοποθεσίας αυτού του παραθύρου εμφάνισης στην κύρια προβολή # Game options window @@ -1278,22 +1279,22 @@ STR_CONFIG_SETTING_CATCHMENT :Επιτρέπ STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Διαφορετικοί σταθμοί και αεροδρόμια έχουν περιοχές κάλυψης διαφορετικού μεγέθους STR_CONFIG_SETTING_EXTRADYNAMITE :Επιτρέπεται η αφαίρεση περισσότερων ιδιοκτησιών των πολέων: {STRING} STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Είναι ευκολότερη η αφαίρεση υποδομών και κτιρίων που κατέχονται από την πόλη -STR_CONFIG_SETTING_TRAIN_LENGTH :Μέγιστο μήκος τραίνων: {STRING} -STR_CONFIG_SETTING_TRAIN_LENGTH_HELPTEXT :Ορίστε το μέγιστο μήκος των τραίνων +STR_CONFIG_SETTING_TRAIN_LENGTH :Μέγιστο μήκος τρένων: {STRING} +STR_CONFIG_SETTING_TRAIN_LENGTH_HELPTEXT :Ορίστε το μέγιστο μήκος των τρένων STR_CONFIG_SETTING_TILE_LENGTH :{COMMA} τετραγωνίδι{P 0 ο α} STR_CONFIG_SETTING_SMOKE_AMOUNT :Ποσότητα καπνού/σπινθύρων οχήματος: {STRING} STR_CONFIG_SETTING_SMOKE_AMOUNT_HELPTEXT :Ορίστε τον όγκο του καπνού ή τον αριθμό των σπιθών που παράγονται από τα οχήματα STR_CONFIG_SETTING_TRAIN_ACCELERATION_MODEL :Μοντέλο επιτάχυνσης τρένων: {STRING} -STR_CONFIG_SETTING_TRAIN_ACCELERATION_MODEL_HELPTEXT :Επιλέξτε το μοντέλο φυσικής για την επιτάχυνση των τραίνων. Με το «αρχικό» μοντέλο οι κλίσεις επιβαρύνουν το ίδιο όλα τα οχήματα. Με το «ρεαλιστικό» μοντέλο οι κλίσεις και οι στροφές τα επιβαρύνουν ανάλογα με διάφορες ιδιότητες όπως το μήκος και το ελκτικό φορτίο +STR_CONFIG_SETTING_TRAIN_ACCELERATION_MODEL_HELPTEXT :Επιλέξτε το μοντέλο φυσικής για την επιτάχυνση των τρένων. Με το «αρχικό» μοντέλο οι κλίσεις επιβαρύνουν το ίδιο όλα τα οχήματα. Με το «ρεαλιστικό» μοντέλο οι κλίσεις και οι στροφές τα επιβαρύνουν ανάλογα με διάφορες ιδιότητες όπως το μήκος και το ελκτικό φορτίο STR_CONFIG_SETTING_ROAD_VEHICLE_ACCELERATION_MODEL :Μοντέλο επιτάχυνσης οχημάτων δρόμου: {STRING} STR_CONFIG_SETTING_ROAD_VEHICLE_ACCELERATION_MODEL_HELPTEXT :Επιλέξτε το μοντέλο φυσικής για την επιτάχυνση των οχημάτων. Με το «αρχικό» μοντέλο οι κλίσεις επιβαρύνουν το ίδιο όλα τα οχήματα. Με το «ρεαλιστικό» μοντέλο οι κλίσεις και οι στροφές τα επιβαρύνουν ανάλογα με διάφορες ιδιότητες όπως το μήκος και το ελκτικό φορτίο -STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS :Κλίση εδάφους για τα τραίνα: {STRING} -STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :Η κλίση ενός κεκλιμένου τετραγωνίδιου για τα τραίνα. Μεγαλύτερες τιμές καθιστούν δυσκολότερο το ανέβασμα λόφων +STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS :Κλίση εδάφους για τα τρένα: {STRING} +STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :Η κλίση ενός κεκλιμένου τετραγωνίδιου για τα τρένα. Μεγαλύτερες τιμές καθιστούν δυσκολότερο το ανέβασμα λόφων STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Κλίση εδάφους για τα οδικά οχήματα: {STRING} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Η κλίση ενός κεκλιμένου τετραγωνίδιου για τα οδικά οχήματα. Μεγαλύτερες τιμές καθιστούν δυσκολότερο το ανέβασμα λόφων STR_CONFIG_SETTING_FORBID_90_DEG :Απαγόρευση στα τρένα και πλοία να κάνουν στροφές 90°: {STRING} -STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :Στροφές 90 μοιρών προκύπτουν όταν μια οριζόντια σιδηροτροχιά ακολουθείται από μια κάθετη στο επόμενο τετραγωνίδιο, κάνοντας το τραίνο να στρίψει κατά 90 μοίρες όταν αλλάζει τετραγωνίδιο, αντί για τις συνηθισμένες 45 μοίρες σε άλλους συνδυασμούς σιδηροτροχιών. Αυτό έχει επίσης εφαρμογή στην ακτίνα στροφής των πλοίων +STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :Στροφές 90 μοιρών προκύπτουν όταν μια οριζόντια σιδηροτροχιά ακολουθείται από μια κάθετη στο επόμενο τετραγωνίδιο, κάνοντας το τρένο να στρίψει κατά 90 μοίρες όταν αλλάζει τετραγωνίδιο, αντί για τις συνηθισμένες 45 μοίρες σε άλλους συνδυασμούς σιδηροτροχιών. Αυτό έχει επίσης εφαρμογή στην ακτίνα στροφής των πλοίων STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Να επιτρέπεται η συνένωση μη παρακείμενων σταθμών: {STRING} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Επιτρέπεται η προσθήκη τμημάτων σε σταθμό χωρίς αυτά να αγγίζουν τα ήδη υπάρχοντα τμήματα. Χρειάζεται Ctrl+Κλικ κατά την τοποθέτηση των νέων τμημάτων STR_CONFIG_SETTING_INFLATION :Πληθωρισμός: {STRING} @@ -1323,7 +1324,7 @@ STR_CONFIG_SETTING_SHOWFINANCES_HELPTEXT :Όταν ενε STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT :Οι νέες οδηγίες είναι «χωρίς στάση» από προεπιλογή: {STRING} STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT_HELPTEXT :Κανονικά, τα οχήματα σταματούν σε κάθε σταθμό που περνούν. Ενεργοποιώντας αυτήν τη ρύθμιση, δεν θα σταματούν σε κανένα σταθμό που θα βρει στη διαδρομή τους προς τον τελικό προορισμό. Σημείωστε πως αυτή η ρύθμιση ορίζει μόνο μια καθορισμένη τιμή για νέες εντολές. Ειδικές εντολές μπορούν να δοθούν για οποιαδήποτε συμπεριφορά, άσχετα από την προκαθορισμένη STR_CONFIG_SETTING_STOP_LOCATION :Οι εντόλες νέων τρένων διορίζουν ότι σταματάνε εξ ορισμού στο {STRING} της πλατφόρμας -STR_CONFIG_SETTING_STOP_LOCATION_HELPTEXT :Το προεπιλεγμένο σημείο όπου θα σταματούν τα τραίνα στην πλατφόρμα . Το «κοντινό άκρο» σημαίνει κοντά στο σημείο εισόδου, «Μέση» σημαίνει στο μέσο της πλατφόρμας και «μακρινό άκρο» σημαίνει στο άλλο άκρο από το σημείο εισόδου. Σημειώστε ότι αυτή η ρύθμιση ορίζει μόνο την προκαθορισμένη τιμή για νέες εντολές. Παρ' όλα αυτά, είναι δυνατό να δοθούν διαφορετικές εντολές για οποιαδήποτε συμπεριφορά. +STR_CONFIG_SETTING_STOP_LOCATION_HELPTEXT :Το προεπιλεγμένο σημείο όπου θα σταματούν τα τρένα στην πλατφόρμα . Το «κοντινό άκρο» σημαίνει κοντά στο σημείο εισόδου, «Μέση» σημαίνει στο μέσο της πλατφόρμας και «μακρινό άκρο» σημαίνει στο άλλο άκρο από το σημείο εισόδου. Σημειώστε ότι αυτή η ρύθμιση ορίζει μόνο την προκαθορισμένη τιμή για νέες εντολές. Παρ' όλα αυτά, είναι δυνατό να δοθούν διαφορετικές εντολές για οποιαδήποτε συμπεριφορά. STR_CONFIG_SETTING_STOP_LOCATION_NEAR_END :κοντινό άκρο STR_CONFIG_SETTING_STOP_LOCATION_MIDDLE :στη μέση STR_CONFIG_SETTING_STOP_LOCATION_FAR_END :μακρινό άκρο @@ -1344,7 +1345,7 @@ STR_CONFIG_SETTING_ALLOW_FUND_ROAD_HELPTEXT :Επιτρέπ STR_CONFIG_SETTING_ALLOW_GIVE_MONEY :Επιτρέπεται η αποστολή χρημάτων σε άλλες εταιρίες: {STRING} STR_CONFIG_SETTING_ALLOW_GIVE_MONEY_HELPTEXT :Επιτρέπεται η μεταφορά χρημάτων μεταξύ των εταιρειών σε παιχνίδια πολλαπλών παικτών STR_CONFIG_SETTING_FREIGHT_TRAINS :Πολλαπλασιαστής βάρους σε φορτία για εξομοίωση βαρέων τρένων: {STRING} -STR_CONFIG_SETTING_FREIGHT_TRAINS_HELPTEXT :Ορίζεται ο αντίκτυπος της μεταφοράς φορτίων στα τραίνα. Υψηλότερη τιμή κάνει τη μεταφορά φορτίων πιο απαιτητική για τραίνα, ιδιαίτερα στους λόφους +STR_CONFIG_SETTING_FREIGHT_TRAINS_HELPTEXT :Ορίζεται ο αντίκτυπος της μεταφοράς φορτίων στα τρένα. Υψηλότερη τιμή κάνει τη μεταφορά φορτίων πιο απαιτητική για τρένα, ιδιαίτερα στους λόφους STR_CONFIG_SETTING_PLANE_SPEED :Παράγοντας ταχύτητας αεροπλάνων: {STRING} STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Ορίζεται η σχετική ταχύτητα των αεροπλάνων συγκριτικά με τους άλλους τύπους οχημάτων, ώστε να μειώνεται το ποσό του εισοδήματος από μεταφορές με αεροσκάφη STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} @@ -1444,8 +1445,12 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Χρώμα εδ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Πράσινο STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Σκούρο πράσινο STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Βιολετί -STR_CONFIG_SETTING_REVERSE_SCROLLING :Ανάποδη μετακίνηση οθόνης: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Συμπεριφορά όταν κυλίεται ο χάρτης με το δεξί κουμπί του ποντικιού. Όταν είναι απενεργοποιημένη, το ποντίκι μετακινεί την κάμερα. Όταν είναι ενεργοποιημένη, το ποντίκι μετακινεί τον χάρτη +STR_CONFIG_SETTING_SCROLLMODE :Συμπεριφορά κύλισης του παραθύρου εμφάνισης: {STRING} +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Συμπεριφορά κατά την κύλιση του χάρτη +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Μετακίνηση μικρού χάρτη με ΔΠΠ, θέση ποντικιού κλειδωμένη +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Μετακίνηση χάρτη με ΔΠΠ, θέση ποντικιού κλειδωμένη +STR_CONFIG_SETTING_SCROLLMODE_RMB :Μετακίνηση χάρτη με ΔΠΠ +STR_CONFIG_SETTING_SCROLLMODE_LMB :Μετακίνηση χάρτη με ΑΠΠ STR_CONFIG_SETTING_SMOOTH_SCROLLING :Ομαλή μετάβαση οθόνης: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Ελέγξτε τον τρόπο με τον οποίο η κύρια προβολή κυλίεται σε μια συγκεκριμένη θέση όταν πατάτε πάνω στον μικρό χάρτη ή όταν δίνετε εντολή για μετάβαση σε ένα συγκεκριμένο αντικείμενο στον χάρτη. Όταν είναι ενεργοποιημένη, η κύλιση γίνεται ομαλά, και όταν είναι απενεργοποιημένη μεταβαίνει απ' ευθείας στο επιλεγμένο σημείο STR_CONFIG_SETTING_MEASURE_TOOLTIP :Εμφάνιση εργαλείου μετρήσεως όταν χρησιμοποιούνται διάφορα εργαλεία: {STRING} @@ -1477,8 +1482,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command+Κλι STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Control+Κλικ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Απενεργοποιημένος -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Μετάβαση με αριστερό κλικ: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Ενεργοποίηση της κύλισης του χάρτη σύροντας τον με το αριστερό κουμπί του ποντικιού. Αυτό είναι ιδιαίτερα χρήσιμο για την κύλιση όταν χρησιμοποιείται οθόνη αφής STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Κλείσιμο παραθύρου με δεξί-κλικ: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Κλείνει το παράθυρο με δεξί πάτημα μέσα του. Απενεργοποιεί την ανάδυση επεξηγήσεων με το δεξί κουμπί! @@ -1504,7 +1507,7 @@ STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS_HELPTEXT :Ενεργοπ STR_CONFIG_SETTING_LOADING_INDICATORS :Χρήση δεικτών φόρτωσης: {STRING} STR_CONFIG_SETTING_LOADING_INDICATORS_HELPTEXT :Επιλέξτε εάν οι δείκτες φόρτωσης εμφανίζονται πάνω από τα οχήματα που φορτώνουν ή ξεφορτώνουν STR_CONFIG_SETTING_TIMETABLE_IN_TICKS :Εμφάνιση δρομολογίων σε στιγμές αντί για ημέρες: {STRING} -STR_CONFIG_SETTING_TIMETABLE_IN_TICKS_HELPTEXT :Εμφάνιση χρόνων ταξιδιού στα χρονοδιαγράμματα σε χρόνο παιχνιδιού αντί σε ημέρες +STR_CONFIG_SETTING_TIMETABLE_IN_TICKS_HELPTEXT :Εμφάνιση χρόνων ταξιδιού στα χρονοδιαγράμματα σε στιγμές αντί σε ημέρες STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE :Εμφάνιση αφίξεων και αναχωρήσεων στα δρομολόγια: {STRING} STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE_HELPTEXT :Εμφάνιση αναμενόμενης ώρας άφιξης και αναχώρησης στα χρονοδιαγράμματα STR_CONFIG_SETTING_QUICKGOTO :Γρήγορη δημιουργία εντολών για τα οχήματα: {STRING} @@ -1514,8 +1517,8 @@ STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_HELPTEXT :Επιλογή STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_FIRST :Πρώτος διαθέσιμος STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_LAST :Τελευταίος διαθέσιμος STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_MOST_USED :Περισσότερο χρησιμοποιούμενος -STR_CONFIG_SETTING_SHOW_TRACK_RESERVATION :Εμφάνιση δεσμέυσεων διαδρομών για γραμμές τραίνου: {STRING} -STR_CONFIG_SETTING_SHOW_TRACK_RESERVATION_HELPTEXT :Δίνεται ένα διαφορετικό χρώμα στις κατειλημμένες ράγες για να σας βοηθήσουν με προβλήματα όταν τα τραίνα αρνούνται να εισέλθουν σε τμήματα με βάση τροχιές +STR_CONFIG_SETTING_SHOW_TRACK_RESERVATION :Εμφάνιση δεσμέυσεων διαδρομών για γραμμές τρένου: {STRING} +STR_CONFIG_SETTING_SHOW_TRACK_RESERVATION_HELPTEXT :Δίνεται ένα διαφορετικό χρώμα στις κατειλημμένες ράγες για να σας βοηθήσουν με προβλήματα όταν τα τρένα αρνούνται να εισέλθουν σε τμήματα με βάση τροχιές STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS :Διατήρηση των οικοδομικών εργαλείων ενεργών μετά από χρήση τους: {STRING} STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS_HELPTEXT :Διατήρηση ανοικτών των εργαλείων για γέφυρες, σήραγγες, κλπ μετά από τη χρήση STR_CONFIG_SETTING_EXPENSES_LAYOUT :Ομαδοποίηση εξόδων στο παράθυρο οικονομικών της εταιρίας: {STRING} @@ -1541,7 +1544,7 @@ STR_CONFIG_SETTING_SOUND_AMBIENT_HELPTEXT :Παίζει τ STR_CONFIG_SETTING_DISABLE_UNSUITABLE_BUILDING :Απενεργοποίηση των υποδομών για τα οχήματα που δεν είναι διαθέσιμα: {STRING} STR_CONFIG_SETTING_DISABLE_UNSUITABLE_BUILDING_HELPTEXT :Όταν είναι ενεργοποιημένο, οι υποδομές είναι διαθέσιμες μόνο όταν υπάρχουν διαθέσιμα οχήματα, αποτρέποντας σπατάλη χρόνου και χρημάτων σε μη χρησιμοποιήσιμες υποδομές STR_CONFIG_SETTING_MAX_TRAINS :Μέγιστος αριθμός τρένων ανά εταιρία: {STRING} -STR_CONFIG_SETTING_MAX_TRAINS_HELPTEXT :Μέγιστος αριθμός τραίνων που μπορεί να έχει μια εταιρεία +STR_CONFIG_SETTING_MAX_TRAINS_HELPTEXT :Μέγιστος αριθμός τρένων που μπορεί να έχει μια εταιρεία STR_CONFIG_SETTING_MAX_ROAD_VEHICLES :Μέγιστος αριθμός οχημάτων δρόμου ανά εταιρία: {STRING} STR_CONFIG_SETTING_MAX_ROAD_VEHICLES_HELPTEXT :Μέγιστος αριθμός οδικών οχημάτων που μπορεί να έχει μια εταιρεία STR_CONFIG_SETTING_MAX_AIRCRAFT :Μέγιστος αριθμός αεροσκαφών ανά εταιρία: {STRING} @@ -1550,7 +1553,7 @@ STR_CONFIG_SETTING_MAX_SHIPS :Μέγιστο STR_CONFIG_SETTING_MAX_SHIPS_HELPTEXT :Μέγιστος αριθμός πλοίων που μπορεί να έχει μια εταιρεία STR_CONFIG_SETTING_AI_BUILDS_TRAINS :Απενεργοποίηση τρένων για τον υπολογιστή: {STRING} -STR_CONFIG_SETTING_AI_BUILDS_TRAINS_HELPTEXT :Ενεργοποιώντας αυτήν τη ρύθμιση κάνει αδύνατη την κατασκευή τραίνων από παίκτη του υπολογιστή +STR_CONFIG_SETTING_AI_BUILDS_TRAINS_HELPTEXT :Ενεργοποιώντας αυτήν τη ρύθμιση κάνει αδύνατη την κατασκευή τρένων από παίκτη του υπολογιστή STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES :Απενεργοποίηση οχημάτων υπολογιστή: {STRING} STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES_HELPTEXT :Ενεργοποιώντας αυτήν τη ρύθμιση κάνει αδύνατη την κατασκευή οδικών οχημάτων από παίκτη του υπολογιστή STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT :Απενεργοποίηση αεροσκαφών υπολογιστή: {STRING} @@ -1571,8 +1574,8 @@ STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Μέγιστο STR_CONFIG_SETTING_SERVINT_ISPERCENT :Τα διαστήματα μεταξύ συντήρησης είναι σε ποσοστά: {STRING} STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Επιλέξτε εάν η επισκευή των οχημάτων εξαρτάται από τον χρόνο που πέρασε από την τελευταία επισκευή ή από την μείωση της αξιοπιστίας κατά ένα συγκεκριμένο ποσοστό της μέγιστης αξιοπιστίας -STR_CONFIG_SETTING_SERVINT_TRAINS :Προκαθορισμένο διάστημα μεταξύ επισκευών για τα τραίνα: {STRING} -STR_CONFIG_SETTING_SERVINT_TRAINS_HELPTEXT :Ορίστε το προκαθορισμένο διάστημα μεταξύ συντηρήσεων για τα νέα οχήματα τραίνων, όταν δεν δίνεται άλλο διάστημα για το όχημα +STR_CONFIG_SETTING_SERVINT_TRAINS :Προκαθορισμένο διάστημα μεταξύ επισκευών για τα τρένα: {STRING} +STR_CONFIG_SETTING_SERVINT_TRAINS_HELPTEXT :Ορίστε το προκαθορισμένο διάστημα μεταξύ συντηρήσεων για τα νέα οχήματα τρένων, όταν δεν δίνεται άλλο διάστημα για το όχημα STR_CONFIG_SETTING_SERVINT_VALUE :{COMMA}{NBSP}ημέρ{P 0 α ες}/% STR_CONFIG_SETTING_SERVINT_DISABLED :Απενεργοποιημένο STR_CONFIG_SETTING_SERVINT_ROAD_VEHICLES :Προκαθορισμένο διάστημα μεταξύ συντηρήσεων για οδικά οχήματα: {STRING} @@ -1584,7 +1587,7 @@ STR_CONFIG_SETTING_SERVINT_SHIPS_HELPTEXT :Ορίστε τ STR_CONFIG_SETTING_NOSERVICE :Απενεργοποίηση επισκευών όταν οι καταρρεύσεις είναι απενεργοποιημένες: {STRING} STR_CONFIG_SETTING_NOSERVICE_HELPTEXT :Όταν είναι ενεργοποιημένη, τα οχήματα δεν συντηρούνται όταν δεν είναι δυνατό να χαλάσουν STR_CONFIG_SETTING_WAGONSPEEDLIMITS :Ενεργοποίηση ορίων ταχύτητας βαγονιών: {STRING} -STR_CONFIG_SETTING_WAGONSPEEDLIMITS_HELPTEXT :Όταν είναι ενεργοποιημένο, χρησιμοποιούνται και τα όρια ταχύτητας των βαγονιών όταν αποφασίζεται η μέγιστη ταχύτητα ενός τραίνου +STR_CONFIG_SETTING_WAGONSPEEDLIMITS_HELPTEXT :Όταν είναι ενεργοποιημένο, χρησιμοποιούνται και τα όρια ταχύτητας των βαγονιών όταν αποφασίζεται η μέγιστη ταχύτητα ενός τρένου STR_CONFIG_SETTING_DISABLE_ELRAILS :Απενεργοποίηση ηλεκτρικών σιδηροτροχιών: {STRING} STR_CONFIG_SETTING_DISABLE_ELRAILS_HELPTEXT :Ενεργοποιώντας αυτήν την ρύθμιση απενεργοποιείται η ανάγκη ηλεκτροδότησης των σιδηροτροχιών για να μπορέσουν σε αυτές να λειτουργήσουν οι ηλεκτρικές μηχανές @@ -1802,13 +1805,13 @@ STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Συνίσταται) STR_CONFIG_SETTING_PATHFINDER_FOR_TRAINS :Μέθοδος δρομολόγησης για τρένα: {STRING} -STR_CONFIG_SETTING_PATHFINDER_FOR_TRAINS_HELPTEXT :Μέθοδος διαπίστωσης διαδρομής που χρησιμοποιείται για τα τραίνα +STR_CONFIG_SETTING_PATHFINDER_FOR_TRAINS_HELPTEXT :Μέθοδος διαπίστωσης διαδρομής που χρησιμοποιείται για τα τρένα STR_CONFIG_SETTING_PATHFINDER_FOR_ROAD_VEHICLES :Μέθοδος δρομολόγησης για οχήματα δρόμου: {STRING} STR_CONFIG_SETTING_PATHFINDER_FOR_ROAD_VEHICLES_HELPTEXT :Μέθοδος διαπίστωσης διαδρομής που χρησιμοποιείται για τα οδικά οχήματα STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS :Μέθοδος δρομολόγησης για πλοία: {STRING} STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS_HELPTEXT :Μέθοδος διαπίστωσης διαδρομής που χρησιμοποιείται για τα πλοία STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Αυτόματη αναστροφή σε σηματοδότες: {STRING} -STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Επιτρέπεται στα τραίνα να αντιστραφούν σε σήμα, εάν περιμένουν εκεί για πολύ ώρα +STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Επιτρέπεται στα τρένα να αντιστραφούν σε σήμα, εάν περιμένουν εκεί για πολύ ώρα STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Αλλαγή τιμής ρύθμισης @@ -2392,6 +2395,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Υπόμ STR_LINKGRAPH_LEGEND_ALL :{BLACK}Όλες STR_LINKGRAPH_LEGEND_NONE :{BLACK}Καμία STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Επιλογή εταιριών για να εμφανιστούν +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}μη χρησιμοποιημένο @@ -2800,6 +2804,37 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Αρχι STR_ABOUT_VERSION :{BLACK}Έκδοση OpenTTD{REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 Η ομάδα του OpenTTD +# Framerate display window +STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Αριθμός στιγμών παιχνιδιού που προσομοιώνεται ανά δευτερόλεπτο. +STR_FRAMERATE_SPEED_FACTOR :{WHITE}Παράγοντας ταχύτητας τρέχοντος παιχνιδιού: {DECIMAL}x +STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Πόσο γρήγορα εκτελείται το παιχνίδι αυτήν τη στιγμή, σε σύγκριση με την αναμενόμενη ταχύτητα στον κανονικό ρυθμό εξομοίωσης. +STR_FRAMERATE_CURRENT :{WHITE}Τρέχον +STR_FRAMERATE_AVERAGE :{WHITE}Μέσο +STR_FRAMERATE_DATA_POINTS :{WHITE}Τα δεδομένα βασίζονται σε μετρήσεις {COMMA} +STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL}{WHITE} ms +############ Leave those lines in this order!! +STR_FRAMERATE_GL_ECONOMY :{WHITE} Διαχείριση φορτίου: +STR_FRAMERATE_GL_TRAINS :Στιγμές τρένων: +STR_FRAMERATE_GL_ROADVEHS :{WHITE} Στιγμές οχημάτων δρόμου: +STR_FRAMERATE_GL_SHIPS :Στιγμές πλοίων: +STR_FRAMERATE_GL_AIRCRAFT :Στιγμές αεροσκαφών: +STR_FRAMERATE_GL_LANDSCAPE :Στιγμές κόσμου: +STR_FRAMERATE_VIDEO :{WHITE}Έξοδος βίντεο: +STR_FRAMERATE_SOUND :{WHITE}Μίξη ήχου: +############ End of leave-in-this-order +############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_GL_ECONOMY :Διαχείριση φορτίου +STR_FRAMETIME_CAPTION_GL_TRAINS :Στιγμές τρένων +STR_FRAMETIME_CAPTION_GL_ROADVEHS :Στιγμές οχημάτων δρόμου +STR_FRAMETIME_CAPTION_GL_SHIPS :Στιγμές πλοίων +STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Στιγμές αεροσκαφών +STR_FRAMETIME_CAPTION_GL_LANDSCAPE :Στιγμές κόσμου +STR_FRAMETIME_CAPTION_GL_LINKGRAPH :Καθυστέρηση γραφήματος συνδέσμου +STR_FRAMETIME_CAPTION_VIDEO :Έξοδος βίντεο +STR_FRAMETIME_CAPTION_SOUND :Μίξη ήχου +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Αποθήκευση Παιχνιδιού STR_SAVELOAD_LOAD_CAPTION :{WHITE}Φόρτωση Παιχνιδιού @@ -3084,6 +3119,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Δώστ STR_TOWN_DIRECTORY_CAPTION :{WHITE}Πόλεις STR_TOWN_DIRECTORY_NONE :{ORANGE}- Τίποτα - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Πόλη){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Ονόματα πόλεων - πατήστε στο όνομα για να κεντράρετε την εικόνα στην πόλη. Με Ctrl+Κλικ ανοίγει νέο παράθυρο προβολής στην τοποθεσία της πόλης STR_TOWN_POPULATION :{BLACK}Παγκόσμιος πληθυσμός: {COMMA} @@ -3091,8 +3127,7 @@ STR_TOWN_POPULATION :{BLACK}Παγκ STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Πόλη) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Πληθυσμός: {ORANGE}{COMMA}{BLACK} Σπίτια: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Επιβάτες τον προηγούμενο μήνα: {ORANGE}{COMMA}{BLACK} μεγ: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Αλληλογραφία τον προηγούμενο μήνα: {ORANGE}{COMMA}{BLACK} μεγ: {ORANGE}{COMMA} +STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} προηγούμενος μήνας: {ORANGE}{COMMA}{BLACK} μέγιστο: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Εμπορεύματα που χρειάζονται για την επέκταση της πόλης: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} απαιτείται STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} απαιτείται τον χειμώνα @@ -3293,7 +3328,7 @@ STR_FINANCES_EXPENDITURE_INCOME_TITLE :{WHITE}Έξοδ STR_FINANCES_YEAR :{WHITE}{NUM} STR_FINANCES_SECTION_CONSTRUCTION :{GOLD}Κατασκευές STR_FINANCES_SECTION_NEW_VEHICLES :{GOLD}Νέα Οχήματα -STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Λειτουργικά Έξοδα Τραίνων +STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Λειτουργικά Έξοδα Τρένων STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Λειτουργικά Έξοδα Οχημάτων STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Λειτουργικά Έξοδα Αεροσκαφών STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Λειτουργικά Έξοδα Πλοίων @@ -3605,7 +3640,7 @@ STR_DEPOT_CLONE_ROAD_VEHICLE :{BLACK}Κλων STR_DEPOT_CLONE_SHIP :{BLACK}Κλωνοποίηση Πλοίου STR_DEPOT_CLONE_AIRCRAFT :{BLACK}Κλωνοποίηση Αεροσκάφους -STR_DEPOT_CLONE_TRAIN_DEPOT_INFO :{BLACK}Αυτό θα αγοράσει ένα αντίγραφο του τρένου μαζί με τα όλα τα βαγόνια. Πατήστε αυτό το κουμπί και μετά σε κάποιο τραίνο μέσα ή έξω από το αμαξοστάσιο. Με Ctrl+Κλικ θα έχει τις ίδιες εντολές. Με Shift+Κλικ εμφανίζεται το εκτιμώμενο κόστος χωρίς να γίνει η αγορά +STR_DEPOT_CLONE_TRAIN_DEPOT_INFO :{BLACK}Αυτό θα αγοράσει ένα αντίγραφο του τρένου μαζί με τα όλα τα βαγόνια. Πατήστε αυτό το κουμπί και μετά σε κάποιο τρένο μέσα ή έξω από το αμαξοστάσιο. Με Ctrl+Κλικ θα έχει τις ίδιες εντολές. Με Shift+Κλικ εμφανίζεται το εκτιμώμενο κόστος χωρίς να γίνει η αγορά STR_DEPOT_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Αυτό θα αγοράσει ένα αντίγραφο του οχήματος. Πατήστε αυτό το κουμπί και μετά σε κάποιο όχημα μέσα ή έξω από το αμαξοστάσιο. Με Ctrl+Κλικ θα έχει τις ίδιες εντολές. Με Shift+Κλικ εμφανίζεται το εκτιμώμενο κόστος χωρίς να γίνει η αγορά STR_DEPOT_CLONE_SHIP_DEPOT_INFO :{BLACK}Αυτό θα αγοράσει ένα αντίγραφο του πλοίου. Πατήστε αυτό το κουμπί και μετά σε κάποιο πλοίο μέσα ή έξω από το ναυπηγείο. Με Ctrl+Κλικ θα έχει τις ίδιες εντολές. Με Shift+Κλικ εμφανίζεται το εκτιμώμενο κόστος χωρίς να γίνει η αγορά STR_DEPOT_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Αυτό θα αγοράσει ένα αντίγραφο του αεροσκάφους. Πατήστε αυτό το κουμπί και μετά σε κάποιο αεροσκάφος μέσα στο ή έξω από το υπόστεγο. Με Ctrl+Κλικ θα έχει τις ίδιες εντολές. Με Shift+Κλικ εμφανίζεται το εκτιμώμενο κόστος χωρίς να γίνει η αγορά @@ -4337,7 +4372,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Πάρα STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Πάρα πολλά κομμάτια σιδηροδρομικού σταθμού STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Πάρα πολλές στάσεις λεωφορείου STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Πάρα πολλοί σταθμοί φορτηγών -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Πολύ κοντά σε άλλη περιοχή σταθμού/φόρτωσης STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Πολύ κοντά σε άλλη αποβάθρα STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Πολύ κοντά σε άλλο αεροδρόμιο STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Δεν μπορεί να μετονομαστεί ο σταθμός... @@ -4345,6 +4379,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... αυ STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... ο δρόμος βλέπει σε λάθος κατεύθυνση STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... οι μη τερματικοί σταθμοί δε μπορούν να έχουν στροφές STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... οι μη τερματικοί σταθμοί δε μπορούν να έχουν διασταυρώσεις +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... ο δρόμος είναι μονόδρομος η μπλοκαρισμένος # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Δεν μπορεί να αφαιρεθεί μέρος του σταθμού... @@ -4549,7 +4584,7 @@ STR_ERROR_NO_VEHICLES_AVAILABLE_YET_EXPLANATION :{WHITE}Ξεκι # Specific vehicle errors STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Δεν μπορεί το τρένο να περάσει σήμα με κίνδυνο... STR_ERROR_CAN_T_REVERSE_DIRECTION_TRAIN :{WHITE}Δεν αντιστρέφεται η κατεύθυνση του τρένου... -STR_ERROR_TRAIN_START_NO_POWER :Το τραίνο δεν έχει ενέργεια +STR_ERROR_TRAIN_START_NO_POWER :Το τρένο δεν έχει ενέργεια STR_ERROR_CAN_T_MAKE_ROAD_VEHICLE_TURN :{WHITE}Δεν γίνεται να αλλάξει πορεία το όχημα... @@ -4596,6 +4631,8 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Αρχικοί STR_BASESOUNDS_WIN_DESCRIPTION :Αρχικοί ήχοι από το Transport Tycoon Deluxe έκδοση Windows. STR_BASESOUNDS_NONE_DESCRIPTION :Ένα πάκετο ήχων χώρις ήχους. STR_BASEMUSIC_WIN_DESCRIPTION :Αρχική μουσική από το Transport Tycoon Deluxe έκδοση Windows. +STR_BASEMUSIC_DOS_DESCRIPTION :Αρχική μουσική από το Transport Tycoon Deluxe έκδοση DOS. +STR_BASEMUSIC_TTO_DESCRIPTION :Αρχική μουσική από το Transport Tycoon (Αρχικός Επεξεργαστής Κόσμου) έκδοση DOS. STR_BASEMUSIC_NONE_DESCRIPTION :Ένα πάκετο μουσικής χωρίς πραγματική μουσική. ##id 0x2000 diff --git a/src/lang/hebrew.txt b/src/lang/hebrew.txt index 90ed5ccc55..8f15c95ef6 100644 --- a/src/lang/hebrew.txt +++ b/src/lang/hebrew.txt @@ -489,6 +489,7 @@ STR_ABOUT_MENU_SCREENSHOT :צילום מס STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :צילום מסך בהגדלה מלאה STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :ברירת מחדל של תקריב צילום מסך STR_ABOUT_MENU_GIANT_SCREENSHOT :צילום מסך ענק +STR_ABOUT_MENU_SHOW_FRAMERATE :הצג קצב פריימים STR_ABOUT_MENU_ABOUT_OPENTTD :'OpenTTD'{NBSP}אודות STR_ABOUT_MENU_SPRITE_ALIGNER :מיישר ספרייטים STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :הדלק/כבה הצגת תיבות גבול של ספרייטים @@ -664,6 +665,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}אין מוזיקה זמינה STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" STR_MUSIC_TRACK :{TINY_FONT}{BLACK}רצועה STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}כותרת @@ -683,10 +685,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}(בחר STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}עירבוב תוכניות פועל/כבוי STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}הצג את חלון בחירת המנגינה -STR_ERROR_NO_SONGS :{WHITE}נבחרה ערכת מוזיקה ללא שירים. לא יושמעו שירים - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}בחירת תכנית מנגינה STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}רשימת רצועות STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}תוכנית- '{STRING}' @@ -939,6 +938,7 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :(ZAR) ראנד STR_GAME_OPTIONS_CURRENCY_CUSTOM :אחר... STR_GAME_OPTIONS_CURRENCY_GEL :לארי גאורגי (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :ריאל איראני (IRR) +STR_GAME_OPTIONS_CURRENCY_RUB :רובל רוסי (RUB) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}רכבי כביש @@ -1351,8 +1351,8 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :צבע פני STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :ירוק STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :ירוק כהה STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :סגול -STR_CONFIG_SETTING_REVERSE_SCROLLING :{STRING} :היפוך כיוון הגלילה של התצוגה -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :התנהגות בעת גלילת המפה באמצעות כפתור העכבר האמצעי. כאשר מבוטל, העכבר מזיז את המצלמה. כאשר מאופשר, העכבר מזיז את המפה +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :הזז את התצוגה עם כפתור עכבר ימני, מיקום העכבר נעול +STR_CONFIG_SETTING_SCROLLMODE_LMB :הזז מפה עם כפתור עכבר שמאלי STR_CONFIG_SETTING_SMOOTH_SCROLLING :{STRING} :גלילה חלקה של התצוגה המשנית STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :שלוט כיצד התצוגה הראשית נגללת למיקום מסוים כאשר מקליקים על המפה הקטנה אן כאשר נותנים הוראה לגלול לעצם מסוים על גבי המפה. אם מאופשר, חלון התצוגה נגלל באופן חלק, אם מבוטל הוא מוקפץ ישירות אל נקודת המטרה STR_CONFIG_SETTING_MEASURE_TOOLTIP :{STRING} :'הצג מידות בעת בניית כבישים/מסילות וכיוב @@ -1384,8 +1384,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command-click STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Control-click STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :כבוי -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :גלילה בלחיצה שמאלית: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :אפשר גלילת המפה באמצעות גרירתה עם כפתור העכבר השמאלי. אפשרות זו שימושית במיוחד בעת שימוש במסך מגע לצורך גלילה STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :סגירת חלון בכפתור ימני: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :סוגר חלון על-ידי לחיצה ימנית בתוכו. מבטל הצגת מידע בלחיצה ימנית! @@ -2707,6 +2705,27 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}כל ה STR_ABOUT_VERSION :{BLACK}{REV} גירסה , OpenTTD STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2018 The OpenTTD team +# Framerate display window +STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) +STR_FRAMERATE_RATE_GAMELOOP :{WHITE}קצב סימולציה: {STRING} +STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK} כמה מהר המשחק כרגע רץ, בהשוואה למהירות הצפוייה בקצב סימולציה רגיל. +STR_FRAMERATE_DATA_POINTS :{WHITE}נתונים מבוססים על {COMMA} מדידות +############ Leave those lines in this order!! +STR_FRAMERATE_GL_ROADVEHS :{WHITE} פעימות כלי רכב: +STR_FRAMERATE_GL_SHIPS :{WHITE} פעימות כלי שייט: +STR_FRAMERATE_GL_LANDSCAPE :{WHITE} נקודות עולם: +STR_FRAMERATE_DRAWING :{WHITE}עיבוד גרפיקה: +STR_FRAMERATE_SOUND :{WHITE} ערבוב צליל: +############ End of leave-in-this-order +############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_GL_TRAINS :פעימות רכבת +STR_FRAMETIME_CAPTION_GL_LINKGRAPH :השהיית גרף קשרים +STR_FRAMETIME_CAPTION_DRAWING :עיבוד גרפיקה +STR_FRAMETIME_CAPTION_DRAWING_VIEWPORTS :עיבוד תצוגת עולם +STR_FRAMETIME_CAPTION_VIDEO :פלט וידאו +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}שמור משחק STR_SAVELOAD_LOAD_CAPTION :{WHITE}טען משחק @@ -2733,7 +2752,7 @@ STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: STR_SAVELOAD_OSKTITLE :{BLACK}הכנס שם לשמירה # World generation -STR_MAPGEN_WORLD_GENERATION_CAPTION :{WHITE}יצור עולם +STR_MAPGEN_WORLD_GENERATION_CAPTION :{WHITE}יצירת עולם STR_MAPGEN_MAPSIZE :{BLACK}:גודל המפה STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}בחר את גודל המפה במשבצות. מספר המשבצות הזמינות תהיה קצת קטנה יותר. STR_MAPGEN_BY :{BLACK}* @@ -2991,6 +3010,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}הכנס STR_TOWN_DIRECTORY_CAPTION :{WHITE}ערים STR_TOWN_DIRECTORY_NONE :{ORANGE}- אין - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (City){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}שמות ערים - לחץ על שם כדי למקד את התצוגה על העיר. Ctrl+לחיצה פותח חלונית תצוגה חדשה על מיקום העיר STR_TOWN_POPULATION :{BLACK}אוכלוסיית העולם: {COMMA} @@ -2998,8 +3018,6 @@ STR_TOWN_POPULATION :{BLACK}אוכל STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (עיר) STR_TOWN_VIEW_POPULATION_HOUSES :{ORANGE}{1:COMMA}{BLACK} :בתים {ORANGE}{0:COMMA}{BLACK} :אוכלוסיה -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{ORANGE}{1:COMMA}{BLACK} :מספר מירבי {ORANGE}{0:COMMA}{BLACK} :נוסעים בחודש שעבר -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{ORANGE}{1:COMMA}{BLACK} :מספר מירבי {ORANGE}{0:COMMA}{BLACK} :שקי דואר בחודש שעבר STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}המטען שצריך בשביל גידול עיר STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} דרוש STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} דרוש בחורף @@ -4238,7 +4256,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}יותר STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}התחנה מורכבת מיותר מידי חלקים STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}יותר מידי תחנות אוטובוס STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}יותר מידי תחנות משאיות -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}קרוב מידי לתחנה או איזור טעינה אחרים STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}יותר מידי קרוב למזח אחר STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}קרוב מידי לשדה תעופה אחר STR_ERROR_CAN_T_RENAME_STATION :{WHITE}לא ניתן לשנות שם תחנה... @@ -4246,6 +4263,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... כב STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}הכביש פונה לכיוון לא נכון... STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... לתחנות "על הדרך" לא יכולות להיות פינות STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... לתחנות "על הדרך" לא יכולות להיות צמתים +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... הדרך חד כיוונית או חסומה # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}... לא ניתן לבטל חלק מהתחנה @@ -4497,6 +4515,7 @@ STR_BASESOUNDS_DOS_DESCRIPTION :צלילי Tran STR_BASESOUNDS_WIN_DESCRIPTION :צלילי Transport Tycoon Deluxe המקורי בגרסת Windows. STR_BASESOUNDS_NONE_DESCRIPTION :אוסף צלילים ללא צלילים. STR_BASEMUSIC_WIN_DESCRIPTION :מנגינות Transport Tycoon Deluxe המקורי בגרסת Windows. +STR_BASEMUSIC_TTO_DESCRIPTION :מנגינות Transport Tycoon Deluxe (Original/World Editor) המקורי בגרסת DOS. STR_BASEMUSIC_NONE_DESCRIPTION :אוסף מנגינות ללא מנגינות. ##id 0x2000 diff --git a/src/lang/hungarian.txt b/src/lang/hungarian.txt index 99dbfb82c8..f9f2e19a2b 100644 --- a/src/lang/hungarian.txt +++ b/src/lang/hungarian.txt @@ -732,10 +732,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}A 'Sajá STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Véletlen sorrendű lejátszás be/ki STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}A számkiválasztó ablak megjelenítése -STR_ERROR_NO_SONGS :{WHITE}Egy zeneszámokat nem tartalmazó zenei alapcsomag lett kiválasztva. A játékban nem lesz zene - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Zenei műsor kiválasztása STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Számlista STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}"{STRING}" Műsora @@ -1401,8 +1398,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Talaj színe a STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Zöld STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Sötétzöld STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Sötétkék -STR_CONFIG_SETTING_REVERSE_SCROLLING :Inverz görgetési irány: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :A térkép jobb gombbal történő görgetésének viselkedése. Kikapcsolva az egér mozgatja a kamerát. Bekapcsolva az egér a térképet mozgatja STR_CONFIG_SETTING_SMOOTH_SCROLLING :Finomított nézőpont-görgetés: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Beállítható, hogy a fő nézet hogyan mozogjon egy adott pozícióra a térképre kattintáskor ha egy adott objektumra történik mozgás. Bekapcsolva a nézet egyenletesen mozog, kikapcsolva közvetlenül a kijelölt helyre ugrik STR_CONFIG_SETTING_MEASURE_TOOLTIP :Területinformációk mutatása építési eszközök használatakor: {STRING} @@ -1434,8 +1429,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Parancs+Kattint STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+kattintás STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Kikapcsolva -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Bal gombos térképmozgatás: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Bal egérgombbal történő térképmozgatás engedélyezése. Különösen hasznos érintőképernyős mozgatás használata esetén STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Ablakok bezárása jobb gombbal: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :A jobb gombbal való kattintás az ablak területén bezárja az ablakot. Ez a beállítás kikapcsolja a segédletek jobb gombbal való megjelenítését! @@ -2757,6 +2750,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Eredeti STR_ABOUT_VERSION :{BLACK}OpenTTD {REV} verzió STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2018 Az OpenTTD csapat +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Játék mentése STR_SAVELOAD_LOAD_CAPTION :{WHITE}Játék betöltése @@ -3048,8 +3048,6 @@ STR_TOWN_POPULATION :{BLACK}Világn STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Város) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Lakosság: {ORANGE}{COMMA}{BLACK} Házak: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Utasok az előző hónapban: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Levélcsomagok az előző hónapban: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}A város növekedéséhez szükséges rakomány: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} szükséges STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} szükséges télen @@ -4288,7 +4286,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Túl sok STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Túl sok vasútállomás-rész STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Túl sok buszmegálló STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Túl sok a teherautó-rakodóhely -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Túl közel van egy másik állomáshoz/rakodóhelyhez STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Túl közel van egy másik kikötőhöz STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Túl közel van egy másik repülőtérhez STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Nem nevezheted át az állomást... diff --git a/src/lang/icelandic.txt b/src/lang/icelandic.txt index 77e9c09660..31c6ff796b 100644 --- a/src/lang/icelandic.txt +++ b/src/lang/icelandic.txt @@ -647,10 +647,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Velja 'S STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Kveikja/slökkva á stokkun STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Sýna lagalista -STR_ERROR_NO_SONGS :{WHITE}Tómur lagalisti hefur verið valinn. Engin lög verða spiluð - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Lagalistar STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Laganúmer STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Listi - '{STRING}' @@ -1273,8 +1270,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Litur á landsl STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Grænn STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Dökkgrænn STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Fjólublátt -STR_CONFIG_SETTING_REVERSE_SCROLLING :Færa sjónarhorn í öfuga átt miðað við mús: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Hegðun þegar sjónarhornið er fært með hægri músartakkanum. Þegar stillingin er óvirk færir músin myndavélina. Þegar stillingin er virk færir músin sjónarhornið STR_CONFIG_SETTING_SMOOTH_SCROLLING :Mjúkt skrun í skjágluggum: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Stýrir hvernig aðalsjónarhornið færist á ákveðna staði þegar smellt er á þá á litla kortinu eða þegar ákveðinn hlutur er valin á kortinu. Ef stillingin er virk færist aðalsjónarhornið rólega, ef stillingin er óvirk fer aðalsjónarhornið beint á ákveðna staðinn STR_CONFIG_SETTING_MEASURE_TOOLTIP :Sýna mælingar þegar verið er að byggja og breyta landslagi: {STRING} @@ -1306,8 +1301,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command+smella STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+smella STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Af -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Skrun með hægri músarhnappi: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Virkja að hægt sé að færa sjónarhornið með því að færa það með vinstri músar takkanum. Þetta er sérstaklega gott þegar notast er við snerti-skjá til að færa sjónarhornið STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES :Nota dagsetningar á {STRING} formi fyrir vistaða leiki. @@ -2538,6 +2531,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Upphafle STR_ABOUT_VERSION :{BLACK}OpenTTD útgáfa {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2018 OpenTTD hópurinn +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Vista leik STR_SAVELOAD_LOAD_CAPTION :{WHITE}Opna leik @@ -2808,8 +2808,6 @@ STR_TOWN_POPULATION :{BLACK}Heildar STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Borg) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Íbúafjöldi: {ORANGE}{COMMA}{BLACK} Hús: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Farþegar síðasta mánaðar: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Póstur síðasta mánaðar: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Nauðsynlegur farmur fyrir stækkun bæjarins: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} nauðsynlegt STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} nauðsynlegt á veturnar @@ -3968,7 +3966,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Of marga STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Of margir hlutar af lestarstöðvum STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Of margar strætisvagnastöðvar STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Of margar vörubílastöðvar -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Of nálægt annarri stöð/lestunarsvæði STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Of nálægt annarri bryggju STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Of nálægt öðrum flugvelli STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Get ekki endurnefnt stöð... diff --git a/src/lang/indonesian.txt b/src/lang/indonesian.txt index 36ead125af..f0d8efc7a8 100644 --- a/src/lang/indonesian.txt +++ b/src/lang/indonesian.txt @@ -650,6 +650,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}Tidak ada musik yang tersedia STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Track STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Titel @@ -669,14 +670,13 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Pilih 'B STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Acak/Urut program STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Tampilkan jendela pemilihan judul musik -STR_ERROR_NO_SONGS :{WHITE}Set Musik tanpa lagu telah dipilih. Tidak ada lagu yang akan dimainkan. - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Pilihan program Musik +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Program Musik - '{STRING}' STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Daftar rel STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Program - '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Kosong +STR_PLAYLIST_CHANGE_SET :{BLACK}Gantikan set STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Hapus program saat ini (hanya Bebas 1 atau Bebas 2) STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Klik pada musik track untuk menambah pada program sekarang (hanya Bebas 1 atau Bebas 2) STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Klik pada track musik untuk menghapusnya dari program saat ini. (Bebas 1 atau Bebas 2 saja) @@ -813,6 +813,7 @@ STR_NEWS_MERGER_TAKEOVER_TITLE :{BIG_FONT}{BLAC STR_PRESIDENT_NAME_MANAGER :{BLACK}{PRESIDENT_NAME}{}(Pimpinan) STR_NEWS_NEW_TOWN :{BLACK}{BIG_FONT}{STRING} menjadi sponsor pembangunan kota baru {TOWN}! +STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK}{BIG_FONT}Kota baru yang bernama {TOWN} baru dibuatkan! STR_NEWS_INDUSTRY_CONSTRUCTION :{BIG_FONT}{BLACK}Ada pembangunan {STRING} baru di dekat {TOWN}! STR_NEWS_INDUSTRY_PLANTED :{BIG_FONT}{BLACK}{STRING} baru sedang ditanam di dekat {TOWN}! @@ -898,7 +899,7 @@ STR_GAME_OPTIONS_CURRENCY_JPY :Yen Jepang (JPY STR_GAME_OPTIONS_CURRENCY_ATS :Shilling Austria (ATS) STR_GAME_OPTIONS_CURRENCY_BEF :Franc Belgia (BEF) STR_GAME_OPTIONS_CURRENCY_CHF :Franc Swiss (CHF) -STR_GAME_OPTIONS_CURRENCY_CZK :Koruna Czech (CZK) +STR_GAME_OPTIONS_CURRENCY_CZK :Koruna Ceko (CZK) STR_GAME_OPTIONS_CURRENCY_DEM :Deutschmark (DEM) STR_GAME_OPTIONS_CURRENCY_DKK :Krone Denmark (DKK) STR_GAME_OPTIONS_CURRENCY_ESP :Peseta Spanyol (ESP) @@ -912,7 +913,7 @@ STR_GAME_OPTIONS_CURRENCY_NLG :Dutch Guilder ( STR_GAME_OPTIONS_CURRENCY_NOK :Krone Norwegia (NOK) STR_GAME_OPTIONS_CURRENCY_PLN :Zloty Polandia (PLN) STR_GAME_OPTIONS_CURRENCY_RON :Leu Romania (RON) -STR_GAME_OPTIONS_CURRENCY_RUR :Rubles Rusia (RUR) +STR_GAME_OPTIONS_CURRENCY_RUR :Rubel Rusia (RUR) STR_GAME_OPTIONS_CURRENCY_SIT :Tolar Slovenia (SIT) STR_GAME_OPTIONS_CURRENCY_SEK :Krona Swedia (SEK) STR_GAME_OPTIONS_CURRENCY_TRY :Lira Turki (TRY) @@ -925,6 +926,7 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :Rand Afrika Sel STR_GAME_OPTIONS_CURRENCY_CUSTOM :Atur sendiri... STR_GAME_OPTIONS_CURRENCY_GEL :Lari Georgia (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :Rial Iran (IRR) +STR_GAME_OPTIONS_CURRENCY_RUB :Rubel Rusia Baru (RUB) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Kendaraan jalan raya @@ -941,7 +943,7 @@ STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Perancis STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Jerman STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Inggris (Tambahan) STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Amerika-Latin -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Silly +STR_GAME_OPTIONS_TOWN_NAME_SILLY :Lucu STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Swedia STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Belanda STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finlandia @@ -951,7 +953,7 @@ STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norwegia STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Hungaria STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austria STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Romania -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Czechnya +STR_GAME_OPTIONS_TOWN_NAME_CZECH :Ceko STR_GAME_OPTIONS_TOWN_NAME_SWISS :Swiss STR_GAME_OPTIONS_TOWN_NAME_DANISH :Denmark STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turki @@ -1337,8 +1339,10 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Warna daratan d STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Hijau STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Hijau Gelap STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Violet -STR_CONFIG_SETTING_REVERSE_SCROLLING :Berbalik Arah: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Untuk menggeser peta berlawanan arah dengan klik kanan. Ketika dimatikan, mouse menggeser kamera. Ketika dinyalakan, mouse menggeser peta +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Kelakuan waktu menggerakkan peta +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Gerakan viewport memakai tombol kanan tetikus, posisi tetikus terkunci +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Gerakan peta memakai tombol kanan tetikus, posisi tetikus terkunci +STR_CONFIG_SETTING_SCROLLMODE_RMB :Gerakan peta memakai tombol kanan tetikus STR_CONFIG_SETTING_SMOOTH_SCROLLING :Pergeseran pandangan viewport secara halus: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Menyetel bagaimana tampilan utama menggeser posisi di peta kecil. Jika dinyalakan, peta akan bergeser secara halus. Jika dimatikan, peta langsung menuju tempat yang di klik STR_CONFIG_SETTING_MEASURE_TOOLTIP :Tampilkan ukuran ketika menggunakan alat pembangun: {STRING} @@ -1370,8 +1374,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Perintah-klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Kontrol-klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Non-aktifkan -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Geser dgn klik-kiri: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Aktifkan penggeseran peta dengan menyeret menggunakan tombol kiri mouse. Hal ini sangat berguna apabila menggunakan layar sentuh. STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Tutup jendela dengan klik kanan: {STRING} STR_CONFIG_SETTING_AUTOSAVE :Simpan otomatis: {STRING} @@ -1989,7 +1991,7 @@ STR_NETWORK_LANG_FRENCH :Perancis STR_NETWORK_LANG_BRAZILIAN :Brazil STR_NETWORK_LANG_BULGARIAN :Bulgaria STR_NETWORK_LANG_CHINESE :China -STR_NETWORK_LANG_CZECH :Czech +STR_NETWORK_LANG_CZECH :Ceko STR_NETWORK_LANG_DANISH :Denmark STR_NETWORK_LANG_DUTCH :Belanda STR_NETWORK_LANG_ESPERANTO :Esperanto @@ -2004,7 +2006,7 @@ STR_NETWORK_LANG_NORWEGIAN :Norwegia STR_NETWORK_LANG_POLISH :Polandia STR_NETWORK_LANG_PORTUGUESE :Portugis STR_NETWORK_LANG_ROMANIAN :Rumania -STR_NETWORK_LANG_RUSSIAN :Russia +STR_NETWORK_LANG_RUSSIAN :Rusia STR_NETWORK_LANG_SLOVAK :Slovakia STR_NETWORK_LANG_SLOVENIAN :Slovenia STR_NETWORK_LANG_SPANISH :Spanyol @@ -2283,6 +2285,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Legenda STR_LINKGRAPH_LEGEND_ALL :{BLACK}Semua STR_LINKGRAPH_LEGEND_NONE :{BLACK}Tidak ada STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Pilih perusahaan yang akan ditampilkan +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}tak terpakai @@ -2691,6 +2694,38 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Hak Cipt STR_ABOUT_VERSION :{BLACK}OpenTTD versi {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 Tim OpenTTD +# Framerate display window +STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) +STR_FRAMERATE_RATE_GAMELOOP :{WHITE}Rata simulasi: {STRING} +STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Beberapa cepat permainan lagi berjalan, dibanding dengan kecepatan diharapkan memakai rata simulasi biasa. +STR_FRAMERATE_CURRENT :{WHITE}Sekarang +STR_FRAMERATE_DATA_POINTS :{WHITE}Data tergantung oleh ukuran {COMMA} +STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL}{WHITE} ms +STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL}{WHITE} ms +STR_FRAMERATE_MS_BAD :{RED}{DECIMAL}{WHITE} ms +STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms +STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s +############ Leave those lines in this order!! +STR_FRAMERATE_GL_ECONOMY :{WHITE} Penanganan kargo: +STR_FRAMERATE_GL_TRAINS :{WHITE} Titik kereta: +STR_FRAMERATE_GL_ROADVEHS :{WHITE} Titik kendaraan: +STR_FRAMERATE_GL_SHIPS :{WHITE} Titik kapal: +STR_FRAMERATE_GL_AIRCRAFT :{WHITE} Titik pesawat: +STR_FRAMERATE_GL_LANDSCAPE :{WHITE} Titik dunia: +STR_FRAMERATE_DRAWING_VIEWPORTS :{WHITE} Viewport dunia: +STR_FRAMERATE_SOUND :{WHITE}Mixing suara: +############ End of leave-in-this-order +############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_GL_ECONOMY :Penanganan kargo +STR_FRAMETIME_CAPTION_GL_TRAINS :Titik kereta +STR_FRAMETIME_CAPTION_GL_ROADVEHS :Titik kendaraan +STR_FRAMETIME_CAPTION_GL_SHIPS :Titik kapal +STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Titik pesawat +STR_FRAMETIME_CAPTION_GL_LANDSCAPE :Titik dunia +STR_FRAMETIME_CAPTION_SOUND :Mixing suara +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Simpan Permainan STR_SAVELOAD_LOAD_CAPTION :{WHITE}Buka Permainan @@ -2978,8 +3013,7 @@ STR_TOWN_POPULATION :{BLACK}Populasi STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (City) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Populasi: {ORANGE}{COMMA}{BLACK} Rumah: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Penumpang bulan lalu: {ORANGE}{COMMA}{BLACK} maks: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Surat bulan lalu: {ORANGE}{COMMA}{BLACK} maks: {ORANGE}{COMMA} +STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} bulan lalu: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Kargo untuk pertumbuhan kota: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{RED} Butuh {ORANGE}{STRING} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} dibutuhkan saat musim dingin @@ -3290,6 +3324,8 @@ STR_INDUSTRY_VIEW_REQUIRES_CARGO_CARGO :{BLACK}Membutuh STR_INDUSTRY_VIEW_REQUIRES_CARGO_CARGO_CARGO :{BLACK}Membutuhkan: {YELLOW}{STRING}{STRING}, {STRING}{STRING}, {STRING}{STRING} ############ range for requires ends +STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Membutuhkan: +STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} menunggu{STRING} ############ range for produces starts STR_INDUSTRY_VIEW_PRODUCES_CARGO :{BLACK}Menghasilkan: {YELLOW}{STRING}{STRING} @@ -3359,6 +3395,9 @@ STR_GROUP_REMOVE_ALL_VEHICLES :Jual semua STR_GROUP_RENAME_CAPTION :{BLACK}Ubah nama kelompok STR_GROUP_PROFIT_THIS_YEAR :Keuntungan tahun ini: +STR_GROUP_PROFIT_LAST_YEAR :Keuntungan tahun lalu: +STR_GROUP_OCCUPANCY :Penggunaan sekarang: +STR_GROUP_OCCUPANCY_VALUE :{NUM}% # Build vehicle window STR_BUY_VEHICLE_TRAIN_RAIL_CAPTION :Kereta Baru @@ -3366,7 +3405,7 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Kereta listrik STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Monorel Baru STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Maglev Baru -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Semua Kereta +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Kereta Baru STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Kendaraan Baru STR_BUY_VEHICLE_SHIP_CAPTION :Kapal Baru STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Buat Pesawat @@ -3391,6 +3430,7 @@ STR_PURCHASE_INFO_ALL_TYPES :Semua jenis kar STR_PURCHASE_INFO_ALL_BUT :Semua tapi tidak untuk {CARGO_LIST} STR_PURCHASE_INFO_MAX_TE :{BLACK}Traksi Maks.: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Jangkauan: {GOLD}{COMMA} kotak +STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Jenis pesawat: {GOLD}{STRING} STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Daftar pilihan kereta - klik pada kereta untuk menampilkan informasi STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Daftar pilihan kendaraan - klik pada kendaraan untuk menampilkan informasi @@ -3525,6 +3565,10 @@ STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :lokomotif magle STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Biaya: {CURRENCY_LONG} Berat: {WEIGHT_SHORT}{}Kecepatan: {VELOCITY} Daya: {POWER}{}Biaya ops.: {CURRENCY_LONG}/thn{}Kapasitas: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Biaya: {CURRENCY_LONG} Berat: {WEIGHT_SHORT}{}Kecepatan: {VELOCITY} Power: {POWER} Max. T.E.: {6:FORCE}{}Biaya Operasional: {4:CURRENCY_LONG}/yr{}Kapasitas: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Biaya: {CURRENCY_LONG} Kec. Max: {VELOCITY}{}Kapasitas: {CARGO_LONG}{}Bea Berjalan: {CURRENCY_LONG}/thn +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Biaya: {CURRENCY_LONG} Kec. Max.: {VELOCITY}{}Jenis pesawat: {STRING}{}Kapasitas: {CARGO_LONG}, {CARGO_LONG}{}Biaya operasi: {CURRENCY_LONG}/thn +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Biaya: {CURRENCY_LONG} Kec. Max.: {VELOCITY}{}Jenis pesawat: {STRING}{}Kapasitas: {CARGO_LONG}{}Biaya operasi: {CURRENCY_LONG}/thn +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_CAP_RUNCOST :{BLACK}Biaya: {CURRENCY_LONG} Kec. Max.: {VELOCITY}{}Jenis pesawat: {STRING} Jangkauan: {COMMA} ubin{}Kapasitas: {CARGO_LONG}, {CARGO_LONG}{}Biaya Operasi: {CURRENCY_LONG}/thn +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_RUNCOST :{BLACK}Biaya: {CURRENCY_LONG} Kec. Max.: {VELOCITY}{}Jenis pesawat: {STRING} Jangkauan: {COMMA} ubin{}Kapasitas: {CARGO_LONG}{}Biaya operasi: {CURRENCY_LONG}/thn # Autoreplace window STR_REPLACE_VEHICLES_WHITE :{WHITE}Ganti {STRING} - {STRING} @@ -3554,6 +3598,7 @@ STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Tekan un STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Pindah tampilan penggantian lokomitif atau gerbong STR_REPLACE_ENGINES :Lokomotif STR_REPLACE_WAGONS :Gerbong +STR_REPLACE_ALL_RAILTYPE :Semua kereta STR_REPLACE_HELP_RAILTYPE :{BLACK}Pilih jenis kereta yang anda inginkan untuk diganti STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Menampilkan kendaraan terpilih di sisi kiri yang akan diganti, jika ada @@ -3647,6 +3692,7 @@ STR_VEHICLE_INFO_AGE_RED :{RED}{COMMA} ta STR_VEHICLE_INFO_MAX_SPEED :{BLACK}Kec. Max: {LTBLUE}{VELOCITY} STR_VEHICLE_INFO_MAX_SPEED_TYPE :{BLACK}Kecepatan Maks.: {LTBLUE}{VELOCITY} {BLACK}Jenis pesawat: {LTBLUE}{STRING} +STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE :{BLACK}Kec. max.: {LTBLUE}{VELOCITY} {BLACK}Jenis pesawat: {LTBLUE}{STRING} {BLACK}Jangkauan: {LTBLUE}{COMMA} ubin STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Berat: {LTBLUE}{WEIGHT_SHORT} {BLACK}Tenaga: {LTBLUE}{POWER}{BLACK} Kec. Max: {LTBLUE}{VELOCITY} STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Berat: {LTBLUE}{WEIGHT_SHORT} {BLACK}Tenaga: {LTBLUE}{POWER}{BLACK} Kec. Max: {LTBLUE}{VELOCITY} {BLACK}Max. T.E.: {LTBLUE}{FORCE} @@ -4205,7 +4251,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Terlalu STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Terlalu banyak bag. stasiun STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Terlalu banyak pemberhentian Bus STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Terlalu banyak terminal truk -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Terlalu dekat dengan stasiun/area bongkar muat lainnya STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Terlalu dekat dengan dok/galangan kapal lainnya STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Terlalu dekat dengan bandara lainnya STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Tidak dapat mengganti nama stasiun... @@ -4213,6 +4258,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... jala STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... menghadap pada arah yang salah STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... terminal lintas-lalu tak bisa memiliki sudut STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... terminal lintas-lalu tak bisa memiliki simpangan +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... jalannya satu arah atau terhalang # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Tidak dapat menghapus bagian dari stasiun... @@ -4281,7 +4327,7 @@ STR_ERROR_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Kombinas STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Sinyal harus dihancurkan dulu STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Tidak tersedia rel yang sesuai STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Harus membongkar rel terlebih dahulu -STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Jalan satu arah atau ada yang menghalangi +STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Jalannya satu arah atau terhalang STR_ERROR_CROSSING_DISALLOWED :{WHITE}Perlintasan tingkat tidak diperbolehkan pada tipe rel ini STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Tidak dapat membangun sinyal disini STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Tidak dapat membangun jalur rel disini @@ -4464,6 +4510,8 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Efek suara oris STR_BASESOUNDS_WIN_DESCRIPTION :Efek suara orisinil Transport Tycoon Deluxe versi Windows. STR_BASESOUNDS_NONE_DESCRIPTION :Paket efek suara tanpa suara apapun. STR_BASEMUSIC_WIN_DESCRIPTION :Musik pengiring orisinil Transport Tycoon Deluxe versi Windows. +STR_BASEMUSIC_DOS_DESCRIPTION :Musik orisinil Transport Tycoon Deluxe versi DOS. +STR_BASEMUSIC_TTO_DESCRIPTION :Musik orisinil Transport Tycoon (Orisinil/Editor Dunia) versi DOS. STR_BASEMUSIC_NONE_DESCRIPTION :Paket musik tanpa musik sungguhan. ##id 0x2000 diff --git a/src/lang/irish.txt b/src/lang/irish.txt index 6c2cb21375..0ea266d541 100644 --- a/src/lang/irish.txt +++ b/src/lang/irish.txt @@ -669,10 +669,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Roghnaig STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Scoránaigh ord randamach clár air/as STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Taispeáin an fhuinneogh chun rianta ceoil a roghnú -STR_ERROR_NO_SONGS :{WHITE}Roghnaíodh sraith ceoil gan aon amhrán ann. Ní sheinnfear aon amhrán - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Clár Ceoil a Roghnú STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Innéacs na Rianta STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Clár - '{STRING}' @@ -1337,8 +1334,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Dath an tír-ra STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Uaine STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Ciaruaine STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Corcairghorm -STR_CONFIG_SETTING_REVERSE_SCROLLING :Aisiompaigh an treo scrollaithe: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :An méid a tharlaíonn agus an léarscáil á scrollú leis an gcnaipe luchóige deas. Má bhíonn sé díchumasaithe, bogann an luchóg leis an gceamara. Má bhíonn sé cumasaithe, bogann an luchóg an léarscáil STR_CONFIG_SETTING_SMOOTH_SCROLLING :Scrollú mín do na fuinneoga amhairc: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Roghnaigh an chaoi a scrollóidh an príomhamharc chuig suíomh ar leith má chliceálann tú ar an léarscáil bheag nó má thugann tú ordú scrollú chuig oibiacht ar leith ar an léarscáil. Má tá sé cumasaithe, scrollóidh an fhuinneog amhairc go mín, má tá sé díchumasaithe léimfidh sé go díreach chuig an suíomh sin. STR_CONFIG_SETTING_MEASURE_TOOLTIP :Taispeáin leid uirlise tomhais agu uirlisí tógála áirithe in úsáid: {STRING} @@ -1370,8 +1365,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Ordú+Cliceáil STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+Cliceáil STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :As -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Scrollú le cléchliceáil: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Cumasaigh scrollú an léarscáil trí bheith ag tarraingt le cnaipe clé na luiche. Tá sé seo thar a bheith úsáideach don scrollú nuair atá scáileán tadhaill á úsáid STR_CONFIG_SETTING_AUTOSAVE :Uathshábháil: {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :Roghnaigh an t-eatramh idir uathshábhálacha cluichí @@ -2689,6 +2682,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Cóipche STR_ABOUT_VERSION :{BLACK}OpenTTD leagan {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 An fhoireann OpenTTD +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Sábháil an Cluiche STR_SAVELOAD_LOAD_CAPTION :{WHITE}Lódáil Cluiche @@ -2980,8 +2980,6 @@ STR_TOWN_POPULATION :{BLACK}Daonra d STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Cathair) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Daonra: {ORANGE}{COMMA}{BLACK} Tithe: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Paisinéirí an mhí seo caite: {ORANGE}{COMMA}{BLACK} Uasmhéid: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Post an mhí seo caite: {ORANGE}{COMMA}{BLACK} uasmhéid: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Lastas atá ag teastáil le go bhfásfaidh an baile: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} ag teastáil STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} ag teastáil sa Gheimhreadh @@ -4205,7 +4203,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}An iomar STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}An iomarca codanna stáisiún iarnróid STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}An iomarca stadanna bus STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}An iomarca stáisiúin leoraithe -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Roghearr do stáisiún/limistéar lódála eile STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Roghearr do dug eile STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Roghearr d'aerfort eile STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Ní féidir an stáisiún a athainmniú... diff --git a/src/lang/italian.txt b/src/lang/italian.txt index e2d5ffa49a..53a3d342d0 100644 --- a/src/lang/italian.txt +++ b/src/lang/italian.txt @@ -477,6 +477,7 @@ STR_ABOUT_MENU_SCREENSHOT :Screenshot STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Screenshot con zoom massimo STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Screenshot con zoom predefinito STR_ABOUT_MENU_GIANT_SCREENSHOT :Screenshot intera mappa +STR_ABOUT_MENU_SHOW_FRAMERATE :Mostra frame rate STR_ABOUT_MENU_ABOUT_OPENTTD :Informazioni su 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Strumento allineamento sprite STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Attiva/disattiva bounding box @@ -652,6 +653,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}Musica non disponibile STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Brano STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Titolo @@ -671,15 +673,15 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Selezion STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Attiva/disattiva la riproduzione in ordine casuale STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Mostra la finestra di selezione dei brani musicali -STR_ERROR_NO_SONGS :{WHITE}È stato selezionato un pacchetto musicale senza brani. Non sarà possibile avviare la musica. - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Selezione programma musicale +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Programma musicale - '{STRING}' STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Indice brani STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programma - '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Elimina +STR_PLAYLIST_CHANGE_SET :{BLACK}Cambia pacchetto STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Elimina il programma corrente (solo Personale1 e Personale2) +STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Seleziona un altro pacchetto musicale installato STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Fare clic su un brano per aggiungerlo al programma corrente (solo Personale1 o Personale2) STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Fare clic su un brano per rimuoverlo dal programma corrente (solo Personale1 o Personale2) @@ -815,6 +817,7 @@ STR_NEWS_MERGER_TAKEOVER_TITLE :{BIG_FONT}{BLAC STR_PRESIDENT_NAME_MANAGER :{BLACK}{PRESIDENT_NAME}{}(Presidente) STR_NEWS_NEW_TOWN :{BLACK}{BIG_FONT}La {STRING} finanzia la costruzione della nuova cittadina di {TOWN}! +STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK}{BIG_FONT}È stata fondata una nuova città chiamata {TOWN}! STR_NEWS_INDUSTRY_CONSTRUCTION :{BIG_FONT}{BLACK}Nuov{G o o a} {STRING} in costruzione vicino a {TOWN}! STR_NEWS_INDUSTRY_PLANTED :{BIG_FONT}{BLACK}Nuov{G 0 o o a} {STRING} piantat{G 0 o o a} vicino a {TOWN}! @@ -882,9 +885,9 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC # Extra view window STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Mini visuale {COMMA} -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Copia nella mini visuale +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Cambia mini visuale STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Copia la posizione della visuale principale in questa mini visuale -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Copia dalla mini visuale +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Cambia vis. principale STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Copia la posizione di questa mini visuale nella visuale principale # Game options window @@ -927,6 +930,7 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :Rand sudafrican STR_GAME_OPTIONS_CURRENCY_CUSTOM :Personalizzata... STR_GAME_OPTIONS_CURRENCY_GEL :Lari georgiano (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :Rial iraniano (IRR) +STR_GAME_OPTIONS_CURRENCY_RUB :Nuovo rublo russo (RUB) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Automezzi @@ -1361,8 +1365,12 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Colore del terr STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Verde STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Verde scuro STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Viola -STR_CONFIG_SETTING_REVERSE_SCROLLING :Inverti direzione di scorrimento della mappa: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Comportamento dello scorrimento della mappa con il tasto destro del mouse. Se disabilitata, il mouse muove l'inquadratura. Se abilitata, il mouse muove la mappa +STR_CONFIG_SETTING_SCROLLMODE :Scorrimento delle visuali: {STRING} +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Comportamento dello scorrimento della mappa +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Muovi visuale col pulsante destro, puntatore bloccato +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Muovi mappa col pulsante destro, puntatore bloccato +STR_CONFIG_SETTING_SCROLLMODE_RMB :Muovi mappa col pulsante destro +STR_CONFIG_SETTING_SCROLLMODE_LMB :Muovi mappa col pulsante sinistro STR_CONFIG_SETTING_SMOOTH_SCROLLING :Scorrimento morbido delle visuali: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Controlla il modo in cui la visuale principale scorre verso una specifica posizione quando si fa clic sulla minimappa o si ordina di visualizzare un oggetto specifico sulla mappa. Se abilitata, la visuale scorre in modo morbido. Se disabilitata, salta direttamente al punto prescelto STR_CONFIG_SETTING_MEASURE_TOOLTIP :Mostra un tooltip di misura durante la costruzione: {STRING} @@ -1394,8 +1402,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :COMANDO+clic STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :CTRL+clic STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Nessuna -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Scorrimento con clic sinistro: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Abilita lo scorrimento della mappa trascinandola con il pulsante sinistro del mouse. Questa impostazione è utile quando si utilizza un touch-screen STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Chiudi finestra con clic destro: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Consente di chiudere una finestra facendo clic col pulsante destro al suo interno. Disabilita i suggerimenti attivati al clic col pulsante destro! @@ -2311,6 +2317,7 @@ STR_LINKGRAPH_LEGEND_NONE :{BLACK}Nessuno STR_LINKGRAPH_LEGEND_NONE.ms :{BLACK}Nessuno STR_LINKGRAPH_LEGEND_NONE.fs :{BLACK}Nessuna STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Seleziona le compagnie da mostrare +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}inutilizzata @@ -2723,6 +2730,56 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Copyrigh STR_ABOUT_VERSION :{BLACK}OpenTTD versione {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 Il team OpenTTD +# Framerate display window +STR_FRAMERATE_CAPTION :{WHITE}Frame rate +STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) +STR_FRAMERATE_RATE_GAMELOOP :{BLACK}Velocità simulazione: {STRING} +STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Numero di cicli di simulazione della partita in un secondo +STR_FRAMERATE_RATE_BLITTER :{BLACK}Frame rate grafica: {STRING} +STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Numero di fotogrammi video renderizzati in un secondo +STR_FRAMERATE_SPEED_FACTOR :{BLACK}Fattore di velocità corrente della partita: {DECIMAL}x +STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Prestazioni correnti della partita, confrontate con le prestazioni attese alla velocità di giorno normale. +STR_FRAMERATE_CURRENT :{WHITE}Corrente +STR_FRAMERATE_AVERAGE :{WHITE}Media +STR_FRAMERATE_DATA_POINTS :{BLACK}Dati basati su {COMMA} misurazioni +STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms +STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms +STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} ms +STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} frame/s +STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} frame/s +STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} frame/s +STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms +STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s +############ Leave those lines in this order!! +STR_FRAMERATE_GAMELOOP :{BLACK}Totale ciclo simulazione: +STR_FRAMERATE_GL_ECONOMY :{BLACK} Gestione carichi: +STR_FRAMERATE_GL_TRAINS :{BLACK} Aggiornamento treni: +STR_FRAMERATE_GL_ROADVEHS :{BLACK} Aggiornamento automezzi: +STR_FRAMERATE_GL_SHIPS :{BLACK} Aggiornamento navi: +STR_FRAMERATE_GL_AIRCRAFT :{BLACK} Aggiornamento aeromobili: +STR_FRAMERATE_GL_LANDSCAPE :{BLACK} Aggiornamento mondo: +STR_FRAMERATE_GL_LINKGRAPH :{BLACK} Ritardo grafo di distribuzione: +STR_FRAMERATE_DRAWING :{BLACK}Renderizzazione grafica: +STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK} Visuali mondo: +STR_FRAMERATE_VIDEO :{BLACK}Output video: +STR_FRAMERATE_SOUND :{BLACK}Missaggio suoni: +############ End of leave-in-this-order +############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_GAMELOOP :Ciclo simulazione +STR_FRAMETIME_CAPTION_GL_ECONOMY :Gestione carichi +STR_FRAMETIME_CAPTION_GL_TRAINS :Aggiornamento treni +STR_FRAMETIME_CAPTION_GL_ROADVEHS :Aggiornamento automezzi +STR_FRAMETIME_CAPTION_GL_SHIPS :Aggiornamento navi +STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Aggiornamento aeromobili +STR_FRAMETIME_CAPTION_GL_LANDSCAPE :Aggiornamento mondo +STR_FRAMETIME_CAPTION_GL_LINKGRAPH :Ritardo grafo di distribuzione +STR_FRAMETIME_CAPTION_DRAWING :Renderizzazione grafica +STR_FRAMETIME_CAPTION_DRAWING_VIEWPORTS :Renderizzazione visuali mondo +STR_FRAMETIME_CAPTION_VIDEO :Output video +STR_FRAMETIME_CAPTION_SOUND :Missaggio suoni +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Salva partita STR_SAVELOAD_LOAD_CAPTION :{WHITE}Carica partita @@ -2745,6 +2802,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Dettagli STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Informazioni non disponibili STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} +STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtro: STR_SAVELOAD_OSKTITLE :{BLACK}Inserire un nome per il salvataggio @@ -2943,6 +3001,8 @@ STR_NEWGRF_ERROR_READ_BOUNDS :Lettura oltre l STR_NEWGRF_ERROR_GRM_FAILED :Risorsa GRF richiesta non disponibile (sprite {3:NUM}) STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING} è stato disabilitato da {STRING} STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Formato di layout dello sprite sconosciuto o non valido (sprite {3:NUM}) +STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG :Troppi elementi nella lista valori di una proprietà (sprite {3:NUM}, proprietà {4:HEX}) +STR_NEWGRF_ERROR_INDPROD_CALLBACK :Callback di produzione industria non valido (sprite {3:NUM}, "{1:STRING}") # NewGRF related 'general' warnings STR_NEWGRF_POPUP_CAUTION_CAPTION :{WHITE}Attenzione! @@ -3007,6 +3067,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Inserire STR_TOWN_DIRECTORY_CAPTION :{WHITE}Città STR_TOWN_DIRECTORY_NONE :{ORANGE}- Nessuna - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Metropoli){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Nomi delle città - fare clic su un nome per centrare la visuale principale sulla città. CTRL+clic la mostra in una mini visuale. STR_TOWN_POPULATION :{BLACK}Popolazione mondiale: {COMMA} @@ -3014,8 +3075,7 @@ STR_TOWN_POPULATION :{BLACK}Popolazi STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Metropoli) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Popolazione: {ORANGE}{COMMA}{BLACK} Case: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passeggeri il mese scorso: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Posta il mese scorso: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} +STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} il mese scorso: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Carichi richiesti per la crescita della città: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} richiest{G 0 o o a} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} richiest{G 0 o o a} in inverno @@ -4254,7 +4314,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Troppe s STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Stazione composta da troppe parti STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Troppe stazioni degli autobus STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Troppe aree di carico per camion -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Troppo vicino ad un'altra stazione/area di carico STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Troppo vicino ad un altro molo STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Troppo vicino ad un altro aeroporto STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Impossibile rinominare la stazione... @@ -4262,6 +4321,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... ques STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... strada rivolta nella direzione sbagliata STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... le fermate passanti non possono trovarsi in curva STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... le fermate passanti non possono avere raccordi +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... la strada è bloccata o a senso unico # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Impossibile rimuovere parte della stazione... @@ -4513,6 +4573,8 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Suoni originali STR_BASESOUNDS_WIN_DESCRIPTION :Suoni originali di Transport Tycoon Deluxe, edizione Windows. STR_BASESOUNDS_NONE_DESCRIPTION :Un pacchetto sonoro non contenente alcun suono. STR_BASEMUSIC_WIN_DESCRIPTION :Musica originale di Transport Tycoon Deluxe, edizione Windows. +STR_BASEMUSIC_DOS_DESCRIPTION :Musica originale di Transport Tycoon Deluxe, edizione DOS. +STR_BASEMUSIC_TTO_DESCRIPTION :Musica originale di Transport Tycoon (edizione Original/World). STR_BASEMUSIC_NONE_DESCRIPTION :Un pacchetto musicale non contenente alcuna musica. ##id 0x2000 diff --git a/src/lang/japanese.txt b/src/lang/japanese.txt index 8e7f0c486d..c1b2fb1e75 100644 --- a/src/lang/japanese.txt +++ b/src/lang/japanese.txt @@ -669,10 +669,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}プレ STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}プレイリストのシャッフルの有効/無効を切り替えます STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}曲選択のウィンドウを表示します -STR_ERROR_NO_SONGS :{WHITE}選択した音楽セットに曲がありません - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}プレイリストの選択 STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}楽曲索引 STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}プレイリスト - '{STRING}' @@ -1337,8 +1334,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :ミニマップ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :緑 STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :濃緑 STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :青紫 -STR_CONFIG_SETTING_REVERSE_SCROLLING :スクロール方面を反転: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :マウス右ボタンで地図をスクロールする時の挙動を設定します。無効にした場合はマウスはカメラを動かします(マウスの移動方向に移動します)。有効にした場合は地図を動かします(マウスの移動方向と逆に移動します) STR_CONFIG_SETTING_SMOOTH_SCROLLING :画面のスムーズスクロール: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :ミニマップでの移動や「現在位置に移動」などのコマンドを使用した際にメイン画面がどのように移動するかを設定します。有効にした場合はスムーズにスクロールして移動します。無効の場合は目的地に直接ジャンプします STR_CONFIG_SETTING_MEASURE_TOOLTIP :測定ツールチップ表示: {STRING} @@ -1370,8 +1365,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :コマンド+ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+クリック (Win) STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :切 -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :左ドラッグスクロール: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :有効にすると左ドラッグでマップのスクロールができるようになります。特にタッチスクリーンを利用しているときに便利です STR_CONFIG_SETTING_AUTOSAVE :オートセーブ: {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :オートセーブの間隔を設定します @@ -2690,6 +2683,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}オリ STR_ABOUT_VERSION :{BLACK}OpenTTD バージョン {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 The OpenTTD team +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}ゲームを保存 STR_SAVELOAD_LOAD_CAPTION :{WHITE}ゲームを開く @@ -2981,8 +2981,6 @@ STR_TOWN_POPULATION :{BLACK}地域 STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN}(市) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}人口: {ORANGE}{COMMA}人{BLACK} 建物: {ORANGE}{COMMA}戸 -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}旅客数(先月): {ORANGE}{COMMA}人{BLACK} 最大: {ORANGE}{COMMA}人 -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}郵便袋(先月): {ORANGE}{COMMA}袋{BLACK} 最大: {ORANGE}{COMMA}袋 STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}街の成長に必要な物資: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}が{RED}必要です STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}が{BLACK}冬に必要です @@ -4208,7 +4206,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}停留 STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}駅の部分が多すぎます STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}バス停が多すぎます STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}荷役所が多すぎます -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}他の停留施設に近すぎます STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}他の埠頭に近すぎます STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}他の空港に近すぎます STR_ERROR_CAN_T_RENAME_STATION :{WHITE}駅名を変更できません diff --git a/src/lang/korean.txt b/src/lang/korean.txt index b6dc29a099..ea66904cd8 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -476,6 +476,7 @@ STR_ABOUT_MENU_SCREENSHOT :스크린샷 STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :스크린샷 찍기 (지금 보고 있는 영역) STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :스크린샷 찍기 (창을 제외한 게임 화면만) STR_ABOUT_MENU_GIANT_SCREENSHOT :스크린샷 찍기 (지도 전체) +STR_ABOUT_MENU_SHOW_FRAMERATE :프레임레이트 보기 STR_ABOUT_MENU_ABOUT_OPENTTD :'OpenTTD'에 대해서 STR_ABOUT_MENU_SPRITE_ALIGNER :스프라이트 정렬도구 STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :박스 경계선 보기 전환 @@ -651,6 +652,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}사용 가능한 음악 없음 STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" STR_MUSIC_TRACK :{TINY_FONT}{BLACK}트랙 STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}제목 @@ -670,15 +672,15 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}'사용 STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}프로그램을 무작위 재생합니다. STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}배경 음악 트랙을 선택할 수 있는 창을 엽니다. -STR_ERROR_NO_SONGS :{WHITE}선택된 배경 음악 목록에 노래가 없습니다. 배경 음악이 재생 되지 않을 것입니다. - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}배경 음악 프로그램 선택 +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}음악 프로그램 - '{STRING}' STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}음악 목록 STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}프로그램 - '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}초기화 +STR_PLAYLIST_CHANGE_SET :{BLACK}세트 변경 STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}현재 배경 음악 프로그램을 초기화합니다. (사용자1, 사용자2에서만 선택 가능) +STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}배경 음악 세트를 이미 설치된 다른 세트로 변경합니다. STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}배경 음악 목록에 음악을 추가하려면 클릭하세요. (사용자1, 사용자2에서만 사용 가능) STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}배경 음악 목록에서 음악을 제거하려면 클릭하세요. (사용자1, 사용자2에서만 사용 가능) @@ -814,6 +816,7 @@ STR_NEWS_MERGER_TAKEOVER_TITLE :{BIG_FONT}{BLAC STR_PRESIDENT_NAME_MANAGER :{BLACK}{PRESIDENT_NAME}{}(사장) STR_NEWS_NEW_TOWN :{BLACK}{BIG_FONT}{STRING}은(는) 새로운 도시 {TOWN}을(를) 건설했습니다! +STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK}{BIG_FONT}{TOWN} - 새 도시가 생겼습니다! STR_NEWS_INDUSTRY_CONSTRUCTION :{BIG_FONT}{BLACK}{1:TOWN} 근처에 새로운 {0:STRING}{G 0 "이" "가"} 건설되고 있습니다! STR_NEWS_INDUSTRY_PLANTED :{BIG_FONT}{BLACK}새 {STRING}{G 0 "이" "가"} {TOWN} 근처에서 자라나고 있습니다! @@ -881,7 +884,7 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC # Extra view window STR_EXTRA_VIEW_PORT_TITLE :{WHITE}외부 화면 {COMMA} -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}외부 화면에 복사 +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}외부 화면으로 복사 STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}현재 장소를 외부 화면에 복사합니다. STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}이 장소로 이동 STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}외부 화면에 저장된 장소로 이동합니다. @@ -926,6 +929,7 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :남아프리카 STR_GAME_OPTIONS_CURRENCY_CUSTOM :사용자 설정... STR_GAME_OPTIONS_CURRENCY_GEL :그루지야 라리 (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :이란 리알 (IRR) +STR_GAME_OPTIONS_CURRENCY_RUB :신 러시아 루블 (RUB) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}차량 통행 방식 @@ -1003,7 +1007,7 @@ STR_GAME_OPTIONS_BASE_MUSIC_STATUS :{RED}{NUM}개 STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP :{BLACK}기본 배경 음악 세트에 대한 추가 정보를 봅니다. STR_ERROR_RESOLUTION_LIST_FAILED :{WHITE}지원되는 해상도 목록을 불러오는데 실패하였습니다. -STR_ERROR_FULLSCREEN_FAILED :{WHITE}풀스크린 모드 실패 +STR_ERROR_FULLSCREEN_FAILED :{WHITE}전체화면 모드 실패 # Custom currency window @@ -1265,7 +1269,7 @@ STR_CONFIG_SETTING_ORDER_REVIEW_HELPTEXT :이 설정을 STR_CONFIG_SETTING_ORDER_REVIEW_OFF :검사하지 않음 STR_CONFIG_SETTING_ORDER_REVIEW_EXDEPOT :정지한 차량을 제외하고 검사 STR_CONFIG_SETTING_ORDER_REVIEW_ON :모든 차량을 검사 -STR_CONFIG_SETTING_WARN_INCOME_LESS :차량의 수입이 적자일때 경고하기: {STRING} +STR_CONFIG_SETTING_WARN_INCOME_LESS :차량의 수입이 적자일 때 경고하기: {STRING} STR_CONFIG_SETTING_WARN_INCOME_LESS_HELPTEXT :이 설정을 켜면, 지난 해에 수익이 없는 차량이 있으면 뉴스 메시지로 알려줍니다. STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES :옛날 차량을 사라지지 않고 계속 만들 수 있게 함: {STRING} STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES_HELPTEXT :이 설정을 켜면, 오래된 차량 모델을 포함하여 모든 차량 모델을 도입 이후에 계속 사용할 수 있게 됩니다. @@ -1338,8 +1342,12 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :소형지도 STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :녹색 STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :어두운 녹색 STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :보라색 -STR_CONFIG_SETTING_REVERSE_SCROLLING :스크롤 방향 뒤집기: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :마우스 오른쪽 클릭으로 지도를 스크롤하는 방법을 선택합니다. 이 설정을을 끄면, 마우스 방향과 화면의 스크롤 방향이 같아집니다. 설정을 켜면, 마우스 방향과 화면의 스크롤 방향이 반대가 됩니다. +STR_CONFIG_SETTING_SCROLLMODE :외부 화면 스크롤 행동: {STRING} +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :지도를 스크롤 할 때의 행동을 선택합니다. +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :마우스 오른쪽 클릭으로 외부 화면 이동 (마우스 위치는 고정) +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :마우스 오른쪽 클릭으로 지도 이동 (마우스 위치는 고정) +STR_CONFIG_SETTING_SCROLLMODE_RMB :마우스 오른쪽 클릭으로 지도 이동 +STR_CONFIG_SETTING_SCROLLMODE_LMB :마우스 왼쪽 클릭으로 지도 이동 STR_CONFIG_SETTING_SMOOTH_SCROLLING :게임 화면을 이동시킬 때 부드럽게 이동: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :소형 지도를 클릭하여 특정 지역으로 스크롤되거나 지도 상의 특정 장소로 이동하는 경우에 주 화면이 어떻게 스크롤 되는지를 설정합니다. 이 설정을 켜면, 화면이 목표 지점까지 부드럽게 이동하고, 설정을 끄면 목표 지점으로 곧바로 넘어가게 됩니다. STR_CONFIG_SETTING_MEASURE_TOOLTIP :건설도구 사용시 거리 도움말 표시: {STRING} @@ -1352,7 +1360,7 @@ STR_CONFIG_SETTING_LIVERIES_ALL :모든 회사 STR_CONFIG_SETTING_PREFER_TEAMCHAT :엔터(ENTER) 키로 같은 팀끼리 채팅: {STRING} STR_CONFIG_SETTING_PREFER_TEAMCHAT_HELPTEXT :이 설정을 켜면, 멀티 플레이시 같은 회사 간의 채팅을 키 대신 키로 할 수 있게 됩니다. STR_CONFIG_SETTING_SCROLLWHEEL_SCROLLING :마우스 휠 동작: {STRING} -STR_CONFIG_SETTING_SCROLLWHEEL_SCROLLING_HELPTEXT :상하좌우로 회전 가능한 마우스 휠(2차원 마우스휠)로 지도를 스크롤할 수 있게 허용합니다. +STR_CONFIG_SETTING_SCROLLWHEEL_SCROLLING_HELPTEXT :상하좌우로 회전 가능한 마우스 휠(2차원 마우스 휠)로 지도를 스크롤할 수 있게 허용합니다. STR_CONFIG_SETTING_SCROLLWHEEL_ZOOM :화면 확대/축소 STR_CONFIG_SETTING_SCROLLWHEEL_SCROLL :지도 스크롤 STR_CONFIG_SETTING_SCROLLWHEEL_OFF :끄기 @@ -1371,8 +1379,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :커맨드 + 클 STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :CTRL + 클릭 STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :끄기 -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :마우스 왼쪽 버튼으로 스크롤: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :왼쪽 마우스 버튼을 드래그하여 지도를 스크롤 할 수 있도록 합니다. 터치 스크린 환경에서 이 설정을 켜면 매우 유용합니다. STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :오른쪽 클릭으로 창 닫기: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :창 내부를 오른쪽 클릭하여 창을 닫습니다. 오른쪽 클릭으로 도움말 표시 설정을 해제해야 합니다! @@ -2286,6 +2292,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}화물 STR_LINKGRAPH_LEGEND_ALL :{BLACK}모두 STR_LINKGRAPH_LEGEND_NONE :{BLACK}없음 STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}표시할 회사를 선택하십시오 +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}이용 없음 @@ -2694,6 +2701,56 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Original STR_ABOUT_VERSION :{BLACK}OpenTTD 버전 {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 OpenTTD 개발팀 +# Framerate display window +STR_FRAMERATE_CAPTION :{WHITE}프레임레이트 +STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) +STR_FRAMERATE_RATE_GAMELOOP :{BLACK}시뮬레이션 비율: {STRING} +STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}1초에 시뮬레이션하는 게임 틱 수입니다. +STR_FRAMERATE_RATE_BLITTER :{BLACK}그래픽 프레임레이트: {STRING} +STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}1초에 표현하는 비디오 프레임 수입니다. +STR_FRAMERATE_SPEED_FACTOR :{BLACK}현재 게임 속력 계수: {DECIMAL}x +STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}현재 게임이 일반적인 시뮬레이션 비율 속도에 비해 얼마나 빠르게 구동되고 있는지를 보여줍니다. +STR_FRAMERATE_CURRENT :{WHITE}현재 +STR_FRAMERATE_AVERAGE :{WHITE}평균 +STR_FRAMERATE_DATA_POINTS :{BLACK}{COMMA}개의 값을 기반으로 측정한 데이터 +STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL}{BLACK} ms +STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms +STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} ms +STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} 프레임/초 +STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} 프레임/초 +STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} 프레임/초 +STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms +STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA}초 +############ Leave those lines in this order!! +STR_FRAMERATE_GAMELOOP :{BLACK}총 게임 루프: +STR_FRAMERATE_GL_ECONOMY :{BLACK} 화물 처리: +STR_FRAMERATE_GL_TRAINS :{BLACK} 열차 틱: +STR_FRAMERATE_GL_ROADVEHS :{BLACK} 자동차 틱: +STR_FRAMERATE_GL_SHIPS :{BLACK} 선박 틱: +STR_FRAMERATE_GL_AIRCRAFT :{BLACK} 항공기 틱: +STR_FRAMERATE_GL_LANDSCAPE :{BLACK} 세계 틱: +STR_FRAMERATE_GL_LINKGRAPH :{BLACK} 연결 그래프 지연: +STR_FRAMERATE_DRAWING :{BLACK}그래픽 렌더링: +STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK} 세계 화면: +STR_FRAMERATE_VIDEO :{BLACK}비디오 출력: +STR_FRAMERATE_SOUND :{BLACK}사운드 합성: +############ End of leave-in-this-order +############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_GAMELOOP :게임 루프 +STR_FRAMETIME_CAPTION_GL_ECONOMY :화물 처리 +STR_FRAMETIME_CAPTION_GL_TRAINS :열차 틱 +STR_FRAMETIME_CAPTION_GL_ROADVEHS :자동차 틱 +STR_FRAMETIME_CAPTION_GL_SHIPS :선박 틱 +STR_FRAMETIME_CAPTION_GL_AIRCRAFT :항공기 틱 +STR_FRAMETIME_CAPTION_GL_LANDSCAPE :세계 틱 +STR_FRAMETIME_CAPTION_GL_LINKGRAPH :연결 그래프 지연 +STR_FRAMETIME_CAPTION_DRAWING :그래픽 렌더링 +STR_FRAMETIME_CAPTION_DRAWING_VIEWPORTS :세계 화면 렌더링 +STR_FRAMETIME_CAPTION_VIDEO :비디오 출력 +STR_FRAMETIME_CAPTION_SOUND :사운드 합성 +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}게임 저장 STR_SAVELOAD_LOAD_CAPTION :{WHITE}게임 불러오기 @@ -2716,6 +2773,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}게임 STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}사용 가능한 정보 없음. STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} +STR_SAVELOAD_FILTER_TITLE :{BLACK}검색할 문자열: STR_SAVELOAD_OSKTITLE :{BLACK}게임을 저장할 파일명을 입력하세요 @@ -2914,6 +2972,8 @@ STR_NEWGRF_ERROR_READ_BOUNDS :유사 스프 STR_NEWGRF_ERROR_GRM_FAILED :요청한 GRF 자원을 사용할 수 없음 (스프라이트 {3:NUM}) STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING}(은)는 {STRING} 때문에 사용할 수 없습니다 STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :유효하지 않은/알 수 없는 스프라이트 구조 유형 (스프라이트 {3:NUM}) +STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG :속성값 목록에 너무 많은 요소가 있음 (스프라이트 {3:NUM}, 속성 {4:HEX}) +STR_NEWGRF_ERROR_INDPROD_CALLBACK :유효하지 않은 산업 생산 콜백 (스프라이트 {3:NUM}, "{1:STRING}") # NewGRF related 'general' warnings STR_NEWGRF_POPUP_CAUTION_CAPTION :{WHITE}경고! @@ -2978,6 +3038,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}팻말 STR_TOWN_DIRECTORY_CAPTION :{WHITE}도시 목록 STR_TOWN_DIRECTORY_NONE :{ORANGE}(없음) STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (대도시){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}도시 이름 - 이 도시로 시점을 변경하려면 클릭하세요. CTRL+클릭하면 이 도시 위치를 기준으로 새로운 외부 화면을 엽니다. STR_TOWN_POPULATION :{BLACK}총 인구 수: {COMMA} @@ -2985,8 +3046,7 @@ STR_TOWN_POPULATION :{BLACK}총 인 STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (대도시) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}인구: {ORANGE}{COMMA}{BLACK} 가구수: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}지난 달 승객 수: {ORANGE}{COMMA}{BLACK} 최대: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}지난달 우편수: {ORANGE}{COMMA}{BLACK} 최고: {ORANGE}{COMMA} +STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} 지난 달: {ORANGE}{COMMA}{BLACK} 최대: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}도시가 성장하기 위해 필요한 화물: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED}{G 0 "이" "가"} 필요함 STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :겨울에는 {ORANGE}{STRING}{BLACK}{G 0 "이" "가"} 필요함 @@ -4225,7 +4285,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}역이 STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}철도역 조각이 너무 많습니다 STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}버스 정류장이 너무 많습니다 STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}트럭 적하장이 너무 많습니다 -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}다른 역과 너무 가깝습니다! STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}다른 항구와 너무 가깝습니다! STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}다른 공항과 너무 가깝습니다! STR_ERROR_CAN_T_RENAME_STATION :{WHITE}역 이름을 바꿀 수 없습니다... @@ -4233,6 +4292,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... 여 STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... 도로의 방향과 일치하지 않습니다. STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... 도로 통과 정류장은 곡선도로에 건설할 수 없습니다. STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... 도로 통과 정류장은 교차로에 건설할 수 없습니다. +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... 도로가 일방통행이거나 막혔습니다 # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}역의 일부를 제거할 수 없습니다... @@ -4480,10 +4540,12 @@ STR_DESKTOP_SHORTCUT_COMMENT :트랜스포트 STR_BASEGRAPHICS_DOS_DESCRIPTION :오리지널 트랜스포트 타이쿤 디럭스 도스 에디션의 그래픽입니다. STR_BASEGRAPHICS_DOS_DE_DESCRIPTION :오리지널 트랜스포트 타이쿤 디럭스 도스 에디션(독일)의 그래픽입니다. STR_BASEGRAPHICS_WIN_DESCRIPTION :오리지널 트랜스포트 타이쿤 디럭스 윈도 에디션의 그래픽입니다. -STR_BASESOUNDS_DOS_DESCRIPTION :오리지널 트랜스포트 타이쿤 도스 에디션의 효과음입니다. +STR_BASESOUNDS_DOS_DESCRIPTION :오리지널 트랜스포트 타이쿤 디럭스 도스 에디션의 효과음입니다. STR_BASESOUNDS_WIN_DESCRIPTION :오리지널 트랜스포트 타이쿤 디럭스 윈도 에디션의 효과음입니다. STR_BASESOUNDS_NONE_DESCRIPTION :아무런 효과음도 없는 효과음 팩입니다. STR_BASEMUSIC_WIN_DESCRIPTION :오리지널 트랜스포트 타이쿤 디럭스 윈도 에디션의 음악입니다. +STR_BASEMUSIC_DOS_DESCRIPTION :오리지널 트랜스포트 타이쿤 디럭스 DOS 에디션의 음악입니다. +STR_BASEMUSIC_TTO_DESCRIPTION :오리지널 트랜스포트 타이쿤 (오리지널/월드 에디터) DOS 에디션의 음악입니다. STR_BASEMUSIC_NONE_DESCRIPTION :실제 음악이 없는 음악 목록입니다. ##id 0x2000 diff --git a/src/lang/latin.txt b/src/lang/latin.txt index 42047a47d6..9fa9f87293 100644 --- a/src/lang/latin.txt +++ b/src/lang/latin.txt @@ -838,6 +838,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}Nulla musica parata STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Carmen STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Titulus @@ -857,15 +858,15 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Eligere STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Incipere desinereve admixtionem carminum STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Monstrare fenestram electionis carminum -STR_ERROR_NO_SONGS :{WHITE}Compositio sine carminibus electa est. Nulla carmina canentur - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Electio Compositionis Musicae +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Compositio Musicae - '{STRING}' STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Index Carminum STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Compositio - '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Vacuefacere +STR_PLAYLIST_CHANGE_SET :{BLACK}Mutare gregem STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Vacuefacere compositionem (modo Propriam I aut Propriam II) +STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Mutare gregem musicam STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Preme in carmen ut compositioni addantur (modo Propriae I aut Propriae II) STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Preme in carmen ut ex compositione removeatur (modo Propria I aut Propria II) @@ -1068,10 +1069,10 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC # Extra view window STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Fenestra conspectus {COMMA} -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Transcribere ad fenestram conspectus +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Mutare conspectum STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Transcribere locum primarium ad hanc fenestram conspectus -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Glutinare ex fenestra conspectus -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Glutinare locum ex hac fenestra ad conspectum primarium +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Mutare conspectum primum +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Transcribere locum ex hac fenestra ad conspectum primarium # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Ludi optiones @@ -1525,9 +1526,13 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Color terrae in STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Viridis STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Viridis Obscurus STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Purpureus -STR_CONFIG_SETTING_REVERSE_SCROLLING :Revertere cursum vagationis: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Quomodo tabula vagatur globulo dextri presso. Neglecta, mus conspectum movet. Electa, mus tabulam movet -STR_CONFIG_SETTING_SMOOTH_SCROLLING :Vagari conspectum leniter: {STRING} +STR_CONFIG_SETTING_SCROLLMODE :Modus conspectum movendi: {STRING} +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Quomodo tabula geographica vagatur +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Conspectus movetur globulo dextro, loco muris fixo +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Tabula movetur globulo dextro, loco muris fixo +STR_CONFIG_SETTING_SCROLLMODE_RMB :Tabula movetur globulo muris dextro +STR_CONFIG_SETTING_SCROLLMODE_LMB :Tabula movetur globulo muris sinistro +STR_CONFIG_SETTING_SMOOTH_SCROLLING :Movere conspectum leniter: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Quomodo conspectus vagatur ad quemdam locum globulo sinistro in tabula premendi aut cum iubetur vagari ad quamdam rem in tabula. Electa, conspectus leniter vagatur. Neglecta, statim salit ad locum STR_CONFIG_SETTING_MEASURE_TOOLTIP :Ostendere nuntium adiuvans apud varia ferramenta construendi: {STRING} STR_CONFIG_SETTING_MEASURE_TOOLTIP_HELPTEXT :Ostendere spatium atque altitudinem inter tegulas dum mus trahitur in construendo @@ -1558,8 +1563,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Cmd+Premere STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+Premere STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Neglecta -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Vagatio globuli sinistri: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Annuere tabulam vagari trahendo globuli sinistri. Magnopere utilis est cum tangendo navigas in scrinio STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Claudere fenestras globulo muris dextro: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Facit ut globulus muris dexter fenestras claudat. Cave: hac electa, non apparent nuntia adiuvantia globulo dextro. @@ -2483,6 +2486,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Formula STR_LINKGRAPH_LEGEND_ALL :{BLACK}Omnia STR_LINKGRAPH_LEGEND_NONE :{BLACK}Nulla STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Eligere societates monstrandas +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}non usus @@ -2895,6 +2899,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Privileg STR_ABOUT_VERSION :{BLACK}OpenTTD editio {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} MMII-MMXVII Manus OpenTTD +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Servare Ludum STR_SAVELOAD_LOAD_CAPTION :{WHITE}Legere Ludum @@ -3179,6 +3190,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Inscribe STR_TOWN_DIRECTORY_CAPTION :{WHITE}Oppida STR_TOWN_DIRECTORY_NONE :{ORANGE}- Nulla - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Urbs){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Nomina oppidorum - preme in nomen ut conspectus supra oppidum locetur. Ctrl+Preme ut novam fenestram conspectus supra oppidum aperiatur STR_TOWN_POPULATION :{BLACK}Incolae mundi: {COMMA} @@ -3186,8 +3198,6 @@ STR_TOWN_POPULATION :{BLACK}Incolae STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Urbs) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Incolae: {ORANGE}{COMMA}{BLACK} Aedificia: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Vectores mensis prioris: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Epistulae mensis prioris: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Onera mandata ad oppidum crescendum: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} mandatur STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} hieme mandatur @@ -4428,7 +4438,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Nimis st STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Nimis partes stationum ferriviariarum adsunt STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Nimis stationes laophoricae adsunt STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Nimis stationes autoplaustricae adsunt -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Nimis prope aliam stationem STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Nimis prope aliud navale STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Nimis prope alium aeroportum STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Non licet stationem renominare... @@ -4436,6 +4445,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... via STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... viae directio non convenit STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... stationi perviae non licet esse curva STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... stationi perviae non licet compita habere +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... via est monodromus vel obstructa # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Non licet partem stationis removere... @@ -4687,6 +4697,8 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Soni ex edition STR_BASESOUNDS_WIN_DESCRIPTION :Soni ex editione originale Transport Tycoon Deluxe Windows. STR_BASESOUNDS_NONE_DESCRIPTION :Sarcina sonorum sine ullis sonis. STR_BASEMUSIC_WIN_DESCRIPTION :Musica ex editione originale Transport Tycoon Deluxe Windows. +STR_BASEMUSIC_DOS_DESCRIPTION :Musica ex editione originale Transport Tycoon Deluxe DOS. +STR_BASEMUSIC_TTO_DESCRIPTION :Musica ex editione originale Transport Tycoon (Originale/World Editor) DOS. STR_BASEMUSIC_NONE_DESCRIPTION :Sarcina musicae sine ulla musica. ##id 0x2000 diff --git a/src/lang/latvian.txt b/src/lang/latvian.txt index dab5900f75..4f723b5a88 100644 --- a/src/lang/latvian.txt +++ b/src/lang/latvian.txt @@ -475,6 +475,7 @@ STR_ABOUT_MENU_SCREENSHOT :Ekrānuzņēmum STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Pilnībā pietuvināts ekrānuzņēmums STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Noklusējuma mēroga ekrānuzņēmums STR_ABOUT_MENU_GIANT_SCREENSHOT :Visas kartes ekrānuzņēmums +STR_ABOUT_MENU_SHOW_FRAMERATE :Rādīt kadru ātrumu STR_ABOUT_MENU_ABOUT_OPENTTD :Par 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Gariņu līdzinātājs STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Pārslēgt saistītās kastes @@ -669,10 +670,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Izvēlē STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Ieslēgt/izslēgt mūzikas saraksta jaukšanu STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Rādīt mūzikas celiņu atlases logu -STR_ERROR_NO_SONGS :{WHITE}Izvēlēts komplekts bez mūzikas. Mūzika netiks atskaņota - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Mūzikas programmas izvēle STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Celiņu rādītājs STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programma - '{STRING}' @@ -1276,6 +1274,7 @@ STR_CONFIG_SETTING_LANDSCAPE :Ainava: {STRING STR_CONFIG_SETTING_LAND_GENERATOR :Zemes radītājs: {STRING} STR_CONFIG_SETTING_LAND_GENERATOR_ORIGINAL :Sākotnējais STR_CONFIG_SETTING_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis +STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT :(Tikai TerraGenesis) Ainavas kalnainība STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Maksimālais attālums no kartes malas naftas pārstrādes rūpnīcām: {STRING} STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Naftas pārstrādes rūpnīcas ir būvējamas tikai kartes malu tuvumā, salu kartēm tas ir pie krasta STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Sniega līnijas augstums: {STRING} @@ -1307,7 +1306,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Apvidus krāsa STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :zaļa STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :{G=f}tumši zaļa STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :{G=f}violeta -STR_CONFIG_SETTING_REVERSE_SCROLLING :Pretējs ritināšanas virziens: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING :Plūdena skatvietas ritināšana: {STRING} STR_CONFIG_SETTING_MEASURE_TOOLTIP :Rādīt mērījumu rīkjoslu, izmantojot dažādus būvniecības rīkus: {STRING} STR_CONFIG_SETTING_MEASURE_TOOLTIP_HELPTEXT :Rāda lauciņu attālumus un augstuma starpības, ar vilkšanu veicot būvniecības darbības @@ -1337,7 +1335,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Komanda+klikš STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+klikšķis STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Izslēgta -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Kreisā klikšķa ritināšana: {STRING} STR_CONFIG_SETTING_AUTOSAVE :Automātiskā saglabāšana: {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :Izvēlēties spēles automātiskās saglabāšanas starplaikus @@ -1566,6 +1563,7 @@ STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Lielpilsētu vi STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manuāli STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asimetriska STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :simetriska +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"nesimetriski" nozīmē, ka patvaļīgu kravas daudzumu var nosūtīt abos virzienos."manuāli" nozīmē, ka šīm kravām netiks veikta automātiska izplatīšana. STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Sadales precizitāte: {STRING} STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT :Uzstādod šo mazāk par 100% liks simetriskajai sadalei izturēties vairāk kā asimetriskajai. Mazāk kravas ar varu tiks sūtīts atpakaļ ja noteikts daudzums tiks sūtīts uz piestātni. Ja jūs uzstādīsiet to uz 0% simetriskā sadale izturēsies tā pat kā asimetriskā. @@ -2630,6 +2628,16 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Oriģin STR_ABOUT_VERSION :{BLACK}OpenTTD versija {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 OpenTTD darba grupa +# Framerate display window +STR_FRAMERATE_SPEED_FACTOR :{WHITE}pašreizējās spēles ātruma pakāpe: {DECIMAL}x +STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Cik ātri spēle šobrīd iet salīdzinot ar standarta ātrumu. +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_VIDEO :{WHITE}video izeja +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Saglabāt spēli STR_SAVELOAD_LOAD_CAPTION :{WHITE}Ielādēt spēli @@ -2780,6 +2788,7 @@ STR_SAVE_PRESET_EDITBOX_TOOLTIP :{BLACK}Pašlaik STR_SAVE_PRESET_CANCEL :{BLACK}Atcelt STR_SAVE_PRESET_CANCEL_TOOLTIP :{BLACK}Nemainīt iepriekšiestatījumu STR_SAVE_PRESET_SAVE :{BLACK}Saglabāt +STR_SAVE_PRESET_SAVE_TOOLTIP :{BLACK}pašreizējos iestatījumus saglābāt kā sākontnējos iestatījumus # NewGRF parameters window STR_NEWGRF_PARAMETERS_CAPTION :{WHITE}Mainīt NewGRF parametrus @@ -2913,8 +2922,6 @@ STR_TOWN_POPULATION :{BLACK}Pasaules STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (lielpilsēta) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Iedzīvotāji: {ORANGE}{COMMA}{BLACK} Mājas: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Pasažieri pagājušajā mēnesī: {ORANGE}{COMMA}{BLACK} maksimāli: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Pasts pagājušajā mēnesī: {ORANGE}{COMMA}{BLACK} maksimāli: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Krava nepieciešama pilsētas attīstībai: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} nepieciešams STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} nepieciešams ziemā @@ -3219,6 +3226,7 @@ STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE :{BLACK}Iepriek STR_INDUSTRY_VIEW_TRANSPORTED :{YELLOW}{CARGO_LONG}{STRING}{BLACK} (aizvests {COMMA}%) STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Centrēt galveno skatu uz ražotni. Ctrl+klikšķis atvērs skatu uz ražotni jaunā skatlaukā STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Ražošanas līmenis: {YELLOW}{COMMA}% +STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}Nozare ir paziņojusi par nenovēršamu slēgšanu! ############ range for requires starts STR_INDUSTRY_VIEW_REQUIRES_CARGO :{BLACK}Nepieciešams: {YELLOW}{STRING}{STRING} @@ -3293,6 +3301,7 @@ STR_GROUP_REMOVE_ALL_VEHICLES :Novākt visus t STR_GROUP_RENAME_CAPTION :{BLACK}Pārdēvēt grupu +STR_GROUP_PROFIT_THIS_YEAR :Ienākumi šajā gadā: # Build vehicle window STR_BUY_VEHICLE_TRAIN_RAIL_CAPTION :Jauni dzelzceļa transportlīdzekļi @@ -4058,6 +4067,7 @@ STR_ERROR_EXCAVATION_WOULD_DAMAGE :{WHITE}Rakšana STR_ERROR_ALREADY_AT_SEA_LEVEL :{WHITE}... jau ir jūras līmenī STR_ERROR_TOO_HIGH :{WHITE}... pārāk augstu STR_ERROR_ALREADY_LEVELLED :{WHITE}... jau ir līdzens +STR_ERROR_BRIDGE_TOO_HIGH_AFTER_LOWER_LAND :{WHITE}Tilta otrs gals ir pārāk augstu. # Company related errors STR_ERROR_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Uzņēmuma nosaukumu nevar mainīt... @@ -4124,7 +4134,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Pārāk STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Pārāk daudz dzelzceļa stacijas daļu STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Pārāk daudz autobusu pieturvietu STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Pārāk daudz kravas automobiļu staciju -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Pārāk tuvu citai stacijai/iekraušanas zonai STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Pārāk tuvu citai piestātnei STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Pārāk tuvu citai lidostai STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Nevar pārdēvēt staciju... @@ -4272,6 +4281,7 @@ STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... tā STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Nevar izveidot grupu... STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Nevar izdzēst šo grupu... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Nevar pārdēvēt grupu... +STR_ERROR_GROUP_CAN_T_SET_PARENT :nevar iestatīt vecāku grupu... STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Nevar noņemt no šīs grupas visus transportlīdzekļus... STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Nevar pievienot transportlīdzekļus šai grupai... STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Nevar pievienot koplietojamos transportlīdzekļus šai grupai... diff --git a/src/lang/lithuanian.txt b/src/lang/lithuanian.txt index 4d44522671..163c90c70d 100644 --- a/src/lang/lithuanian.txt +++ b/src/lang/lithuanian.txt @@ -864,10 +864,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Parinkti STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Programos „Atsitiktiniai takeliai“ įj./išj. STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Rodyti muzikos takelių pasirinkimo langą -STR_ERROR_NO_SONGS :{WHITE}Pasirinktas muzikos rinkinys be dainų. Dainos nebus grojamos - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Muzikos programos pasirinkimas STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} „{STRING}“ STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Takelio numeris STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programa - „{STRING}“ @@ -1542,8 +1539,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Reljefo spalva STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Žalia STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Tamsiai žalia STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Violetinė -STR_CONFIG_SETTING_REVERSE_SCROLLING :Priešinga slinkties kryptis: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Vaizdo slinkties elgsena, laikant nuspaudus dešinįjį pelės klavišą: pasirinkus „ne“, judės stebėtojas. Pasirinkus „taip“, judės žemėlapis STR_CONFIG_SETTING_SMOOTH_SCROLLING :Tolydi vaizdo slinktis: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Įjungus šią nuostatą ir pakeitus pagrindinio lango rodomą vietą (pvz., spragtelėjus žemėlapyje), vaizdas slinksis tolydžiai. Priešingu atveju vaizdas pasikeis akimirksniu, šuoliškai. STR_CONFIG_SETTING_MEASURE_TOOLTIP :Rodyti matavimo pastabą, kai naudojami įvairūs statybų įrankiai: {STRING} @@ -1575,8 +1570,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command+Click STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+Click STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Išjungta -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Left-click scrolling: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Slinkti žemėlapį velkant jį nuspaudus kairįjį pelės klavišą. Naudinga, jei žaidžiama kompiuteriuose su lietimui jautriais ekranais STR_CONFIG_SETTING_AUTOSAVE :Automatinis saugojimas: {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :Laiko tarpsnis tarp automatinių žaidimo išsaugojimų @@ -2908,6 +2901,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Pradinė STR_ABOUT_VERSION :{BLACK}OpenTTD versija {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2018 OpenTTD komanda +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Išsaugoti žaidimą STR_SAVELOAD_LOAD_CAPTION :{WHITE}Įkelti žaidimą @@ -3199,8 +3199,6 @@ STR_TOWN_POPULATION :{BLACK}Pasaulio STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Miestas) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Populiacija: {ORANGE}{COMMA}{BLACK} Namų skaičius: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Praėjusio mėnesio keleivių sk.: {ORANGE}{COMMA}{BLACK} Daugiausia: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Praėjusio mėnesio pašto siuntų sk.: {ORANGE}{COMMA}{BLACK} Daugiausia: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Kad miestas augtų reikalingi kroviniai: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} reikia STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} reikalingas žiemą @@ -4480,7 +4478,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Per daug STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Perdaug traukinių stoties dalių STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Per daug autobusų stotelių STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Per daug sunkvežimių pakrovimo aikstelių -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Per arti kitos stotelės STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Per arti kitos prieplaukos STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Per arti kito oro uosto STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Stotelės pervardinti negalima... diff --git a/src/lang/luxembourgish.txt b/src/lang/luxembourgish.txt index 38dba61000..60ffaf64a3 100644 --- a/src/lang/luxembourgish.txt +++ b/src/lang/luxembourgish.txt @@ -669,10 +669,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Wielt de STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Schalt den "shuffle" un/aus STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Weis d'Fënster fir Musik ze wielen -STR_ERROR_NO_SONGS :{WHITE}E Music Set ouni Lidder gouf gewielt. Et wäerten keng Lidder gespillt ginn - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Musiksprogramm Auswiel STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Lidder Index STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programm - '{STRING}' @@ -1337,8 +1334,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Faarf vum Terra STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Gréng STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Donkelgréng STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Mof -STR_CONFIG_SETTING_REVERSE_SCROLLING :Deen anere Wee scrollen: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Verhalen beim Scrollen vun der Kaart mat der rietser Maustast. Wann ausgeschalt, beweegt d'Maus d'Kamera. Wann ugeschalt, beweegt d'Maus d'Kaart STR_CONFIG_SETTING_SMOOTH_SCROLLING :Feine Scrolling: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Kontrolléiert wéi d'Haptusiicht op eng bestëmmten Positioun scrollt, wann een op déi kléng Kaart klickt oder en Befehl fir ob en spezifescht Objet ze scrollen gëtt. Wann ugeschalt, gëtt bis dohin gescrollt, wann ausgeschalt, spréngt d'Vue op den Zielobjet STR_CONFIG_SETTING_MEASURE_TOOLTIP :Weis en Mooss-Tooltip wann verschidde Bau-Tools benotzt ginn: {STRING} @@ -1370,8 +1365,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :COMM+Klick STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :CTRL+Klick STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Aus -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Lénksklickscroll: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Schalt d'Scrollen vun der Kaart un, wann se mat der lénker Maustast gezunn gëtt STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Fënster mat rietsem Mausklick zouman: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Mécht eng Fenster mat engem Rietsklick zou, wann een an d'Fënster klickt. Schalt Tooltips aus déi per Rietsklick gemet ginn! @@ -2693,6 +2686,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Original STR_ABOUT_VERSION :{BLACK}OpenTTD Versioun {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 D'OpenTTD team +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Spill späicheren STR_SAVELOAD_LOAD_CAPTION :{WHITE}Spill lueden @@ -2984,8 +2984,6 @@ STR_TOWN_POPULATION :{BLACK}Weltbev STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Stad) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Awunner: {ORANGE}{COMMA}{BLACK} Haiser: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passagéier leschte Mount: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Post leschte Mount: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Gidder gebraucht fir Stadwuesstem: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} gebraucht STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} gebraucht am Wanter @@ -4224,7 +4222,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Ze vill STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Ze vill Garesdeeler STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Ze vill Busarrêten STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Ze vill Camionsgaren -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Ze noo un enger aanerer Gare/Luedstatioun STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Ze noo un engem aanerem Hafen STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Ze noo un engem aaneren Fluchhafen STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Kann d'Statioun net ëmbenennen... diff --git a/src/lang/malay.txt b/src/lang/malay.txt index 4ba83efdaa..e5ba9a2dc0 100644 --- a/src/lang/malay.txt +++ b/src/lang/malay.txt @@ -215,6 +215,7 @@ STR_UNITS_VOLUME_LONG_SI :{COMMA} m³ STR_UNITS_FORCE_SI :{COMMA} kN STR_UNITS_HEIGHT_IMPERIAL :{COMMA} ka +STR_UNITS_HEIGHT_METRIC :{COMMA}{NBSP}m STR_UNITS_HEIGHT_SI :{COMMA} m # Common window strings @@ -241,6 +242,7 @@ STR_TOOLTIP_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Bar Skro STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC :{BLACK}Musnahkan bangunan dll. dari dataran tanah. Ctrl memilih kawasan menyerong. Shift bangunan/tunjukkan anggaran kos. # Show engines button +STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT :{BLACK}Tunjukkan perkara yang tersembunyi STR_SHOW_HIDDEN_ENGINES_VEHICLE_SHIP_TOOLTIP :{BLACK}Dengan membenarkan pilihan ini, kapal tersembunyi turut ditunjukkan @@ -453,7 +455,7 @@ STR_ABOUT_MENU_TOGGLE_CONSOLE :Papar atau pada STR_ABOUT_MENU_AI_DEBUG :Al/Skrip pepijat permainan STR_ABOUT_MENU_SCREENSHOT :Tangkapan skrin (Ctrl+S) STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Zum sepenuhnya di pembidik skrin -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Tangkapan skrin dizoom asal +STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Tangkapan skrin di zum asal STR_ABOUT_MENU_GIANT_SCREENSHOT :Tangkap gambar skrin besar (Ctrl+G) STR_ABOUT_MENU_ABOUT_OPENTTD :Tentang 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Penjajar peperi @@ -610,7 +612,7 @@ STR_PERFORMANCE_DETAIL_MIN_INCOME_TOOLTIP :{BLACK}Jumlah w STR_PERFORMANCE_DETAIL_MAX_INCOME_TOOLTIP :{BLACK}Jumlah wang keuntungan dalam suku tahun dengan keuntungan tertinggi dalam 12 suku tahun yang lepas STR_PERFORMANCE_DETAIL_DELIVERED_TOOLTIP :{BLACK}Unit-unit kargo yang dihantar dalam 4 suku tahun yang lepas STR_PERFORMANCE_DETAIL_CARGO_TOOLTIP :{BLACK}Jumlah jenis kargo yang dihantar dalam suku tahun yang lepas -STR_PERFORMANCE_DETAIL_MONEY_TOOLTIP :{BLACK}Jumlah wang syarikat ini mempunyai dalam bank +STR_PERFORMANCE_DETAIL_MONEY_TOOLTIP :{BLACK}Jumlah wang syarikat di dalam bank STR_PERFORMANCE_DETAIL_LOAN_TOOLTIP :{BLACK}Jumlah wang syarikat ini yang telah dipinjam STR_PERFORMANCE_DETAIL_TOTAL_TOOLTIP :{BLACK}Jumlah markah daripada markah yang boleh diperolehi @@ -649,10 +651,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Pilih ra STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Mainkan muzik secara rawak atau tidak STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Tunjukkan tetingkap pilihan lagu -STR_ERROR_NO_SONGS :{WHITE}Set muzik yang tidak mengandungi lagu telah dipilih. Tiada lagu yang akan dimainkan - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Pilihan Rancangan Muzik STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Indeks Lagu STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Program - '{STRING}' @@ -737,6 +736,7 @@ STR_SMALLMAP_TOOLTIP_ENABLE_ALL_INDUSTRIES :{BLACK}Paparkan STR_SMALLMAP_TOOLTIP_SHOW_HEIGHT :{BLACK}Papar atau padamkan heightmap STR_SMALLMAP_TOOLTIP_DISABLE_ALL_COMPANIES :{BLACK}Paparkan hartanah tanpa syarikat pada peta STR_SMALLMAP_TOOLTIP_ENABLE_ALL_COMPANIES :{BLACK}Paparkan seluruh maklumat hartanah syarikat pada peta +STR_SMALLMAP_TOOLTIP_ENABLE_ALL_CARGOS :{BLACK}Tunjukkan semua kargo di atas peta # Status bar messages STR_STATUSBAR_TOOLTIP_SHOW_LAST_NEWS :{BLACK}Tunjukkan mesej atau laporan berita terakhir @@ -853,10 +853,10 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT} {BLA # Extra view window STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Tetingkap Pemandangan {COMMA} -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Salin ke tetingkap pemandangan +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Ubah tetingkap paparan STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Salin lokasi pemandangan global kepada tetingkap pemandangan ini -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Tampal daripada tetingkap pemandangan -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Salin lokasi tetingkap pemandangan ini kepada pemandangan utama +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Ubah paparan utama +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Salin lokasi tetingkap paparan ini ke paparan utama # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Pilihan Permainan @@ -1218,6 +1218,7 @@ STR_CONFIG_SETTING_ORDER_REVIEW_ON :Semua kenderaan STR_CONFIG_SETTING_WARN_INCOME_LESS :Beri amaran jika pendapatan kenderaan adalah negatif: {STRING} STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES :Kenderaan tidak akan tamat tempohnya: {STRING} STR_CONFIG_SETTING_AUTORENEW_VEHICLE :Gunakan pembaharuan automatik apabila kenderaan usang : {STRING} +STR_CONFIG_SETTING_AUTORENEW_MONTHS_VALUE_AFTER :{COMMA} bulan{P 0 "" s} selepas STR_CONFIG_SETTING_AUTORENEW_MONEY :Wang minimum yang diperlukan untuk pembaharuan automatik: {STRING} STR_CONFIG_SETTING_ERRMSG_DURATION :Jangkamasa mesej ralat: {STRING} STR_CONFIG_SETTING_POPULATION_IN_LABEL :Tunjukkan jumlah penduduk dalam label nama bandar: {STRING} @@ -1253,7 +1254,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR :Warna tanah yan STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Hijau STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Hijau Gelap STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Ungu -STR_CONFIG_SETTING_REVERSE_SCROLLING :Arah skrol terbalik: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING :Skrol tetingkap pemandangan yang licin: {STRING} STR_CONFIG_SETTING_MEASURE_TOOLTIP :Tunjukkan bantuan ukuran ketika menggunakan alat binaan: {STRING} STR_CONFIG_SETTING_LIVERIES :Tunjukkan seragam syarikat: {STRING} @@ -1266,6 +1266,7 @@ STR_CONFIG_SETTING_SCROLLWHEEL_ZOOM :Membesarkan pet STR_CONFIG_SETTING_SCROLLWHEEL_SCROLL :Skrol peta STR_CONFIG_SETTING_SCROLLWHEEL_OFF :Matikan STR_CONFIG_SETTING_SCROLLWHEEL_MULTIPLIER :Kelajuan roda skrol pada peta: {STRING} +STR_CONFIG_SETTING_SCROLLWHEEL_MULTIPLIER_HELPTEXT :Kawal kesensitifan skrol roda tetikus STR_CONFIG_SETTING_OSK_ACTIVATION :Papan kekunci di skrin: {STRING} STR_CONFIG_SETTING_OSK_ACTIVATION_HELPTEXT :Pilih kaedah untuk membuka papan kekunci pada skrin untuk memasukkan teks ke dalam kotak edit hanya menggunakan petunjuk peranti. Ini bertujuan untuk peranti kecil yang tiada papan kekunci sebenar STR_CONFIG_SETTING_OSK_ACTIVATION_DISABLED :Dinyah-upayakan @@ -1278,7 +1279,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command+Klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+Klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Matikan -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Skrol klik-kiri: {STRING} STR_CONFIG_SETTING_AUTOSAVE :Simpanan automatik:{STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :Pilih jarak waktu antara menyimpankan permainan automatik @@ -1298,6 +1298,7 @@ STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS :Gunakan senarai STR_CONFIG_SETTING_LOADING_INDICATORS :Gunakan penunjuk muatan: {STRING} STR_CONFIG_SETTING_TIMETABLE_IN_TICKS :Tunjukkan jadual menggunakan tanda rait dan bukan hari: {STRING} STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE :Tunjukkan ketibaan dan pelepasan dalam jadual: {STRING} +STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE_HELPTEXT :Tunjukkan jangkaan waktu ketibaan dan pelepasan dalam jadual STR_CONFIG_SETTING_QUICKGOTO :Pewujudan pantas arahan kenderaan: {STRING} STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE :Landasan keretapi lazim (apabila memulakan permainan baru/buka permainan: {STRING} STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_FIRST :Yang tersedia terawal @@ -1305,6 +1306,7 @@ STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_LAST :Yang tersedia s STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_MOST_USED :Yang selalu digunakan STR_CONFIG_SETTING_SHOW_TRACK_RESERVATION :Tunjukkan landasan yang ditempah: {STRING} STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS :Alat binaan tetap aktif selepas digunakan: {STRING} +STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS_HELPTEXT :Simpan alat pembinaan untuk jambatan, terowong, dll. buka selepas guna STR_CONFIG_SETTING_EXPENSES_LAYOUT :Perbelanjaan kumpulan dalam tetingkap kewangan syarikat: {STRING} STR_CONFIG_SETTING_SOUND_CONFIRM :Pembinaan: {STRING} @@ -1312,6 +1314,7 @@ STR_CONFIG_SETTING_SOUND_CONFIRM :Pembinaan: {STR STR_CONFIG_SETTING_DISABLE_UNSUITABLE_BUILDING :Nyahaktif infrastruktur bangunan apabila tiada kenderaan yang sesuai: {STRING} STR_CONFIG_SETTING_MAX_TRAINS :Amaun maksimum kereta api setiap syarikat: {STRING} STR_CONFIG_SETTING_MAX_ROAD_VEHICLES :Amaun maksimum kenderaan jalanraya setiap syarikat: {STRING} +STR_CONFIG_SETTING_MAX_ROAD_VEHICLES_HELPTEXT :Jumlah maksimum kenderaan darat sesebuah syarikat STR_CONFIG_SETTING_MAX_AIRCRAFT :Amaun maksimum pesawat setiap syarikat: {STRING} STR_CONFIG_SETTING_MAX_SHIPS :Amaun maksimum kapal setiap syarikat: {STRING} @@ -1332,7 +1335,10 @@ STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :#opcodes sebelu STR_CONFIG_SETTING_SERVINT_ISPERCENT :Tempoh waktu servis dalam peratusan: {STRING} STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Pilih sama ada selenggara kenderaan dimulakan sejak tempoh masa dari servis terakhir atau apabila peratusan kebolehupayaan kenderaan berkurang kepada peratusan tertentu. +STR_CONFIG_SETTING_SERVINT_VALUE :{COMMA}{NBSP}hari{P 0 "" s}/% STR_CONFIG_SETTING_SERVINT_DISABLED :Dilumpuhkan +STR_CONFIG_SETTING_SERVINT_AIRCRAFT_HELPTEXT :Tetapkan selang masa servis untuk pesawat baru kepada tetapan asal jika tiada selang masa servis yang jelas ditetapkan untuk pesawat tersebut +STR_CONFIG_SETTING_SERVINT_SHIPS_HELPTEXT :Tetapkan selang masa servis untuk kapal baru kepada tetapan asal jika tiada selang masa servis yang jelas ditetapkan untuk kapal tersebut STR_CONFIG_SETTING_NOSERVICE :Servis tidak diperlukan apabila kerosakan kenderaan ditetapkan kepada tiada: {STRING} STR_CONFIG_SETTING_WAGONSPEEDLIMITS :Benarkan had kelajuan untuk gerabak: {STRING} STR_CONFIG_SETTING_DISABLE_ELRAILS :Tiada landasan elektrik: {STRING} @@ -1344,13 +1350,16 @@ STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION :Maklumat syarik STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION_HELPTEXT :Paparkan surat khabar mengenai pembukaan syarikat baru, atau apabila syarikat dalam risiko untuk muflis STR_CONFIG_SETTING_NEWS_INDUSTRY_OPEN :Pembukaan industri: {STRING} STR_CONFIG_SETTING_NEWS_INDUSTRY_CLOSE :Penutupan industri: {STRING} +STR_CONFIG_SETTING_NEWS_INDUSTRY_CLOSE_HELPTEXT :Paparkan keratan akhbar apabila ada industri yang ditutup STR_CONFIG_SETTING_NEWS_ECONOMY_CHANGES :Perubahan ekonomi: {STRING} STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_COMPANY :Perubahan pengeluaran industri-industri yang diservis oleh syarikat: {STRING} STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_OTHER :Perubahan pengeluaran industri-industri yang diservis oleh pesaing: {STRING} +STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_OTHER_HELPTEXT :Paparkan keratan akhbar apabila berlaku perubahan tahap pengeluaran industri yang diservis oleh pesaing STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_UNSERVED :Pengubaran pengeluaran industri lain: {STRING} STR_CONFIG_SETTING_NEWS_ADVICE :Nasihat / maklumat tentang kenderaan syarikat: {STRING} STR_CONFIG_SETTING_NEWS_NEW_VEHICLES :Kenderaan baru: {STRING} STR_CONFIG_SETTING_NEWS_CHANGES_ACCEPTANCE :Penukaran pada penerimaan kargo: {STRING} +STR_CONFIG_SETTING_NEWS_CHANGES_ACCEPTANCE_HELPTEXT :Tunjukkan mesej berkenaan perubahan kebolehterimaan sesetengah kargo di stesen terlibat STR_CONFIG_SETTING_NEWS_SUBSIDIES :Subsidi: {STRING} STR_CONFIG_SETTING_NEWS_GENERAL_INFORMATION :Maklumat umum: {STRING} @@ -1411,17 +1420,25 @@ STR_CONFIG_SETTING_TOWN_GROWTH_NORMAL :Biasa STR_CONFIG_SETTING_TOWN_GROWTH_FAST :Pantas STR_CONFIG_SETTING_TOWN_GROWTH_VERY_FAST :Sangat pantas STR_CONFIG_SETTING_LARGER_TOWNS_VALUE :1 dalam {COMMA} +STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Tiada STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Pengganda awal saiz bandar: {STRING} +STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_IMPERIAL :Sistem Imperial (kuasa kuda/hp) +STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_METRIC :Sistem metrik (kuasa kuda/hp) +STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_SI :Unit SI (kW) + + +STR_CONFIG_SETTING_LOCALISATION_UNITS_VOLUME_SI :Unit SI (m³) - - +STR_CONFIG_SETTING_SOUND :{ORANGE}Bunyi STR_CONFIG_SETTING_INTERFACE :{ORANGE}Antaramuka (Interface) STR_CONFIG_SETTING_INTERFACE_CONSTRUCTION :{ORANGE}Pembinaan +STR_CONFIG_SETTING_ADVISORS :{ORANGE}Berita / Penasihat +STR_CONFIG_SETTING_COMPANY :{ORANGE}Syarikat STR_CONFIG_SETTING_VEHICLES :{ORANGE}Kenderaan STR_CONFIG_SETTING_VEHICLES_ROUTING :{ORANGE}Laluan STR_CONFIG_SETTING_ACCIDENTS :{ORANGE}Kecelakaan / Kemalangan @@ -1502,7 +1519,7 @@ STR_INTRO_TRANSLATION :{BLACK}Terjemah # Quit window STR_QUIT_CAPTION :{WHITE}Keluar -STR_QUIT_ARE_YOU_SURE_YOU_WANT_TO_EXIT_OPENTTD :{YELLOW}Pastikah anda untuk keluar dari OpenTTD dan kembali ke {STRING}? +STR_QUIT_ARE_YOU_SURE_YOU_WANT_TO_EXIT_OPENTTD :{YELLOW}Adakah anda pasti untuk keluar dari OpenTTD dan kembali ke {STRING}? STR_QUIT_YES :{BLACK}Ya STR_QUIT_NO :{BLACK}Tidak @@ -1520,8 +1537,8 @@ STR_OSNAME_SUNOS :SunOS # Abandon game STR_ABANDON_GAME_CAPTION :{WHITE}Tinggalkan Permainan -STR_ABANDON_GAME_QUERY :{YELLOW}Pastikah anda mahu keluar permainan ini? -STR_ABANDON_SCENARIO_QUERY :{YELLOW}Pastikah anda untuk keluar senario ini? +STR_ABANDON_GAME_QUERY :{YELLOW}Pastikah anda mahu keluar dari permainan ini? +STR_ABANDON_SCENARIO_QUERY :{YELLOW}Pastikah anda untuk keluar dari senario ini? # Cheat window STR_CHEATS :{WHITE}Penipuan (Cheats) @@ -1696,6 +1713,7 @@ STR_NETWORK_START_SERVER_NEW_GAME_NAME_TOOLTIP :{BLACK}Nama per STR_NETWORK_START_SERVER_SET_PASSWORD :{BLACK}Tetapkan kata laluan STR_NETWORK_START_SERVER_PASSWORD_TOOLTIP :{BLACK}Lindungi permainan anda dengan kata laluan jika anda tidak mahu ianya diakses awam +STR_NETWORK_START_SERVER_UNADVERTISED :Tidak STR_NETWORK_START_SERVER_CLIENTS_SELECT :{BLACK}{NUM} pelanggan STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS :{BLACK}Amaun maksimum pemain: STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS_TOOLTIP :{BLACK}Tentukan bilangan klien maks. Tidak perlu semua slot diisi @@ -1773,7 +1791,7 @@ STR_NETWORK_GAME_LOBBY_NEW_COMPANY_TOOLTIP :{BLACK}Mulakan STR_NETWORK_GAME_LOBBY_SPECTATE_GAME :{BLACK}Saksikan permainan STR_NETWORK_GAME_LOBBY_SPECTATE_GAME_TOOLTIP :{BLACK}Saksikan permainan sebagai seorang penyaksi STR_NETWORK_GAME_LOBBY_JOIN_COMPANY :{BLACK}Sertai syarikat -STR_NETWORK_GAME_LOBBY_JOIN_COMPANY_TOOLTIP :{BLACK}Bantu mengurus syarikat ini +STR_NETWORK_GAME_LOBBY_JOIN_COMPANY_TOOLTIP :{BLACK}Bantu uruskan syarikat ini # Network connecting window STR_NETWORK_CONNECTING_CAPTION :{WHITE}Menyambung... @@ -1934,6 +1952,7 @@ STR_CONTENT_SELECT_UPDATES_CAPTION :{BLACK}Pilih pe STR_CONTENT_SELECT_UPDATES_CAPTION_TOOLTIP :{BLACK}Tandakan semua kandungan sedia ada yang telah ditingkatkan untuk dimuat turun STR_CONTENT_UNSELECT_ALL_CAPTION :{BLACK}Nyahpilihkan semua STR_CONTENT_UNSELECT_ALL_CAPTION_TOOLTIP :{BLACK}Tandakan semua kandungan supaya jangan dimuat turun +STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER_CAPTION :{WHITE}Anda sedang meninggalkan OpenTTD! STR_CONTENT_FILTER_TITLE :{BLACK}Saringan tag/nama: STR_CONTENT_OPEN_URL :{BLACK}Lawati halaman STR_CONTENT_OPEN_URL_TOOLTIP :{BLACK}Lawati halaman untuk kandungan ini @@ -1986,7 +2005,7 @@ STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD_FILE_NOT_WRITABLE :{WHITE}... fail STR_CONTENT_ERROR_COULD_NOT_EXTRACT :{WHITE}Tidak dapat menyahmampat fail yang dimuat turun STR_MISSING_GRAPHICS_SET_CAPTION :{WHITE}Grafik hilang -STR_MISSING_GRAPHICS_SET_MESSAGE :{BLACK}OpenTTD memerlukan grafik berfungsi tetapi tiada diperolehi. Adakah anda membenarkan OpenTTD untuk memuat turun dan memasang-grafik? +STR_MISSING_GRAPHICS_SET_MESSAGE :{BLACK}OpenTTD memerlukan grafik berfungsi tetapi tiada grafik diperolehi. Adakah anda benarkan OpenTTD untuk memuat turun dan memasang grafik? STR_MISSING_GRAPHICS_YES_DOWNLOAD :{BLACK}Ya, muat turun grafik STR_MISSING_GRAPHICS_NO_QUIT :{BLACK}Tidak, keluar dari OpenTTD @@ -2309,6 +2328,7 @@ STR_LAND_AREA_INFORMATION_AIRPORTTILE_NAME :{BLACK}Nama pet STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Kargo yang diterima: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) +STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Jenis landasan: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Had kelajuan landasan: {LTBLUE}{VELOCITY} # Description of land area of different tiles @@ -2321,28 +2341,28 @@ STR_LAI_CLEAR_DESCRIPTION_SNOW_COVERED_LAND :Tanah diliputi STR_LAI_CLEAR_DESCRIPTION_DESERT :Padang pasir STR_LAI_RAIL_DESCRIPTION_TRACK :Landasan keretapi -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_SIGNALS :Keretapi landasan dengan isyarat sekatan -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRESIGNALS :Keretapi landasan dengan pra-isyarat +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_SIGNALS :Landasan kereta api dengan isyarat sekatan +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRESIGNALS :Landasan kereta api dengan pra-isyarat STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXITSIGNALS :Landasan keretapi dengan isyarat keluar STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBOSIGNALS :Landasan keretapi dengan isyarat kombo -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBSSIGNALS :Keretapi landasan dengan isyarat laluan +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBSSIGNALS :Landasan kereta api dengan isyarat laluan STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NOENTRYSIGNALS :Landasan keretapi dengan isyarat satu hala -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PRESIGNALS :Keretapi landasan dengan isyarat sekatan dan pra-isyarat +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PRESIGNALS :Landasan kereta api dengan isyarat sekatan dan pra-isyarat STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_EXITSIGNALS :Landasan keretapi dengan isyarat sekatan dan keluar STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_COMBOSIGNALS :Landasan keretapi dengan isyarat sekatan dan kombo -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PBSSIGNALS :Keretapi landasan dengan isyarat sekatan dan laluan +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PBSSIGNALS :Landasan kereta api dengan isyarat sekatan dan laluan STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_NOENTRYSIGNALS :Landasan keretapi dengan isyarat sekatan dan satu hala -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_EXITSIGNALS :Keretapi landasan dengan isyarat pra- dan keluar -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_COMBOSIGNALS :Keretapi landasan dengan isyarat pra- dan kombo -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_PBSSIGNALS :Keretapi landasan dengan isyarat pra- dan laluan -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_NOENTRYSIGNALS :Keretapi landasan dengan isyarat pra- dan satu hala +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_EXITSIGNALS :Landasan kereta api dengan pra-isyarat dan isyarat keluar +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_COMBOSIGNALS :Landasan kereta api dengan pra-isyarat dan isyarat kombo +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_PBSSIGNALS :Landasan kereta api dengan pra-isyarat dan isyarat laluan +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_NOENTRYSIGNALS :Landasan kereta api dengan pra-isyarat dan isyarat laluan satu hala STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_COMBOSIGNALS :Landasan keretapi dengan isyarat keluar dan kombo. STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_PBSSIGNALS :Landasan keretapi dengan isyarat keluar dan laluan STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_NOENTRYSIGNALS :Landasan keretapi dengan isyarat keluar dan satu hala STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_PBSSIGNALS :Landasan keretapi dengan isyarat kombo dan signal laluan STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_NOENTRYSIGNALS :Landasan keretapi dengan isyarat kombo dan satu hala -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBS_NOENTRYSIGNALS :Keretapi landasan dengan isyarat laluan dan satu hala -STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT :Keretapi depoh keretapi +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBS_NOENTRYSIGNALS :Landasan kereta api dengan isyarat laluan dan isyarat laluan satu hala +STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT :Depoh penyelenggaraan kereta api STR_LAI_ROAD_DESCRIPTION_ROAD :Jalanraya STR_LAI_ROAD_DESCRIPTION_ROAD_WITH_STREETLIGHTS :Jalan raya berlampu @@ -2408,6 +2428,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Hakcipta STR_ABOUT_VERSION :{BLACK}OpenTTD versi {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2018 The OpenTTD team +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Simpankan Permainan STR_SAVELOAD_LOAD_CAPTION :{WHITE}Buka Permainan @@ -2555,6 +2582,7 @@ STR_NEWGRF_SETTINGS_INCOMPATIBLE :{RED}Tidak sera # NewGRF save preset window STR_SAVE_PRESET_CAPTION :{WHITE}Simpan pratetapan STR_SAVE_PRESET_TITLE :{BLACK}Masukkan nama untuk pratetapan +STR_SAVE_PRESET_CANCEL :{BLACK}Batal STR_SAVE_PRESET_SAVE :{BLACK}Simpan # NewGRF parameters window @@ -2586,7 +2614,7 @@ STR_SPRITE_ALIGNER_GOTO_TOOLTIP :{BLACK}Pergi ke STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Peperi sebelumnya STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Teruskan ke peperi dahulu yang biasa, melangkau sebarang peperi pseudo/warna kembali/fon dan memusing balik semula STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Perwakilan peperi yang terpilih. Penjajaran tidak diendahkan apabila sedang melukiskan peperi. -STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Alih peperi, mengubahkan ofset X dan Y +STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Alihkan "sprite" ke lokasi lain lantas mengubah ofset X dan Y. "Ctrl+Click" untuk ubah lokasi "sprite" lapan unit pada satu-satu masa STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}Pilih peperi STR_SPRITE_ALIGNER_PICKER_TOOLTIP :{BLACK}Pilih peperi di mana-mana sahaja dari skrin @@ -2686,8 +2714,6 @@ STR_TOWN_POPULATION :{BLACK}Jumlah p STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Bandaraya) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Jumlah penduduk: {ORANGE}{COMMA}{BLACK} Rumah: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Penumpang bulan lalu: {ORANGE}{COMMA}{BLACK} maks: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Beg surat bulan lepas: {ORANGE}{COMMA}{BLACK} maks: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Kargi yang diperlukan untuk pembesaran bandar: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} diperlukan STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} diperlukan sewaktu musim sejuk @@ -2782,6 +2808,7 @@ STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Klik di # Story book window STR_STORY_BOOK_TITLE :{YELLOW}{STRING} +STR_STORY_BOOK_NEXT_PAGE :{BLACK}Seterusnya # Station list window STR_STATION_LIST_TOOLTIP :{BLACK}Nama stesen - klik pada nama untuk memusatkan pemandangan ke stesen. Ctrl+Klik membuka tetingkap pemandangan di lokasi stesen @@ -2808,6 +2835,10 @@ STR_STATION_VIEW_RATINGS_BUTTON :{BLACK}Penarafa STR_STATION_VIEW_RATINGS_TOOLTIP :{BLACK}Tunjukkan penarafan stesen STR_STATION_VIEW_SUPPLY_RATINGS_TITLE :{BLACK}Bekalan bulanan dan penarafan tempatan: +STR_STATION_VIEW_PLANNED_AMOUNT :Jumlah: Telah dirancang +STR_STATION_VIEW_VIA :{YELLOW}{CARGO_SHORT} melalui {STATION} +STR_STATION_VIEW_TO :{YELLOW}{CARGO_SHORT} ke {STATION} +STR_STATION_VIEW_VIA_HERE :{GREEN}{CARGO_SHORT} sedang berhenti di stesen ini ############ range for rating starts @@ -2825,12 +2856,13 @@ STR_STATION_VIEW_CENTER_TOOLTIP :{BLACK}Pusatkan STR_STATION_VIEW_RENAME_TOOLTIP :{BLACK}Tukarkan nama stesen STR_STATION_VIEW_SCHEDULED_TRAINS_TOOLTIP :{BLACK}Tunjukkan semua keretapi yang mengandungi stesen ini dalam jadual mereka -STR_STATION_VIEW_SCHEDULED_ROAD_VEHICLES_TOOLTIP :{BLACK}Tunjukkan semua kenderaan jalanraya yang mengandungi stesen ini dalam jadual mereka +STR_STATION_VIEW_SCHEDULED_ROAD_VEHICLES_TOOLTIP :{BLACK}Tunjukkan semua kenderaan darat yang mempunyai stesen ini di dalam jadual mereka STR_STATION_VIEW_SCHEDULED_AIRCRAFT_TOOLTIP :{BLACK}Tunjukkan semua pesawat yang mengandungi lapangan terbang ini dalam jadual mereka STR_STATION_VIEW_SCHEDULED_SHIPS_TOOLTIP :{BLACK}Tunjukkan semua kapal yang mengandungi stesen ini dalam jadual mereka STR_STATION_VIEW_RENAME_STATION_CAPTION :Namakan semula stesen/ruang punggahan +STR_STATION_VIEW_CLOSE_AIRPORT_TOOLTIP :{BLACK}Halang pesawat daripada mendarat di lapangan terbang ini # Waypoint/buoy view window STR_WAYPOINT_VIEW_CAPTION :{WHITE}{WAYPOINT} @@ -3012,11 +3044,11 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Kenderaan jalan STR_GROUP_DEFAULT_SHIPS :Kapal yang belum berkumpulan STR_GROUP_DEFAULT_AIRCRAFTS :Pesawat yang belum berkumpulan -STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Kumpulan - klik sebuah kumpulan untuk menaraikan semua kenderaan di dalam kumpulan +STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Kumpulan - klik sebuah kumpulan untuk menyenaraikan semua kenderaan di dalam kumpulan tersebut. Tarik dan lepaskan kumpulan untuk menyusun kumpulan mengikut heirarki STR_GROUP_CREATE_TOOLTIP :{BLACK}Klik untuk mewujudkan kumpulan STR_GROUP_DELETE_TOOLTIP :{BLACK}Padamkan kumpulan yang telah dipilih STR_GROUP_RENAME_TOOLTIP :{BLACK}Tukar nama kumpulan yang terpilih -STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Klik untuk menghalang daripada kumpulan ini digantikan secara automatik +STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Klik untuk menghalang kumpulan ini daripada digantikan secara automatik STR_GROUP_ADD_SHARED_VEHICLE :Tambah kenderaan berkongsi @@ -3304,6 +3336,8 @@ STR_VEHICLE_INFO_AGE :{COMMA} tahun ( STR_VEHICLE_INFO_AGE_RED :{RED}{COMMA} tahun ({COMMA}) STR_VEHICLE_INFO_MAX_SPEED :{BLACK}Kelajuan Maks.: {LTBLUE}{VELOCITY} +STR_VEHICLE_INFO_MAX_SPEED_TYPE :{BLACK}Kelajuan maksima: {LTBLUE}{VELOCITY} {BLACK}Jenis pesawat: {LTBLUE}{STRING} +STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE :{BLACK}Kelajuan maksima: {LTBLUE}{VELOCITY} {BLACK}Jenis pesawat: {LTBLUE}{STRING} {BLACK}Lingkungan: {LTBLUE}{COMMA} petak STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Berat: {LTBLUE}{WEIGHT_SHORT} {BLACK}Kuasa: {LTBLUE}{POWER}{BLACK} Kelajuan Maks.: {LTBLUE}{VELOCITY} STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Berat: {LTBLUE}{WEIGHT_SHORT} {BLACK}Kuasa: {LTBLUE}{POWER}{BLACK} Max. speed: {LTBLUE}{VELOCITY} {BLACK}T.E. Maks.: {LTBLUE}{FORCE} @@ -3323,6 +3357,7 @@ STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT :{BLACK}Tempoh P STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP :{BLACK}Tambah 10 tempoh penyenggelaraan. Ctrl+Klik untuk tambah 5 tempoh penyenggelaraan STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP :{BLACK}Kurangkan 10 tempoh penyenggelaraan. Ctrl+Klik untuk kurangkan 5 tempoh penyenggelaraan +STR_VEHICLE_DETAILS_DAYS :Hari STR_VEHICLE_DETAILS_PERCENT :Peratusan STR_QUERY_RENAME_TRAIN_CAPTION :{WHITE}Nama keretapi @@ -3462,7 +3497,7 @@ STR_ORDER_GO_TO_NEAREST_DEPOT :Pergi ke depoh STR_ORDER_GO_TO_NEAREST_HANGAR :Pergi ke hangar paling hampir STR_ORDER_CONDITIONAL :Lompatan arahan bersyarat STR_ORDER_SHARE :Kongsi arahan -STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Masukkan arahan baru ke atas arahan yang terpilih. Ctrl membuatkan arahan stesen 'muatan penuh sebarang kargo', arahan halutuju 'tanpa henti', dan arahn depoh 'penyenggelaraan'. 'Arahan berkongsi' atau Ctrl membenarkan kenderaan ini berkongsi arahan dengan kenderaan terpilih +STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Masukkan arahan baru ke dalam susunan senarai yang terpilih, atau tambah pada penghujung senarai. "Ctrl" mengubah arahan stesen kepada 'muatan penuh untuk apa-apa kargo', arahan halutuju 'tanpa henti', dan arahan depoh 'penyenggelaraan'. 'Arahan berkongsi' atau "Ctrl" membenarkan kenderaan ini berkongsi arahan dengan kenderaan terpilih STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP :{BLACK}Tunjukkan semua kenderaan yang berkongsi jadual yang sama @@ -3843,7 +3878,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Terlampa STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Terlampau banyak bahagian-bahagian stesen keretapi STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Terlampau banyak stesen bas STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Terlampau banyak ruang punggah lori -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Terlalu hampir dengan stesen/kawasan muatan lain STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Terlalu hampir dengan pelabuhan lain STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Terlalu hampir dengan lapangan terbang lain STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Nama stesen tidak dapat ditukar... @@ -4079,7 +4113,7 @@ STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... pesa # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Kenderaan tidak boleh dijadualkan... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Kenderaan hanya boleh menunggu di stesen -STR_ERROR_TIMETABLE_NOT_STOPPING_HERE :{WHITE}Kenderaan ini tidak akan berhenti di stesen ini +STR_ERROR_TIMETABLE_NOT_STOPPING_HERE :{WHITE}Kenderaan ini tidak akan berhenti di stesen berikut # Sign related errors STR_ERROR_TOO_MANY_SIGNS :{WHITE}... papan tanda terlalu banyak @@ -4092,8 +4126,12 @@ STR_DESKTOP_SHORTCUT_COMMENT :Sebuah permaina # Translatable descriptions in media/baseset/*.ob* files STR_BASEGRAPHICS_DOS_DESCRIPTION :Grafik asal Transport Tycoon Deluxe DOS edition. +STR_BASEGRAPHICS_DOS_DE_DESCRIPTION :Grafik asal Transport Tycoon DOS (German) edition STR_BASEGRAPHICS_WIN_DESCRIPTION :Grafik asal Transport Tycoon Deluxe edisi Windows. +STR_BASESOUNDS_WIN_DESCRIPTION :Bunyi asal Transport Tycoon Deluxe edisi Windows +STR_BASESOUNDS_NONE_DESCRIPTION :Sebuah pek suara tanpa apa-apa suara STR_BASEMUSIC_WIN_DESCRIPTION :Muzik asal Transport Tycoon Deluxe edisi Windows. +STR_BASEMUSIC_DOS_DESCRIPTION :Muzik asal Transport Tycoon Deluxe edisi DOS STR_BASEMUSIC_NONE_DESCRIPTION :Pek muzik tanpa muzik sebenar. ##id 0x2000 diff --git a/src/lang/norwegian_bokmal.txt b/src/lang/norwegian_bokmal.txt index dccf73075f..65c4e10c7f 100644 --- a/src/lang/norwegian_bokmal.txt +++ b/src/lang/norwegian_bokmal.txt @@ -671,10 +671,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Velg pro STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Skru av/på tilfeldig program STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Vis musikkspormeny -STR_ERROR_NO_SONGS :{WHITE}Et musikksett uten sanger er valgt. Ingen sanger vil bli avspilt - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Musikkprogram STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Sporliste STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Program - '{STRING}' @@ -1340,8 +1337,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Farge på terre STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Grønn STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Mørkegrønn STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Fiolett -STR_CONFIG_SETTING_REVERSE_SCROLLING :Snu rulleretningen: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Opptreden ved rulling av kartet med høyre museknapp. Når deaktivert, beveger musen kameraet. Når aktivert, beveger musen kartet STR_CONFIG_SETTING_SMOOTH_SCROLLING :Myk rulling: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Velge hvordan synsfeltet ruller til en bestemt posisjon når du klikker på det lille kartet, eller ved utstedelse av en kommando for å gå til et bestemt objekt på kartet. Hvis aktivert, ruller synsfeltet jevnt, og hvis deaktivert hopper det direkte til det valgte punktet STR_CONFIG_SETTING_MEASURE_TOOLTIP :Vis målingsverktøy ved bruk av byggingsverktøy: {STRING} @@ -1373,8 +1368,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Kommando+klikk STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+klikk STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Av -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Venstre-klikk rulling: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Tillat rulling av kartet ved å dra det med den venstre museknappen. Dette er spesielt nyttig når du bruker en berøringsskjerm STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Lukk vinduet med høyreklikk: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Lukker et vindu ved å høyreklikke i det. Deaktiverer verktøytipset med høyreklikk! @@ -2697,6 +2690,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Opprinne STR_ABOUT_VERSION :{BLACK}OpenTTD versjon {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 OpenTTD-teamet +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Lagre spill STR_SAVELOAD_LOAD_CAPTION :{WHITE}Last inn spill @@ -2988,8 +2988,6 @@ STR_TOWN_POPULATION :{BLACK}Verdensb STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (By) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Innbyggertall: {ORANGE}{COMMA}{BLACK} Antall hus: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passasjerer forrige måned: {ORANGE}{COMMA}{BLACK} maks: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Post forrige måned: {ORANGE}{COMMA}{BLACK} maks: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Varebehov for byvekst: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} påkrevd STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} nødvendig om vinteren @@ -4229,7 +4227,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}For mang STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}For mange enkeltdeler på jernbanestasjonen STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}For mange bussholdeplasser STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}For mange lasteterminaler -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}For nærme en annen stasjon/lasteterminal STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}For nærme enn annen havn STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}For nærme en annen flyplass STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Kan ikke endre stasjonens navn... diff --git a/src/lang/norwegian_nynorsk.txt b/src/lang/norwegian_nynorsk.txt index 5e545ce290..93db95f84b 100644 --- a/src/lang/norwegian_nynorsk.txt +++ b/src/lang/norwegian_nynorsk.txt @@ -671,10 +671,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Vel 'Eig STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Skru tilfeldig program av/på STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Syne musikkspormeny -STR_ERROR_NO_SONGS :{WHITE}Eit musikksett utan songar har blitt valt. Ingen songar vil bli spelt - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Musikkprogram STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Sporregister STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Program - '{STRING}' @@ -1311,7 +1308,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Farge på terre STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Grøn STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Mørkegrøn STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Fiolett -STR_CONFIG_SETTING_REVERSE_SCROLLING :Snu rulleretninga: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING :Jamn rulling i tilleggsvindauge: {STRING} STR_CONFIG_SETTING_MEASURE_TOOLTIP :Syne eit målingverktøytips når ymse byggjeverktøy brukast: {STRING} STR_CONFIG_SETTING_LIVERIES :Syne firmaovertakingar: {STRING} @@ -1338,7 +1334,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Kommando+klikk STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :CTRL+klikk STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Av -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Venstreknapps-rulling: {STRING} STR_CONFIG_SETTING_AUTOSAVE :Autolaging: {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :Vel intervall for automatisk lagring av spel @@ -2610,6 +2605,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Opphavel STR_ABOUT_VERSION :{BLACK}OpenTTD versjon {REV}. Oversett til nynorsk av Thor Morten Skogrand med fleire. STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 OpenTTD-teamet +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Lagre spel STR_SAVELOAD_LOAD_CAPTION :{WHITE}Last inn spel @@ -2897,8 +2899,6 @@ STR_TOWN_POPULATION :{BLACK}Verdsinn STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (By) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Innbyggjartal: {ORANGE}{COMMA}{BLACK} Antal hus: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passasjerar førre månad: {ORANGE}{COMMA}{BLACK} maks.: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Post førre månad: {ORANGE}{COMMA}{BLACK} maks.: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Varer naudsynt for folketalsauke: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} naudsynt STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} naudsynt om vinteren @@ -4119,7 +4119,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}For mang STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}For mange togstasjon-delar STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}For mange busshaldeplassar STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}For mange lasteterminalar -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}For nær ein annan jernbanestasjon/lasteterminal STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}For nær ei anna hamn STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}For nær ein annan flyplass STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Kan ikkje endre namnet på stasjonen... diff --git a/src/lang/polish.txt b/src/lang/polish.txt index cc3f06cffe..965c08cb42 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -1029,6 +1029,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}Brak dostępnej muzyki STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Ścieżka STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Tytuł @@ -1048,14 +1049,12 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Wybierz STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Losowe odtwarzanie wł./wył. STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Pokaż okno wyboru ścieżek -STR_ERROR_NO_SONGS :{WHITE}Został wybrany zestaw muzyki bez utworów. Żaden utwór nie będzie odtwarzany - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Wybór Programu STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Wykaz ścieżek STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programuj - '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Wyczyść +STR_PLAYLIST_CHANGE_SET :{BLACK}Zmień zestaw STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Wyczyść obecny program (tylko Wlasny1 lub Wlasny2) STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Klik na ścieżce aby dodać do obecnego programu (Wlasny1 i Wlasny2) STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Kliknij na ścieżce muzycznej aby usunąć ją z wybranego programu (Wlasny1 lub Wlasny2) @@ -1717,8 +1716,9 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Kolor terenu na STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :zielony STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :ciemnozielony STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :fioletowy -STR_CONFIG_SETTING_REVERSE_SCROLLING :Przewijaj obraz myszką w przeciwnym kierunku: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Zachowanie podczas przewijania mapy za pomocą prawego przycisku myszy. W przypadku wyłączenia mysz porusza kamerą. Po włączeniu mysz przesuwa mapę +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Zachowanie podczas przeciągania mapy +STR_CONFIG_SETTING_SCROLLMODE_RMB :Przeciągnij mapę prawym przyciskiem myszy +STR_CONFIG_SETTING_SCROLLMODE_LMB :Przeciągnij mapę lewym przyciskiem myszy STR_CONFIG_SETTING_SMOOTH_SCROLLING :Wygładź przesuwanie widoku: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Zdecyduj, jak główny widok przesuwa się do konkretnej lokacji, gdy klikasz na mini-mapie lub gdy używasz komendy do przesunięcia do danego obiektu na mapie. Kiedy włączone, widok przesuwa się płynnie, kiedy wyłączone, następuje skok bezpośrednio do wybranego miejsca STR_CONFIG_SETTING_MEASURE_TOOLTIP :Pokaż dymek z pomiarem podczas używania różnych narzędzi: {STRING} @@ -1750,8 +1750,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command+klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Wyłączona -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Przewijanie lewym przyciskiem myszy: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Włącz przewijanie mapy przeciąganiem lewym przyciskiem myszki. Jest to przydatne podczas używania ekranu dotykowego do przewijania STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Zamknij okno prawym przyciskiem: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Zamyka okno poprzez kliknięcie prawym przyciskiem. Wyłącza pomoc kontekstową! @@ -3073,6 +3071,20 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Prawa Au STR_ABOUT_VERSION :{BLACK}OpenTTD wersja {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2018 Zespół OpenTTD +# Framerate display window +STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Liczba renderowanych klatek wideo na sekundę. +STR_FRAMERATE_CURRENT :{WHITE}Obecny +############ Leave those lines in this order!! +STR_FRAMERATE_GL_LINKGRAPH :{WHITE} Opóźnienie wykresu połączeń: +STR_FRAMERATE_VIDEO :{WHITE}Wyjście video: +STR_FRAMERATE_SOUND :{WHITE}Miksowanie dźwięku: +############ End of leave-in-this-order +############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_VIDEO :Wyjście wideo +STR_FRAMETIME_CAPTION_SOUND :Miksowanie dźwięku +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Zapisz grę STR_SAVELOAD_LOAD_CAPTION :{WHITE}Wczytaj grę @@ -3364,8 +3376,7 @@ STR_TOWN_POPULATION :{BLACK}Populacj STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Miasto) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Populacja: {ORANGE}{COMMA}{BLACK} Domów: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Pasażerów w zeszłym miesiącu: {ORANGE}{COMMA}{BLACK} maks: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Poczta w zeszłym miesiącu: {ORANGE}{COMMA}{BLACK} maks: {ORANGE}{COMMA} +STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} w ostatnim miesiącu: {ORANGE}{COMMA}{BLACK} najwięcej: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Towar potrzebny do rozwoju miasta: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{RED}Wymagana {ORANGE}{STRING} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} wymagane zimą @@ -4610,7 +4621,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Za duzo STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Za dużo części stacji kolejowej STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Zbyt wiele przystanków autobusowych STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Zbyt wiele stacji załadunku ciężarówek -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Zbyt blisko innej stacji/strefy załadunku STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Zbyt blisko innego portu STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Zbyt blisko innego lotniska STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Nie można zmienić nazwy stacji... @@ -4618,6 +4628,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... ta d STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... droga jest zorientowana w złym kierunku STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... przystanki przelotowe nie mogą mieć zakrętów STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... przystanki przelotowe nie mogą mieć skrzyżowań +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... droga jest jednokierunkowa lub zablokowana # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Nie można usunąć części stacji... @@ -4869,6 +4880,8 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Oryginalna edyc STR_BASESOUNDS_WIN_DESCRIPTION :Oryginalna edycja dźwięków dla Transport Tycoon Deluxe Windows. STR_BASESOUNDS_NONE_DESCRIPTION :Zestaw dźwięków nie zawierający żadnych dźwięków. STR_BASEMUSIC_WIN_DESCRIPTION :Oryginalna edycja utworów muzycznych w Transport Tycoon Deluxe Windows. +STR_BASEMUSIC_DOS_DESCRIPTION :Oryginalna edycja utworów muzycznych dla Transport Tycoon Deluxe DOS. +STR_BASEMUSIC_TTO_DESCRIPTION :Oryginalna edycja utworów muzycznych dla Transport Tycoon DOS. STR_BASEMUSIC_NONE_DESCRIPTION :Zestaw utworów muzycznych nie zawierający żadnej muzyki. ##id 0x2000 diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index 65ad9c6661..d9c00b1101 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -670,10 +670,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Seleccio STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Ligar/Desligar programa aleatório STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Mostrar janela de selecção de faixas de música -STR_ERROR_NO_SONGS :{WHITE}Um conjunto de música vazio foi seleccionado. Nenhuma música vai ser tocada. - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Programação Musical STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} '{STRING}' STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Índice de faixas STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programa - '{STRING}' @@ -1338,8 +1335,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Cor do terreno STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Verde STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Verde Escuro STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Violeta -STR_CONFIG_SETTING_REVERSE_SCROLLING :Ao deslizar com o rato, mover a vista na direcção oposta: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Comportamento ao navegar pelo mapa com o botão direito do rato. Quando desactivado, o rato move a câmara. Quando activo, o rato move o mapa STR_CONFIG_SETTING_SMOOTH_SCROLLING :Suavizar deslocamento da navegação no mapa: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Controla como a vista principal navega para uma posição específica ao clicar no mapa pequeno ou ao dar um comando para navegar para um objecto específico no mapa. Se activo, a vista principal navega suavemente, se inactivo a vista salta directamente para o destino. STR_CONFIG_SETTING_MEASURE_TOOLTIP :Mostrar medidas nas várias ferramentas de construção: {STRING} @@ -1371,8 +1366,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND : + Cli STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL : + clique STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Desligado -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Deslocar com botão esquerdo: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Activar deslocamento do mapa através de arrastamento com o botão esquerdo do rato. Esta opção é particularmente útil quando é usado um ecran de toque para deslocamento STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Fechar janelas ao fazer clique direito: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Fecha uma janela ao fazer clique direito dentro dela. Desactiva os textos de ajuda ao fazer clique direito! @@ -1840,8 +1833,8 @@ STR_LIVERY_TRUCK :Veículo de Mer STR_LIVERY_PASSENGER_SHIP :Barco de Passageiros STR_LIVERY_FREIGHT_SHIP :Barco Cargueiro STR_LIVERY_HELICOPTER :Helicóptero -STR_LIVERY_SMALL_PLANE :Aeronave de Pequenas Dimensões -STR_LIVERY_LARGE_PLANE :Aeronave de Grandes Dimensões +STR_LIVERY_SMALL_PLANE :Avião de Pequenas Dimensões +STR_LIVERY_LARGE_PLANE :Avião de Grandes Dimensões STR_LIVERY_PASSENGER_TRAM :Eléctrico de Passageiros STR_LIVERY_FREIGHT_TRAM :Eléctrico de Mercadorias @@ -2694,6 +2687,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Direitos STR_ABOUT_VERSION :{BLACK}OpenTTD versão {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 A equipa do OpenTTD +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Guardar Jogo STR_SAVELOAD_LOAD_CAPTION :{WHITE}Abrir Jogo @@ -2985,8 +2985,6 @@ STR_TOWN_POPULATION :{BLACK}Populaç STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Metrópole) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}População: {ORANGE}{COMMA}{BLACK} Casas: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passageiros no último mês: {ORANGE}{COMMA}{BLACK} máx: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Correio no último mês: {ORANGE}{COMMA}{BLACK} máx: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Mercadoria necessária para o seu desenvolvimento: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{RED}É necessário {ORANGE}{STRING} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{BLACK}No inverno, é necessário {ORANGE}{STRING} @@ -4225,7 +4223,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Demasiad STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Demasiadas partes na estação ferroviária STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Demasiadas paragens de autocarro STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Demasiadas estações de carga -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Muito junto de uma estação/local de carga STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Muito perto de outra doca STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Demasiado perto de outro aeroporto STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Não pode alterar o nome da estação... diff --git a/src/lang/romanian.txt b/src/lang/romanian.txt index a2aa17927e..6b891bb7e8 100644 --- a/src/lang/romanian.txt +++ b/src/lang/romanian.txt @@ -669,10 +669,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Selectea STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Comutator pentru amestecarea melodiilor (pornit/oprit) STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Afişeaza fereastra pentru selecţia melodiilor -STR_ERROR_NO_SONGS :{WHITE}A fost selectat un set de muzică fără melodii. Nici o melodie nu va fi cântată - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Programare piese muzicale STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Lista melodiilor STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Program - '{STRING}' @@ -1322,8 +1319,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Culoarea terenu STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Verde STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Verde închis STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Mov -STR_CONFIG_SETTING_REVERSE_SCROLLING :Inversează direcţia de scroll: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Modul de funcționare in momentul folosirii butonului drept al mouse-ului pentru deplasare pe hartă. Când opțiunea este dezactivată, mouse-ul schimbă poziția camerei. La activare, mouse-ul desplasează harta. STR_CONFIG_SETTING_SMOOTH_SCROLLING :Derulare uşoară ecran: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Controlează modul de deplasare a imaginii din ecranul principal când se face click pe harta mică sau când se execută o comandă de deplasare către un obiect anume de pe hartă. Dacă este activată, imaginea se deplasează în mod fluid, altfel imaginea sare direct la zona dorită STR_CONFIG_SETTING_MEASURE_TOOLTIP :Arată o indicaţie de distanţă la folosirea uneltelor de construcţie: {STRING} @@ -1355,8 +1350,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Comandă+Click STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Control+Click STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Oprit -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Derulare ecran cu click-stânga: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Activează derularea hărții prin tragerea acesteia cu butonul stâng al mouse-ului. Această opțiune este în special utilă când se folosește un ecran tactil pentru deplasare STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES :Foloseşte formatul datei {STRING} pentru numele salvărilor @@ -2654,6 +2647,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Copyrigh STR_ABOUT_VERSION :{BLACK}OpenTTD versiunea {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 Echipa OpenTTD +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Salvează joc STR_SAVELOAD_LOAD_CAPTION :{WHITE}Încarcă joc @@ -2939,8 +2939,6 @@ STR_TOWN_POPULATION :{BLACK}Populaţ STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Metropolă) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Populaţia: {ORANGE}{COMMA}{BLACK} Locuinţe: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Călători luna trecută: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Colete poştale luna trecută: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Transporturi necesare dezvoltării oraşului: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} necesare STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} necesare iarna @@ -4159,7 +4157,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Prea mul STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Staţia are prea multe componente STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Prea multe staţii de autobuz STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Prea multe staţii de camion -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Prea aproape de altă staţie STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Prea aproape de alt port STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Prea aproape de un alt aeroport STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Nu se poate redenumi staţia... diff --git a/src/lang/russian.txt b/src/lang/russian.txt index 45b3be2c6d..22eaeb0782 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -601,6 +601,7 @@ STR_ABOUT_MENU_SCREENSHOT :Снимок э STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Снимок экрана в макс. приближении STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Снимок экрана в обычном масштабе STR_ABOUT_MENU_GIANT_SCREENSHOT :Снимок всей карты +STR_ABOUT_MENU_SHOW_FRAMERATE :Показать кол-во кадров/с STR_ABOUT_MENU_ABOUT_OPENTTD :Об игре STR_ABOUT_MENU_SPRITE_ALIGNER :Выравнивание спрайтов STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Переключить ограничивающие рамки @@ -788,8 +789,9 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}Музыкальное оформление недоступно STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}«{STRING}» -STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Дорожка +STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Трек STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Название STR_MUSIC_SHUFFLE :{TINY_FONT}{BLACK}Случ. выбор STR_MUSIC_PROGRAM :{TINY_FONT}{BLACK}Программа @@ -807,17 +809,17 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Выбо STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Вкл./Выкл. случайный выбор программы STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Показать окно выбора музыкальных треков -STR_ERROR_NO_SONGS :{WHITE}В выбранном музыкальном наборе отсутствует музыка. - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Выбор программы воспроизведения +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Музыкальная программа - '{STRING}' STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} «{STRING}» STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Номер трека STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Программа - «{STRING}» STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Очистить +STR_PLAYLIST_CHANGE_SET :{BLACK}Изменить набор STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Очистка пользовательской программы +STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Сменить выбор музыкального оформления на другой установленный набор STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Щёлкните по названию трека для добавления в пользовательскую программу -STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Выберите дорожку для удаления из пользовательского списка +STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Выберите трек для удаления из пользовательского списка # Highscore window STR_HIGHSCORE_TOP_COMPANIES_WHO_REACHED :{BIG_FONT}{BLACK}Крупнейшие компании, достигшие {NUM} года @@ -958,6 +960,7 @@ STR_NEWS_MERGER_TAKEOVER_TITLE :{BIG_FONT}{BLAC STR_PRESIDENT_NAME_MANAGER :{BLACK}{PRESIDENT_NAME}{}(Директор) STR_NEWS_NEW_TOWN :{BLACK}{BIG_FONT}Компания «{STRING}» профинансировала основание города {TOWN}! +STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK}{BIG_FONT}Основан новый город - {TOWN}! STR_NEWS_INDUSTRY_CONSTRUCTION :{BIG_FONT}{BLACK}Новое предприятие! {STRING} стро{G 0 и и и я}тся возле г.{NBSP}{TOWN}! STR_NEWS_INDUSTRY_PLANTED :{BIG_FONT}{BLACK}Новое предприятие! {STRING} заложен{G 0 "" а о ы} возле г.{NBSP}{TOWN}! @@ -1025,9 +1028,9 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC # Extra view window STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Окно просмотра {COMMA} -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Скопировать в окно -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Скопировать текущую позицию в окно просмотра -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Вставить из окна +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Из основного окна +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Показать то, что отображается в основном окне +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}В основное окно STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Показать в основном окне # Game options window @@ -1070,15 +1073,16 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :Южноафр STR_GAME_OPTIONS_CURRENCY_CUSTOM :Своя... STR_GAME_OPTIONS_CURRENCY_GEL :Грузинский лари (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :Иранский риал (IRR) +STR_GAME_OPTIONS_CURRENCY_RUB :Российский новый рубль (RUR) ############ end of currency region -STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Направление движения -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_TOOLTIP :{BLACK}По какой стороне дороги ездит автотранспорт -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :левостороннее -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :правостороннее +STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Движение автомобилей +STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_TOOLTIP :{BLACK}Сторона дороги, по которой ездит автотранспорт +STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Левостороннее +STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Правостороннее STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Названия городов -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}На каком языке будут названы населённые пункты +STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Язык, который будет использоваться для выбора названий населённых пунктов ############ start of townname region STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Английские @@ -1173,7 +1177,7 @@ STR_CURRENCY_DECREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Пере STR_CURRENCY_INCREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Перейти на евро позже STR_CURRENCY_PREVIEW :{LTBLUE}Образец: {ORANGE}{CURRENCY_LONG} -STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 англ. фунтов (£) в вашей валюте +STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10{NBSP}000 фунтов стерлингов (£) в вашей валюте STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Изменить параметр валюты STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Максимальное количество конкурентов: {ORANGE}{COMMA} @@ -1257,7 +1261,7 @@ STR_CONFIG_SETTING_RESTRICT_TYPE :{BLACK}Тип: STR_CONFIG_SETTING_RESTRICT_DROPDOWN_HELPTEXT :{BLACK}Отображать в списке только настройки, соответствующие выбранной категории STR_CONFIG_SETTING_RESTRICT_BASIC :Основные настройки (только самые важные) STR_CONFIG_SETTING_RESTRICT_ADVANCED :Расширенные настройки (практически все) -STR_CONFIG_SETTING_RESTRICT_ALL :Специальные настройки (все, включая самые непонятные) +STR_CONFIG_SETTING_RESTRICT_ALL :Все настройки (включая самые непонятные) STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_DEFAULT :Настройки со значениями, отличающимися от значений по умолчанию STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_NEW :Настройки со значениями, отличающимися от настроек новой игры @@ -1489,9 +1493,13 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Цвет лан STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :зелёный STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :тёмно-зелёный STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :фиолетовый -STR_CONFIG_SETTING_REVERSE_SCROLLING :Обратить направление перемещения обзора мышью: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Настройка смещения обзора правой кнопкой мыши.{}Если отключено, мышь двигает камеру.{}Если включено, мышь двигает карту. -STR_CONFIG_SETTING_SMOOTH_SCROLLING :Плавное смещение обзора: {STRING} +STR_CONFIG_SETTING_SCROLLMODE :Перемещение обзора: {STRING} +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Способ перемещения по игровому полю +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Перемещать с помощью ПКМ, зафиксировав курсор +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Перемещать с помощью ПКМ, зафиксировав курсор +STR_CONFIG_SETTING_SCROLLMODE_RMB :Перемещать с помощью ПКМ +STR_CONFIG_SETTING_SCROLLMODE_LMB :Перемещать с помощью ЛКМ +STR_CONFIG_SETTING_SMOOTH_SCROLLING :Плавное перемещение: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Настройка перемещения обзора в основном окне при щелчке по миникарте или по команде обзора какого-нибудь объекта. Если включено, то обзор смещается плавно; если отключено - то мгновенно. STR_CONFIG_SETTING_MEASURE_TOOLTIP :Показывать замеры при строительстве: {STRING} STR_CONFIG_SETTING_MEASURE_TOOLTIP_HELPTEXT :Показывать расстояния и разницу высот при строительстве @@ -1500,8 +1508,8 @@ STR_CONFIG_SETTING_LIVERIES_HELPTEXT :Включит STR_CONFIG_SETTING_LIVERIES_NONE :нет STR_CONFIG_SETTING_LIVERIES_OWN :только для своей компании STR_CONFIG_SETTING_LIVERIES_ALL :для всех компаний -STR_CONFIG_SETTING_PREFER_TEAMCHAT :Открывать командный чат при нажатии Enter: {STRING} -STR_CONFIG_SETTING_PREFER_TEAMCHAT_HELPTEXT :Настроить внутрикорпоративный чат на клавишу «Enter», а общий - на «Ctrl+Enter» +STR_CONFIG_SETTING_PREFER_TEAMCHAT :Использовать Enter для командного чата: {STRING} +STR_CONFIG_SETTING_PREFER_TEAMCHAT_HELPTEXT :Использовать «Enter» для командного чата, а «Ctrl+Enter» - для общего STR_CONFIG_SETTING_SCROLLWHEEL_SCROLLING :Использовать колесо прокрутки: {STRING} STR_CONFIG_SETTING_SCROLLWHEEL_SCROLLING_HELPTEXT :Можно настроить смещение обзора с помощью качающегося колеса прокрутки STR_CONFIG_SETTING_SCROLLWHEEL_ZOOM :для масштабирования @@ -1522,8 +1530,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Команд. STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Контрол. STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Выкл. -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Смещение обзора по нажатию левой кнопки мыши: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Смещение обзора левой кнопкой мыши. Это удобно при использовании сенсорного экрана. STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Закрывать окна щелчком ПКМ: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Закрывать окно щелчком правой кнопкой мыши в его пределах. При этом отключается появление подсказок по правой кнопке. @@ -1778,7 +1784,7 @@ STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Чем выше STR_CONFIG_SETTING_DEMAND_DISTANCE :Зависимость спроса от расстояния: {STRING} STR_CONFIG_SETTING_DEMAND_DISTANCE_HELPTEXT :Если это значение больше 0, то количество груза, отправляемого с одной станции на другую, будет зависеть от расстояния между станциями. Чем выше это значение, тем больше груза будет отправляться к ближним станциям и меньше{NBSP}- к дальним. STR_CONFIG_SETTING_DEMAND_SIZE :Количество возвращаемого груза при симметричном распределении: {STRING} -STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT :Установка этого значения ниже 100% заставит распределение быть менее «симметричным»: количество возвращаемого груза сможет быть меньше, чем количество отправленного. Установка в 0% сделает распределение полностью несимметричным. +STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT :Установка этого значения ниже 100% заставит распределение быть менее «симметричным»: количество возвращаемого груза сможет быть меньше, чем количество отправленного. Установка в 0% сделает распределение полностью асимметричным. STR_CONFIG_SETTING_SHORT_PATH_SATURATION :Предел загрузки коротких маршрутов перед использованием вместительных: {STRING} STR_CONFIG_SETTING_SHORT_PATH_SATURATION_HELPTEXT :При наличии нескольких маршрутов между станциями алгоритм распределения грузов будет использовать кратчайший маршрут до его загрузки, потом следующий по длине и т.{NBSP}д. При избытке груза маршруты будут перегружаться начиная с самых производительных. Загрузка рассчитывается исходя из оценки пропускной способности (которая может быть неточной) и интенсивности использования. Эта настройка определяет, насколько загружать маршрут перед тем, как начать использовать следующий. Установите значение ниже 100% для того, чтобы избежать задержки груза, если пропускная способность маршрута будет переоценена алгоритмом. @@ -2453,6 +2459,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Схем STR_LINKGRAPH_LEGEND_ALL :{BLACK}Все STR_LINKGRAPH_LEGEND_NONE :{BLACK}Нет STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Выберите компании для отображения +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}неиспольз. @@ -2873,6 +2880,28 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Ориг STR_ABOUT_VERSION :{BLACK}OpenTTD версия {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 Команда разработчиков OpenTTD +# Framerate display window +STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) +STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Кол-во игровых циклов, рассчитываемых в секунду. +STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Кол-во отображаемых кадров в секунду. +STR_FRAMERATE_DATA_POINTS :{BLACK}Данные по {COMMA} измерени{P ю ям ям} +STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} мс +STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} мс +STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} мс +STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} кадр{P "" а ов}/с +STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} кадр{P "" а ов}/с +STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} кадр{P "" а ов}/с +STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} мс +STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} с +############ Leave those lines in this order!! +STR_FRAMERATE_GL_LINKGRAPH :{BLACK} Задержка графа распределения: +############ End of leave-in-this-order +############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_GL_LINKGRAPH :Задержка графа распределения +STR_FRAMETIME_CAPTION_DRAWING :Отрисовка графики +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Сохранить игру STR_SAVELOAD_LOAD_CAPTION :{WHITE}Загрузить игру @@ -3157,15 +3186,15 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Введ STR_TOWN_DIRECTORY_CAPTION :{WHITE}Города STR_TOWN_DIRECTORY_NONE :{ORANGE}- Нет - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Список городов - щелчок по названию показывает город в основном окне. Ctrl+щелчок показывает в дополнительном окне. +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Мегаполис){BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Список городов. Щелчок по названию показывает город в основном окне. Ctrl+щелчок показывает в дополнительном окне. STR_TOWN_POPULATION :{BLACK}Население: {COMMA} # Town view window STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Мегаполис) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Население: {ORANGE}{COMMA}{BLACK} Зданий: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Пассажиров в прошлом месяце: {ORANGE}{COMMA}{BLACK}; макс.: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Почты в прошлом месяце: {ORANGE}{COMMA}{BLACK}; макс.: {ORANGE}{COMMA} +STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} в прошлом месяце: {ORANGE}{COMMA}{BLACK} Макс.: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Груз, необходимый для роста города: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} требу{G 0 е е е ю}тся STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} требу{G 0 е е е ю}тся зимой @@ -4414,7 +4443,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Слиш STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Слишком большая ж/д станция STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Слишком много автобусных остановок STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Слишком много грузовых терминалов -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Слишком близко к другой станции STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Слишком близко к другой пристани STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Слишком близко к другому аэропорту STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Невозможно переименовать станцию... @@ -4422,6 +4450,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... эт STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... неверное направление дороги STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... на проходных остановках нельзя делать повороты STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... на проходных остановках нельзя делать перекрёстки +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... дорога односторонняя или заблокирована # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Невозможно удалить часть станции... @@ -4490,7 +4519,7 @@ STR_ERROR_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Недо STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Сначала удалите сигналы STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Нет подходящих рельсов STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Сначала удалите рельсы -STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Дорога односторонняя или блокирована +STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Дорога односторонняя или заблокирована STR_ERROR_CROSSING_DISALLOWED :{WHITE}Через этот вид рельсов запрещено строить переезды STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Здесь невозможно поставить сигнал... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Здесь невозможно проложить рельсы... @@ -4666,13 +4695,15 @@ STR_ERROR_CAN_T_DELETE_SIGN :{WHITE}Не у STR_DESKTOP_SHORTCUT_COMMENT :Экономический симулятор на основе игры «Transport Tycoon Deluxe» # Translatable descriptions in media/baseset/*.ob* files -STR_BASEGRAPHICS_DOS_DESCRIPTION :Оригинальная графика из Transport Tycoon Deluxe для DOS. -STR_BASEGRAPHICS_DOS_DE_DESCRIPTION :Оригинальная графика из немецкой версии Transport Tycoon Deluxe для DOS. -STR_BASEGRAPHICS_WIN_DESCRIPTION :Оригинальная графика из Transport Tycoon Deluxe для Windows. -STR_BASESOUNDS_DOS_DESCRIPTION :Оригинальный набор звукового оформления из игры Transport Tycoon Deluxe для DOS. -STR_BASESOUNDS_WIN_DESCRIPTION :Оригинальный набор звукового оформления из игры Transport Tycoon Deluxe для Windows. +STR_BASEGRAPHICS_DOS_DESCRIPTION :Графика из Transport Tycoon Deluxe для DOS. +STR_BASEGRAPHICS_DOS_DE_DESCRIPTION :Графика из немецкой версии Transport Tycoon Deluxe для DOS. +STR_BASEGRAPHICS_WIN_DESCRIPTION :Графика из Transport Tycoon Deluxe для Windows. +STR_BASESOUNDS_DOS_DESCRIPTION :Набор звукового оформления из игры Transport Tycoon Deluxe для DOS. +STR_BASESOUNDS_WIN_DESCRIPTION :Набор звукового оформления из игры Transport Tycoon Deluxe для Windows. STR_BASESOUNDS_NONE_DESCRIPTION :"Пустой" набор звукового оформления, не содержащий никаких звуков. -STR_BASEMUSIC_WIN_DESCRIPTION :Оригинальный набор музыкального оформления из игры Transport Tycoon Deluxe для Windows. +STR_BASEMUSIC_WIN_DESCRIPTION :Набор музыкального оформления из игры Transport Tycoon Deluxe для Windows. +STR_BASEMUSIC_DOS_DESCRIPTION :Набор музыкального оформления из игры Transport Tycoon Deluxe для DOS. +STR_BASEMUSIC_TTO_DESCRIPTION :Набор музыкального оформления из игры Transport Tycoon Deluxe для DOS. STR_BASEMUSIC_NONE_DESCRIPTION :"Пустой" набор музыкального оформления, не содержащий никакой музыки. ##id 0x2000 diff --git a/src/lang/serbian.txt b/src/lang/serbian.txt index 155772ce5d..d253ac97ed 100644 --- a/src/lang/serbian.txt +++ b/src/lang/serbian.txt @@ -838,6 +838,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT} {DKGREEN} Nije dostupna muzika STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Numera STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Naziv @@ -857,15 +858,15 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Izaberi STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Uključi/isključi nasumičan izbor pri puštanju STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Prikaži prozor za izbor muzičkih numera -STR_ERROR_NO_SONGS :{WHITE}Izabran je skup muzike bez ijedne numere. Neće biti puštena nikakva muzika - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Izbor muzičkog programa +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE} Muzički program - '{STRING}' STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Indeks numera STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Program - '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Obriši +STR_PLAYLIST_CHANGE_SET :{BLACK}Promeni set STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Obriši tekući program (samo korisnički-definisani programi) +STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Promenite izbor muzike na drugi instalirani skup STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Klik na numeru je dodaje u tekući program (samo za korisnički-definisane programe) STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Pritisnite na muzičku numeru kako biste je uklonili sa trenutnog rasporeda (samo za Custom1 ili Custom2) @@ -1075,10 +1076,10 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC # Extra view window STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Pogled{COMMA} -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Premesti u pogled +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK} Kopiraj u prozor za pogled STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Premešta pogled na trenutnu poziciju glavnog pogleda -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Prebaci se -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Premešta glavni pogled na lokaciju na kojoj je ovaj pogled +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Promenite glavni prikaz +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Kopirajte lokaciju prozora za prikaz u glavnom prikazu # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opcije @@ -1532,8 +1533,12 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Boja terena na STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Zelena STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Tamno zelena STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Ljubičasta -STR_CONFIG_SETTING_REVERSE_SCROLLING :Suprotan smer pomeranja prozora: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Ponašanje kod skrolovanja karte desnim dugmetom miša. Kada je isključeno, miš pomiče kameru. Kada je uključeno, miš pomiče kartu +STR_CONFIG_SETTING_SCROLLMODE :Ponašanje listanja pogleda: {STRING} +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Ponašanje prilikom skrolovanje mape +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Pomerite pogled sa desnim tasterom miša, položaj miša zaključan +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Pomerite mapu sa desnim tasterom miša, zaključajte položaj miša +STR_CONFIG_SETTING_SCROLLMODE_RMB :Pomerite mapu pomoću desne tipke miša +STR_CONFIG_SETTING_SCROLLMODE_LMB :Pomerite mapu pomoću levog miša STR_CONFIG_SETTING_SMOOTH_SCROLLING :Ravnomeran prelaz prozora: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Odredi kako se glavni prikaz pomiče na određeno mesto kada se klikne na malu kartu ili kada se daje naredba za pomicanje na određeni objekat na karti. Ako je omogućeno, prikaz se pomiče glatko, ako je onemogućeno, prikaz izravno skače na ciljano mesto STR_CONFIG_SETTING_MEASURE_TOOLTIP :Prikazivati mere dok se koriste alati za gradnju: {STRING} @@ -1565,8 +1570,8 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command+Klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+Klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Nikakvo -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Pomeranje sa levim klikom: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Omogući skrolovanje po mapi povlačenjem mape sa levim dugmetom miša. Ovo je posebno korisno kod skrolovanja na ekranima na dodir +STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Zatvori prozor pomoću desnog klika: {STRING} +STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Zatvara prozor tako što klikne desnim klikom unutar nje. Onemogućava dodir sa desnim tasterom miša! STR_CONFIG_SETTING_AUTOSAVE :Autočuvanje: {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :Izbor vremenskog intervala između dve automatski sačuvane pozicije @@ -2477,6 +2482,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Legenda STR_LINKGRAPH_LEGEND_ALL :{BLACK}Sve STR_LINKGRAPH_LEGEND_NONE :{BLACK}Nema STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Odaberite preduzeća koja želite da se prikažu +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}neiskorišćen @@ -2784,6 +2790,7 @@ STR_LAND_AREA_INFORMATION_AIRPORTTILE_NAME :{BLACK}Naziv de STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Tovar prihvaćen: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) +STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Tip šine: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Najveća brzina na pruzi: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Ograničenje brzine: {LTBLUE}{VELOCITY} @@ -2796,29 +2803,29 @@ STR_LAI_CLEAR_DESCRIPTION_FIELDS :Polja STR_LAI_CLEAR_DESCRIPTION_SNOW_COVERED_LAND :Snegom prekrivena zemlja STR_LAI_CLEAR_DESCRIPTION_DESERT :Pustinja -STR_LAI_RAIL_DESCRIPTION_TRACK :Železnica kolosek -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_SIGNALS :Železnica kolosek sa blok signalizacijom -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRESIGNALS :Železnica kolosek sa predsignalizacijom -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXITSIGNALS :Železnica kolosek sa izlaznom signalizacijom -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBOSIGNALS :Železnica kolosek sa kombinovanom signalizacijom -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBSSIGNALS :Železnica kolosek sa putnom signalizacijom -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NOENTRYSIGNALS :Železnica kolosek sa jednosmernom putnom signalizacijom -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PRESIGNALS :Železnica kolosek sa blok i predsignalizacijom -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_EXITSIGNALS :Železnica kolosek sa blok i izlaznom signalizacijom -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_COMBOSIGNALS :Železnica kolosek sa blok i kombinovanom signalizacijom -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PBSSIGNALS :Železnica kolosek sa blok i putnom signalizacijom -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_NOENTRYSIGNALS :Železnica kolosek sa blok i jednosmernom putnom signalizacijom -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_EXITSIGNALS :Železnica kolosek sa pred i izlaznom signalizacijom -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_COMBOSIGNALS :Železnica kolosek sa pred i kombinovanom signalizacijom -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_PBSSIGNALS :Železnica kolosek sa pred i putnom signalizacijom -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_NOENTRYSIGNALS :Železnica kolosek sa pred i jednosmernom putnom signalizacijom -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_COMBOSIGNALS :Železnica kolosek sa izlaznom i kombinovanom signalizacijom -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_PBSSIGNALS :Železnica kolosek sa izlaznom i putnom signalizacijom -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_NOENTRYSIGNALS :Železnica kolosek sa izlaznom i jednosmernom putnom signalizacijom -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_PBSSIGNALS :Železnica kolosek sa kombinovanom i putnom signalizacijom -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_NOENTRYSIGNALS :Železnica kolosek sa kombinovanom i jednosmernom putnom signalizacijom -STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBS_NOENTRYSIGNALS :Železnica kolosek sa putnom i jednosmernom putnom signalizacijom -STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT :Železnica železnički depo +STR_LAI_RAIL_DESCRIPTION_TRACK :Željeznički put +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_SIGNALS :Željeznički put sa blok signalima +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRESIGNALS :Željeznički put sa pred-signalima +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXITSIGNALS :Železnički put sa izlaznom signalizacijom +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBOSIGNALS :Željeznički put sa kombinovanim signalima +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBSSIGNALS :Železnički put sa putnom signalizacijom +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NOENTRYSIGNALS :Železnički put sa jednosmernim signalima +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PRESIGNALS :Železnički put sa blokom i pred-signalima +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_EXITSIGNALS :Željeznički put sa blokovnim i izlaznim signalima +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_COMBOSIGNALS :Željeznički put sa blokovnim i kombinovanim signalima +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PBSSIGNALS :Železnički put sa signalizacijom izlaza i puta +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_NOENTRYSIGNALS :Železnički put sa blokom i pred-signalima +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_EXITSIGNALS :Željeznički put sa pred-i izlaznim signalima +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_COMBOSIGNALS :Željeznički put sa pred- i kombo-signalima +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_PBSSIGNALS :Željeznički put sa pre- i putnom signalizacijom +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_NOENTRYSIGNALS :Željeznički put sa signalima pre i jednosmernog puta +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_COMBOSIGNALS :Železnički put sa izlaznim i kombo-signalima +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_PBSSIGNALS :Železnički put sa signalizacijom izlaza i puta +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_NOENTRYSIGNALS :Železnički put sa izlaznim i jednosmernim signalima +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_PBSSIGNALS :Željeznički put sa kombinovanim i putnim signalima +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_NOENTRYSIGNALS :Željeznički put sa kombinovanim i jednosmernim signalima +STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBS_NOENTRYSIGNALS :Železnički put sa putnim i jednosmernim signalima +STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT :Vozni park željeznice STR_LAI_ROAD_DESCRIPTION_ROAD :Put STR_LAI_ROAD_DESCRIPTION_ROAD_WITH_STREETLIGHTS :Kolovoz sa uličnom rasvetom @@ -2884,6 +2891,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Original STR_ABOUT_VERSION :{BLACK}OpenTTD verzija {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 OpenTTD tim +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Sačuvaj poziciju STR_SAVELOAD_LOAD_CAPTION :{WHITE}Učitavanje Partije @@ -3168,6 +3182,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Unos naz STR_TOWN_DIRECTORY_CAPTION :{WHITE}Naselja STR_TOWN_DIRECTORY_NONE :{ORANGE}- Prazno - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (City){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Imena naselja - klikom na ime se centrira glavni pogled na to naselje. Ctrl+Klik otvara novi pogled na lokaciju naselja STR_TOWN_POPULATION :{BLACK}Svetska populacija: {COMMA} @@ -3175,8 +3190,7 @@ STR_TOWN_POPULATION :{BLACK}Svetska STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Grad) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Populacija: {ORANGE}{COMMA}{BLACK} Zgrada: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Broj putnika tokom meseca: {ORANGE}{COMMA}{BLACK} najviše: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Količina pošte tokom meseca: {ORANGE}{COMMA}{BLACK} najviše: {ORANGE}{COMMA} +STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} u poslednjem mesecu: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Tovar potreban za razvoj naselja: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} potrebno STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} potrebno zimi @@ -3487,6 +3501,9 @@ STR_INDUSTRY_VIEW_REQUIRES_CARGO_CARGO :{BLACK}Potražu STR_INDUSTRY_VIEW_REQUIRES_CARGO_CARGO_CARGO :{BLACK}Potražuje: {YELLOW}{STRING.aku}{STRING}, {STRING.aku}{STRING}, {STRING.aku}{STRING} ############ range for requires ends +STR_INDUSTRY_VIEW_REQUIRES :{BLACK} Zahteva: +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} čekaje {STRING} ############ range for produces starts STR_INDUSTRY_VIEW_PRODUCES_CARGO :{BLACK}Proizvodi: {YELLOW}{STRING}{STRING} @@ -3555,6 +3572,10 @@ STR_GROUP_REMOVE_ALL_VEHICLES :Ukloni sva vozi STR_GROUP_RENAME_CAPTION :{BLACK}Preimenuj grupu +STR_GROUP_PROFIT_THIS_YEAR :Dobit ove godine: +STR_GROUP_PROFIT_LAST_YEAR :Dobit prošle godine: +STR_GROUP_OCCUPANCY :Trenutna upotreba: +STR_GROUP_OCCUPANCY_VALUE :{NUM}% # Build vehicle window STR_BUY_VEHICLE_TRAIN_RAIL_CAPTION :Nova Železnička Vozila @@ -3587,6 +3608,7 @@ STR_PURCHASE_INFO_ALL_TYPES :Sve vrste teret STR_PURCHASE_INFO_ALL_BUT :Sve sem {CARGO_LIST} STR_PURCHASE_INFO_MAX_TE :{BLACK}Najveća vučna snaga: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Domet: {GOLD}{COMMA} pločica +STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK} Tip aviona: {GOLD} {STRING} STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Spisak probranih šinskih vozila - kliknite na vozilo za više podataka STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Spisak probranih drumskih vozila - kliknite na vozilo za više podataka @@ -3727,6 +3749,10 @@ STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE.aku :magnetnog žel. STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Cena: {CURRENCY_LONG} Težina: {WEIGHT_SHORT}{}Brzina: {VELOCITY} Snaga: {POWER}{}Cena Održavanja: {CURRENCY_LONG}/god.{}Nosivost: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cena: {CURRENCY_LONG} Težina: {WEIGHT_SHORT}{}Brzina: {VELOCITY} Snaga: {POWER} Najveća vučna snaga: {6:FORCE}{}Cena Održavanja: {4:CURRENCY_LONG}/god{}Nosivost: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Najveća Brzina: {VELOCITY}{}Nosivost: {CARGO_LONG}{}Cena Održavanja: {CURRENCY_LONG}/god. +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :BLACK} Cena: {CURRENCY_LONG} Maks. Brzina: {VELOCITY}{} Tip aviona: {STRING}{} Kapacitet: {CARGO_LONG}, {CARGO_LONG}{}Pokretna cena: {CURRENCY_LONG}/godine. +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK} Cena: {CURRENCY_LONG} Maks. Brzina: {VELOCITY}{}Tip aviona: {STRING}{}Kapacitet: {CARGO_LONG}{}Pokretna cena: {CURRENCY_LONG}/god. +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_CAP_RUNCOST :{BLACK} Cena: {CURRENCY_LONG} Maks. Brzina: {VELOCITY}{} Tip aviona: {STRING} Domet: {COMMA} pločice{}Kapacitet: {CARGO_LONG}, {CARGO_LONG}{} Pokretni trošak: {CURRENCY_LONG} /god. +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_RUNCOST :BLACK}Cena: {CURRENCY_LONG} Maks. Brzina: {VELOCITY}{}Tip aviona: {STRING} Opseg: {COMMA} pločice{}Kapacitet: {CARGO_LONG}{}Pokretni trošak: {CURRENCY_LONG}/god. # Autoreplace window STR_REPLACE_VEHICLES_WHITE :{WHITE}Zameni {STRING} - {STRING} @@ -3766,6 +3792,7 @@ STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Pritisni STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Prebacuje između prikaza zamene lokomotiva i zamene vagona STR_REPLACE_ENGINES :Lokomotive STR_REPLACE_WAGONS :Vagoni +STR_REPLACE_ALL_RAILTYPE :Sve šinskih vozila STR_REPLACE_HELP_RAILTYPE :{BLACK}Izaberite vrstu pruge za koju želite zamenu kompozicije STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Prikazuje koja lokomotiva će se zameniti označenom sa leve strane, ako ih ima @@ -3858,6 +3885,8 @@ STR_VEHICLE_INFO_AGE :{COMMA} godin{P STR_VEHICLE_INFO_AGE_RED :{RED}{COMMA} godin{P a e a} ({COMMA}) STR_VEHICLE_INFO_MAX_SPEED :{BLACK}Najveća brzina: {LTBLUE}{VELOCITY} +STR_VEHICLE_INFO_MAX_SPEED_TYPE :{BLACK}Maks. brzina: {LTBLUE}{VELOCITY} {BLACK}Tip aviona: {LTBLUE}{STRING} +STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE :BLACK} Maks. brzina: {LTBLUE} {VELOCITY} {BLACK} Tip aviona: {LTBLUE} {STRING} {BLACK} Opseg: {LTBLUE} {COMMA} pločice STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Težina: {LTBLUE}{WEIGHT_SHORT} {BLACK}Snaga: {LTBLUE}{POWER}{BLACK} Najveća brzina: {LTBLUE}{VELOCITY} STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Težina: {LTBLUE}{WEIGHT_SHORT} {BLACK}Snaga: {LTBLUE}{POWER}{BLACK} Najveća brzina: {LTBLUE}{VELOCITY} {BLACK} Najveća vučna snaga: {LTBLUE}{FORCE} @@ -4416,7 +4445,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Previše STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Previše delova železničke stanice STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Previše autobuskih stanica STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Previše tovarnih stanica -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Previše je blizu druge stanice STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Previše je blizu drugog pristaništa STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Previše je blizu drugog aerodroma STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Ova stanica ne može biti preimenovana... @@ -4424,6 +4452,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... ova STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... ulica je okrenuta u drugom pravcu STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... stajalište ne može biti na krivini STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... stajalište ne može biti na raskrsnici +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... put je jednosmeran ili blokiran. # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Deo stanice se ne može ukloniti... @@ -4675,6 +4704,8 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Originalni skup STR_BASESOUNDS_WIN_DESCRIPTION :Originalni skup zvukova Transport Tycoon Deluxe Windows izdanja. STR_BASESOUNDS_NONE_DESCRIPTION :Prazan skup zvukova. STR_BASEMUSIC_WIN_DESCRIPTION :Originalni skup muzičkih numera Transport Tycoon Deluxe Windows izdanja. +STR_BASEMUSIC_DOS_DESCRIPTION :Originalna muzika za TTD za DOS izdanje. +STR_BASEMUSIC_TTO_DESCRIPTION :Originalna muzika TTD (Original / World Editor) DOS izdanja. STR_BASEMUSIC_NONE_DESCRIPTION :Prazan skup muzičkih numera. ##id 0x2000 diff --git a/src/lang/simplified_chinese.txt b/src/lang/simplified_chinese.txt index d8e9f0c8c6..535e94a582 100644 --- a/src/lang/simplified_chinese.txt +++ b/src/lang/simplified_chinese.txt @@ -475,6 +475,7 @@ STR_ABOUT_MENU_SCREENSHOT :屏幕截图 STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :高清截图 STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :默认缩放模式下的屏幕截图 STR_ABOUT_MENU_GIANT_SCREENSHOT :全地图截图 +STR_ABOUT_MENU_SHOW_FRAMERATE :显示帧率 STR_ABOUT_MENU_ABOUT_OPENTTD :关于 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite 对齐 STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :切换边界框 @@ -650,6 +651,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}没有可用的音乐包 STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" STR_MUSIC_TRACK :{TINY_FONT}{BLACK}音轨 STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}乐曲主题 @@ -669,15 +671,14 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}选择 STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}开启/关闭 随机播放列表中的曲目 STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}打开音乐选单窗口 -STR_ERROR_NO_SONGS :{WHITE}选择了没有歌曲的音乐组。不会播放歌曲。 - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}音乐选单 STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}全部音轨列表 STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}当前选用'{STRING}'列表 STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}清除 +STR_PLAYLIST_CHANGE_SET :更改设置 STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}清除当前列表中曲目{}(仅限自定义1或自定义2) +STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}选择另一种已安装的音乐 STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}点击音乐曲目以加入当前播放列表{}(仅限自定义1或自定义2) STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}点击音乐曲目以从当前播放列表中删除{}(仅限自定义1或自定义2) @@ -813,6 +814,7 @@ STR_NEWS_MERGER_TAKEOVER_TITLE :{BIG_FONT}{BLAC STR_PRESIDENT_NAME_MANAGER :{BLACK}{PRESIDENT_NAME}{}(总裁) STR_NEWS_NEW_TOWN :{BLACK}{BIG_FONT}{STRING} 赞助了城镇 {TOWN} 的建设! +STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK}{BIG_FONT}一个名叫{TOWN}的城镇刚刚成立了! STR_NEWS_INDUSTRY_CONSTRUCTION :{BIG_FONT}{BLACK}新 {STRING} 正在 {TOWN} 加紧建设! STR_NEWS_INDUSTRY_PLANTED :{BIG_FONT}{BLACK}新 {STRING} 即将落户 {TOWN}! @@ -1337,8 +1339,9 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :设置缩略地 STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :绿色 STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :深绿色 STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :紫色 -STR_CONFIG_SETTING_REVERSE_SCROLLING :拖动方向与屏幕移动方向相反:{STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :设置按下鼠标右键拖动时地图移动的方向,“关闭”鼠标拖动摄像机,“打开”时鼠标拖动地图。 +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :鼠标右键移动地图,鼠标指针不跟随移动 +STR_CONFIG_SETTING_SCROLLMODE_RMB :鼠标右键移动地图 +STR_CONFIG_SETTING_SCROLLMODE_LMB :鼠标左键移动地图 STR_CONFIG_SETTING_SMOOTH_SCROLLING :平滑视角滚动: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :设置在缩略图上点击或者发出转到特定目标的命令时主视角的转换方式,如果“打开”本选项,视角平缓滚动,“关闭”时直接跳转到目标位置 STR_CONFIG_SETTING_MEASURE_TOOLTIP :建设时显示测量数据:{STRING} @@ -1370,8 +1373,8 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :按住Command STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :按住Ctrl键 点击 STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :关闭 -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :左击滚动: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :可用按住鼠标左键再拖拉的方法来进行屏幕滚动. 这对于触摸屏设备特别有用 +STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :右键关闭窗口: {STRING} +STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :使用在窗口内按右键关闭该窗口,本功能与右键工具提示不能共存! STR_CONFIG_SETTING_AUTOSAVE :自动保存: {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :选择自动存档时间间隔 @@ -1607,7 +1610,7 @@ STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :游戏开局时 STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :每 {STRING}{NBSP}天刷新一次分配图 STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :指定每次计算货物分配图之间的时间。由于每次重新计算只会处理一个货物分配图元件,因此本设定不代表“每若干日重新计算整个货物分配图”。{}如果此设定赋值越小,則系统需要使用更多处理器时间计算货物分配图。相反,如果此设定赋值越大,則货物被派往新路线所需的时间越长。 STR_CONFIG_SETTING_LINKGRAPH_TIME :容许系统用 {STRING}{NBSP}天时间刷新货物分配图 -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :當刷新货物分配图时,系统會衍生一条线程。本设定的值即为线程的持续时间。{}这设定赋值越小,线程越有可能在应当停止的时候还未完成,游戏会暂停运作至线程完成工作。相反,这设定赋值越大,則货物分配功能需要较长时间反映线路网変动的影晌。 +STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :当刷新货物分配图时,系统会创建一条线程。此处设定的数值即该线程的持续时间。{}赋值越小,线程越有可能在应当停止的时候还未完成,游戏会暂停运作至线程完成工作。相反,赋值越大,则货物分配功能需要较长时间反映线路网变动的影晌。 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :手动 STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :不对称 STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :对称 @@ -1616,7 +1619,7 @@ STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :假设有交通 STR_CONFIG_SETTING_DISTRIBUTION_MAIL :邮件分配方式:{STRING} STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :假设有交通路线连接甲、乙两站。“对称”指甲站往乙站的邮件数量與乙站往甲站的邮件数量大致相同。“不对称”指任何一站往另一站的邮件数量皆由系统随意决定。“手动”指系统不会自动分配邮件的目的地。 STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :装甲货物分配方式:{STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :“装甲货物”包括溫带场景的“贵重品”、寒带场景的“金块”及沙漠场景的“钻石”。使用 NewGRF 可能会改変以上设置。{} 假设有交通路线连接甲、乙两站。“对称”指甲站往乙站的货物数量與乙站往甲站的装甲货物数量大致相同。“不对称”指任何一站往另一站的装甲货物数量皆由系统随意决定。“手动”指系统不会自动分配装甲货物的目的地。{} 建议在溫带及沙漠场景使用“对称”,因为银行之间会相互发送贵重品或钻石;在寒带则应使用“不对称”,因为银行不会把金块送回金矿。 +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :“装甲货物”包括温带场景的“贵重品”、寒带场景的“金块”及沙漠场景的“钻石”。使用 NewGRF 可能会改变以上设置。{} 假设有交通路线连接甲、乙两站。“对称”指甲站往乙站的货物数量与乙站往甲站的装甲货物数量大致相同。“不对称”指任何一站往另一站的装甲货物数量皆由系统随意决定。“手动”指系统不会自动分配装甲货物的目的地。{} 建议在温带及沙漠场景使用“对称”,因为银行之间会相互发送贵重品或钻石;在寒带则应使用“不对称”,因为银行不会把金块送回金矿。 STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :其他货物分配方式:{STRING} STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :如为此设置赋值“不对称”,则任何一站往另一站的货物数量皆由系统随意决定。如为此设置赋值“手动”,则系统不会依据交通路线分配货物的目的地。 STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :分配精确度:{STRING} @@ -2261,7 +2264,7 @@ STR_CONTENT_ERROR_COULD_NOT_EXTRACT :{WHITE}无法 STR_MISSING_GRAPHICS_SET_CAPTION :{WHITE}缺失图形组 STR_MISSING_GRAPHICS_SET_MESSAGE :{BLACK}OpenTTD 需要基础图形组用以绘制界面。您是否希望 OpenTTD 下载并安装以下图形组? -STR_MISSING_GRAPHICS_YES_DOWNLOAD :{BLACK}是的,下载之 +STR_MISSING_GRAPHICS_YES_DOWNLOAD :{BLACK}好,开始下载 STR_MISSING_GRAPHICS_NO_QUIT :{BLACK}不,退出OpenTTD # Transparency settings window @@ -2690,6 +2693,26 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}原始 STR_ABOUT_VERSION :{BLACK}OpenTTD 版本 {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 OpenTTD 团队 +# Framerate display window +STR_FRAMERATE_CAPTION :{WHITE}帧率 +STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) +STR_FRAMERATE_RATE_BLITTER :{BLACK}帧率:{STRING} +STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}每秒渲染更新的图像帧。 +STR_FRAMERATE_SPEED_FACTOR :{BLACK}当前游戏速度:{DECIMAL}x +STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms +STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} ms +STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} fps +STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} fps +STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} fps +STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms +############ Leave those lines in this order!! +STR_FRAMERATE_VIDEO :{BLACK}视频输出: +STR_FRAMERATE_SOUND :{BLACK}混响: +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}保存游戏 STR_SAVELOAD_LOAD_CAPTION :{WHITE}读取存档 @@ -2712,6 +2735,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}游戏 STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}无可用信息 STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} +STR_SAVELOAD_FILTER_TITLE :{BLACK}过滤字串: STR_SAVELOAD_OSKTITLE :{BLACK}为存档命名 @@ -2981,8 +3005,6 @@ STR_TOWN_POPULATION :{BLACK}所有 STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (都市) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}人口:{ORANGE}{COMMA}{BLACK} 房屋:{ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}上月旅客数量:{ORANGE}{COMMA}{BLACK} 最大值:{ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}上月邮包数量:{ORANGE}{COMMA}{BLACK} 最大值:{ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}城镇发展所必需的货物: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{RED} 需要: {ORANGE}{STRING} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} 冬季的需求 @@ -3365,6 +3387,7 @@ STR_GROUP_RENAME_CAPTION :{BLACK}重命 STR_GROUP_PROFIT_THIS_YEAR :今年利润: STR_GROUP_PROFIT_LAST_YEAR :去年利润 +STR_GROUP_OCCUPANCY :当前使用量: STR_GROUP_OCCUPANCY_VALUE :{NUM}% # Build vehicle window @@ -3533,7 +3556,10 @@ STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :磁悬浮机车 STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}售价:{CURRENCY_LONG} 重量:{WEIGHT_SHORT}{}速度:{VELOCITY} 功率:{POWER}{}运行费用:{CURRENCY_LONG}/年{}运载能力: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}售价:{CURRENCY_LONG} 重量:{WEIGHT_SHORT}{}速度:{VELOCITY} 功率:{POWER} 最大牵引力:{6:FORCE}{}运行费用{4:CURRENCY_LONG}/年{}运载能力:{5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}售价:{CURRENCY_LONG} 最大速度:{VELOCITY}{}运载能力:{CARGO_LONG}{}运行成本:{CURRENCY_LONG} /年 +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}售价:{CURRENCY_LONG} 最大速度:{VELOCITY}{}飞机类型:{STRING}{}运载能力:{CARGO_LONG}, {CARGO_LONG}{}运行成本: {CURRENCY_LONG}/年 +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}售价: {CURRENCY_LONG} 最大速度: {VELOCITY}{}飞机类型: {STRING}{}运载能力: {CARGO_LONG}{}运行成本: {CURRENCY_LONG}/年 STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_CAP_RUNCOST :{BLACK}购买费用: {CURRENCY_LONG} 最大速度: {VELOCITY}{}飞机种类: {STRING} 最大航程: {COMMA} 格{}装载量: {CARGO_LONG}, {CARGO_LONG}{}运行费用: {CURRENCY_LONG}/年 +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_RUNCOST :{BLACK}售价: {CURRENCY_LONG} 最大速度: {VELOCITY}{}飞机类型: {STRING} 续航里程: {COMMA} 格{}运载能力: {CARGO_LONG}{}运行成本: {CURRENCY_LONG}/年 # Autoreplace window STR_REPLACE_VEHICLES_WHITE :{WHITE}更新 {STRING} - {STRING} @@ -3656,6 +3682,7 @@ STR_VEHICLE_INFO_AGE :{COMMA} 年 ({C STR_VEHICLE_INFO_AGE_RED :{RED}{COMMA} 年 ({COMMA}) STR_VEHICLE_INFO_MAX_SPEED :{BLACK}最大速度:{LTBLUE}{VELOCITY} +STR_VEHICLE_INFO_MAX_SPEED_TYPE :{BLACK}最高速度: {LTBLUE}{VELOCITY} {BLACK}飞机种类: {LTBLUE}{STRING} STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}重量:{LTBLUE}{WEIGHT_SHORT} {BLACK}功率:{LTBLUE}{POWER}{BLACK} 最大速度:{LTBLUE}{VELOCITY} STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}重量:{LTBLUE}{WEIGHT_SHORT} {BLACK}功率:{LTBLUE}{POWER}{BLACK} 最大速度:{LTBLUE}{VELOCITY} {BLACK}最大牵引力:{LTBLUE}{FORCE} @@ -4135,7 +4162,7 @@ STR_ERROR_NOT_ALLOWED_WHILE_PAUSED :{WHITE}暂停 STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS :{WHITE}{TOWN} 地方政府不批准此操作…… STR_ERROR_LOCAL_AUTHORITY_REFUSES_AIRPORT :{WHITE}{TOWN}地方政府{}不同意在本市范围内再兴建一座机场 STR_ERROR_LOCAL_AUTHORITY_REFUSES_NOISE :{WHITE}{TOWN} 考虑到噪音控制,地方当局拒绝修建机场。 -STR_ERROR_BRIBE_FAILED :{WHITE}您的桥梁修建计划受到了当地投资商的关注 +STR_ERROR_BRIBE_FAILED :{WHITE}您的贿赂行动被当地检察机关发现,赃款均已没收,您在本市评价已降为最低。 # Levelling errors STR_ERROR_CAN_T_RAISE_LAND_HERE :{WHITE}不能提高这里的地面…… @@ -4214,7 +4241,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}车站 STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}分体站台太多 STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}公共汽车站过多 STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}汽车货场过多 -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}距离另一车站过近 STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}距离另一码头过近 STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}距离另一机场过近 STR_ERROR_CAN_T_RENAME_STATION :{WHITE}不能重命名车站 @@ -4473,6 +4499,8 @@ STR_BASESOUNDS_DOS_DESCRIPTION :运输大亨DOS STR_BASESOUNDS_WIN_DESCRIPTION :Transport Tycoon Deluxe Windows (运输大亨Windows豪华版)的原版音效包. STR_BASESOUNDS_NONE_DESCRIPTION :一个空的音效包. STR_BASEMUSIC_WIN_DESCRIPTION :Transport Tycoon Deluxe(运输大亨Windows豪华版)的原版音乐包 +STR_BASEMUSIC_DOS_DESCRIPTION :运输大亨DOS豪华版原版音乐。 +STR_BASEMUSIC_TTO_DESCRIPTION :原版运输大亨(DOS版及地图编辑器扩展)音乐。 STR_BASEMUSIC_NONE_DESCRIPTION :一个没有实际内容的音乐包. ##id 0x2000 diff --git a/src/lang/slovak.txt b/src/lang/slovak.txt index 4e28c45c02..b828879d48 100644 --- a/src/lang/slovak.txt +++ b/src/lang/slovak.txt @@ -733,10 +733,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Zvoliť STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Prepnúť náhodný výber STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Zobraziť okno pre výber hudobných stôp -STR_ERROR_NO_SONGS :{WHITE}Bola zvolená sada hudby bez skladieb. Žiadne skladby nebudú hrať - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Výber hudobného programu STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Zoznam skladieb STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Program - '{STRING}' @@ -1405,8 +1402,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Farby terénu n STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Zelená STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Tmavozelená STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Fialová -STR_CONFIG_SETTING_REVERSE_SCROLLING :Posúvať mapu opačným smerom: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Chovanie sa mapy keď je posúvaná pravým tlačítkom myši. Ak je vypnuté posúva sa kamera, ak je zapnuté posúva sa mapa. STR_CONFIG_SETTING_SMOOTH_SCROLLING :Plynulé posúvanie pohľadu: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Nastaví ako bude reagovať posúvanie na špecifickú pozíciu po kliknutí na minimapu, alebo po zadaní príkazu na presun na zadaný objekt. Ak je zapnuté, pohľad sa presúva plynulo. Ak je vypnuté, pohľad skočí priamo na zadané miesto/objekt. STR_CONFIG_SETTING_MEASURE_TOOLTIP :Zobraziť údaje o rozmeroch pri výstavbe: {STRING} @@ -1438,8 +1433,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Príkaz + klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :CTRL + klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Žiadna -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Posúvať pohľad ľavým tlačidlom myši: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Povolí posúvanie mapy ĽAVÝM tlačítkom myši. Toto je obzvlášť užitočné pri použití dotykového displeja. STR_CONFIG_SETTING_AUTOSAVE :Automatické ukladanie: {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :Vyberte interval pre automatické ukladanie hry @@ -2757,6 +2750,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Pôvodn STR_ABOUT_VERSION :{BLACK}OpenTTD verzia {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 team OpenTTD +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Uložiť hru STR_SAVELOAD_LOAD_CAPTION :{WHITE}Nahrať hru @@ -3048,8 +3048,6 @@ STR_TOWN_POPULATION :{BLACK}Svetová STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Mesto) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Obyvateľstvo: {ORANGE}{COMMA}{BLACK} Domov: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Cestujúci posledný mesiac: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Pošta posledný mesiac: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Tovar potrebný k rozrastu mesta: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} potrebný STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} potrebné v zime @@ -4273,7 +4271,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Príliš STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Veľa častí vlakovej stanice STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Príliš veľa autobusových zastávok STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Príliš veľa zastávok nákladných automobilov -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Príliš blízko inej stanice/vykládky STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Príliš blízko iného prístavu STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Príliš blízko iného letiska STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Stanica sa nedá premenovať... diff --git a/src/lang/slovenian.txt b/src/lang/slovenian.txt index 5fd44b4d36..0704d6e95b 100644 --- a/src/lang/slovenian.txt +++ b/src/lang/slovenian.txt @@ -822,10 +822,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Izberi g STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Preklapljaj mešan program vključeno/izključeno STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Prikaži okno z izborom glasbe -STR_ERROR_NO_SONGS :{WHITE}Izbran je bil komplet glasbe brez skladb. Nobena skladba ne bo predvajana - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Izbor glasbenega programa STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Kazalo skladb STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Program - '{STRING}' @@ -1490,8 +1487,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Barva ozemlja n STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Zelena STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Temno zelena STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Vijolična -STR_CONFIG_SETTING_REVERSE_SCROLLING :Obrni smer premika okna: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Sistem delovanja avtomatskega pomika z miško na robu. Onemogočeno - miška premika pogled, omogočeno - miška premika zemljevid. STR_CONFIG_SETTING_SMOOTH_SCROLLING :Gladek premik pogleda: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Način pomika pogleda na določen objekt majhnega zemljevida (centriranje pogleda). Omogočeno - pogled drsi, onemogočeno - pogled preskoči. STR_CONFIG_SETTING_MEASURE_TOOLTIP :Prikaz merilnega nasveta med uporabo gradbenih orodij: {STRING} @@ -1523,8 +1518,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Ukaz-klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Kontrola-klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Izklop -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Premik slike z levim klikom: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Omogoči pomik pogleda z levim klikom miške in vlečenjem. Primerno za dotične zaslone. STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Zapri okno z desnim klikom: {STRING} STR_CONFIG_SETTING_AUTOSAVE :Samodejno shrani: {STRING} @@ -2843,6 +2836,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Prvotne STR_ABOUT_VERSION :{BLACK}OpenTTD različica {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2018 ekipa OpenTTD +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Shrani igro STR_SAVELOAD_LOAD_CAPTION :{WHITE}Naloži igro @@ -3134,8 +3134,6 @@ STR_TOWN_POPULATION :{BLACK}Svetovno STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Mesto) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Prebivalstvo: {ORANGE}{COMMA}{BLACK} Število stavb: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Potnikov prejšnji mesec: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Pošte prejšnji mesec: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Količina potrebnega tovora za rast mesta: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} potrebno STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} je potreben pozimi @@ -4360,7 +4358,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Preveč STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Preveč delov železniške postaje STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Preveč avtobusnih postaj STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Preveč tovornih postaj -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Preblizu druge postaje STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Preblizu drugemu pristanišču STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Preblizu sosednjemu letališču STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Ni mogoče preimenovati postaje diff --git a/src/lang/spanish.txt b/src/lang/spanish.txt index 6993b7b04b..43f9d57b19 100644 --- a/src/lang/spanish.txt +++ b/src/lang/spanish.txt @@ -476,6 +476,7 @@ STR_ABOUT_MENU_SCREENSHOT :Captura de pant STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Captura con zoom de cerca STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Captura con zoom por defecto STR_ABOUT_MENU_GIANT_SCREENSHOT :Captura de mapa completo +STR_ABOUT_MENU_SHOW_FRAMERATE :Mostrar fotogramas por segundo - FPS STR_ABOUT_MENU_ABOUT_OPENTTD :Acerca de 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Alineador de sprites STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Activar cajas delimitadoras @@ -574,7 +575,7 @@ STR_GRAPH_OPERATING_PROFIT_CAPTION :{WHITE}Gráfico STR_GRAPH_INCOME_CAPTION :{WHITE}Gráfico de Ingresos STR_GRAPH_CARGO_DELIVERED_CAPTION :{WHITE}Unidades de carga entregadas STR_GRAPH_COMPANY_PERFORMANCE_RATINGS_CAPTION :{WHITE}Calificaciones de actuación de empresas (tasa máxima=1000) -STR_GRAPH_COMPANY_VALUES_CAPTION :{WHITE}Valores de las empresas +STR_GRAPH_COMPANY_VALUES_CAPTION :{WHITE}Valor de la empresa STR_GRAPH_CARGO_PAYMENT_RATES_CAPTION :{WHITE}Tasas de pago por carga STR_GRAPH_CARGO_PAYMENT_RATES_X_LABEL :{TINY_FONT}{BLACK}Días en tránsito @@ -651,6 +652,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}No hay música disponible STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Pista STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Título @@ -670,17 +672,17 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Seleccio STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Encender/apagar mezclador STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Mostrar ventana de selección de pistas musicales -STR_ERROR_NO_SONGS :{WHITE}Se ha seleccionado un conjunto de música sin canciones. No se reproducirá música - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Selección del programa de música +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Programación Musical - '{STRING}' STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Índice de pistas STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programa - '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Borrar -STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Borrar programa actual (solo Personal 1 y Personal 2) -STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Pulse en la pista de música para añadirla al programa actual (solo Personal 1 y 2) -STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Pulsa sobre la canción para quitarla del programa actual (Solo Personalizado1 y Personalizado2) +STR_PLAYLIST_CHANGE_SET :{BLACK}Cambiar set +STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Borrar programa actual (solo Personalizado1 y 2) +STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Cambia la selección musical a otro set instalado +STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Pulse en la pista de música para añadirla al programa actual (solo Personalizado1 y 2) +STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Pulsa sobre la canción para quitarla del programa actual (solo Personalizado1 y 2) # Highscore window STR_HIGHSCORE_TOP_COMPANIES_WHO_REACHED :{BIG_FONT}{BLACK}Top de empresas que han alcanzado {NUM} @@ -814,6 +816,7 @@ STR_NEWS_MERGER_TAKEOVER_TITLE :{BIG_FONT}{BLAC STR_PRESIDENT_NAME_MANAGER :{BLACK}{PRESIDENT_NAME}{}(Presidente) STR_NEWS_NEW_TOWN :{BLACK}{BIG_FONT}¡{STRING} patrocina la construcción del nuevo municipio {TOWN}! +STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK}{BIG_FONT}¡Un nuevo municipio, llamado: {TOWN}, ha sido construido! STR_NEWS_INDUSTRY_CONSTRUCTION :{BIG_FONT}{BLACK}¡Nuev{G o a} {STRING} en construcción cerca de {TOWN}! STR_NEWS_INDUSTRY_PLANTED :{BIG_FONT}{BLACK}¡Nuev{G o a} {STRING} está siendo plantad{G o a} cerca de {TOWN}! @@ -881,10 +884,10 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC # Extra view window STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Vista {COMMA} -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Copiar punto de vista +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Cambiar punto de vista STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Copia la localización de la vista principal a este punto de vista -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Pegar punto de vista -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Pega la localización de este punto de vista a la principal +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Cambiar vista principal +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Copia la localización de este punto de vista en la vista principal # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opciones del juego @@ -926,6 +929,7 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :Rand sudafrican STR_GAME_OPTIONS_CURRENCY_CUSTOM :Personalizada... STR_GAME_OPTIONS_CURRENCY_GEL :Lari Georgiano (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :Rial Iraní (IRR) +STR_GAME_OPTIONS_CURRENCY_RUB :Nuevo Rublo Ruso (RUB) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Vehículos de carretera @@ -1338,8 +1342,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Color a usar pa STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Verde STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Verde oscuro STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Violeta -STR_CONFIG_SETTING_REVERSE_SCROLLING :Desplazamiento de vista invertido: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Comportamiento del juego al arrastrar el mapa con el botón derecho. Si se desactiva, el ratón mueve la cámara. Si se activa, el ratón mueve el mapa STR_CONFIG_SETTING_SMOOTH_SCROLLING :Desplazamiento de vista suavizado: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Controla la forma en la que la vista principal se mueve a una posición específica como resultado de hacer click en el mapa o al enviar la orden de moverse a un objeto determinado del mapa. Si se activa, la vista se mueve de forma suave. Si se desactiva, la vista se mueve directamente al destino STR_CONFIG_SETTING_MEASURE_TOOLTIP :Mostrar medidas usando las herramientas de construcción: {STRING} @@ -1371,8 +1373,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command+Click STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+Click STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Desactivado -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Desplazamiento con botón izquierdo: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Activa el deslizamiento del mapa al arrastrarlo con el botón izquierdo. Esto es especialmente útil al usar pantallas táctiles STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Cerrar ventana con click derecho: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Cierra una ventana al hacer click derecho dentro. ¡Quita la información al hacer click derecho! @@ -1497,11 +1497,11 @@ STR_CONFIG_SETTING_NEWS_INDUSTRY_CLOSE_HELPTEXT :Mostrar noticia STR_CONFIG_SETTING_NEWS_ECONOMY_CHANGES :Cambios en la economía: {STRING} STR_CONFIG_SETTING_NEWS_ECONOMY_CHANGES_HELPTEXT :Mostrar noticias sobre cambios globales a la economía STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_COMPANY :Cambios de producción en industrias atendidas por la empresa: {STRING} -STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_COMPANY_HELPTEXT :Mostrar una noticia cuando el nivel de producción de una industria que está servida por tu compañía cambia +STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_COMPANY_HELPTEXT :Mostrar una noticia cuando el nivel de producción de una industria, servida por tu compañía, cambia STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_OTHER :Cambios de producción en las industrias servidas por los competidores: {STRING} -STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_OTHER_HELPTEXT :Mostrar una noticia cuando el nivel de producción de una industria que está servida por compañías competidoras cambia +STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_OTHER_HELPTEXT :Mostrar una noticia cuando el nivel de producción de una industria, servida por tus competidores, cambia STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_UNSERVED :Cambios de producción de otras industrias: {STRING} -STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_UNSERVED_HELPTEXT :Mostrar una noticia cuando el nivel de producción de una industria que no está servida por tu compañía o competidores cambia +STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_UNSERVED_HELPTEXT :Mostrar una noticia cuando el nivel de producción de una industria, no servida por tu compañía o competidores, cambia STR_CONFIG_SETTING_NEWS_ADVICE :Aviso / información de los vehículos de la empresa: {STRING} STR_CONFIG_SETTING_NEWS_ADVICE_HELPTEXT :Mostrar mensajes sobre vehículos que requieren atención STR_CONFIG_SETTING_NEWS_NEW_VEHICLES :Nuevos vehículos: {STRING} @@ -1607,10 +1607,10 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Ninguna STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Multiplicador inicial del tamaño de ciudad: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Tamaño medio de las ciudades en relación a los pueblos normales al comienzo de la partida -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Actualizar el grafo de distribución cada {STRING}{NBSP}día{P 0:2 "" s} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Periodo de tiempo entre cálculos del grafo de distribución consecutivos. Esta opción se refiere a los cálculos para cada uno de los componentes del grafo, por lo cual fijar un valor no quiere decir que el grafo completo se actualizará tras ese número de días. Cuanto menor sea, mayor tiempo de CPU será necesario para calcular el grafo de distribución. Cuanto mayor sea, más tardará el grafo de distribución en adaptarse a nuevas rutas -STR_CONFIG_SETTING_LINKGRAPH_TIME :Usar {STRING}{NBSP}día{P 0:2 "" s} para el cálculo del grafo de distribución -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Tiempo a emplear en el cálculo de cada uno de los componentes del grafo de distribución. Cuanto menor sea este valor, más probable es que se produzca ralentización en el juego. Cuanto mayor sea, más tiempo tardará la distribución en actualizarse cuando se producen cambios en las rutas +STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Actualizar el gráfico de distribución cada {STRING}{NBSP}día{P 0:2 "" s} +STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Periodo de tiempo entre cálculos del gráfico de distribución consecutivos. Esta opción se refiere a los cálculos para cada uno de los componentes del gráfico, por lo cual fijar un valor no quiere decir que el gráfico completo se actualizará tras ese número de días. Cuanto menor sea, mayor tiempo de CPU será necesario para calcular el gráfico de distribución. Cuanto mayor sea, más tardará el gráfico de distribución en adaptarse a nuevas rutas. +STR_CONFIG_SETTING_LINKGRAPH_TIME :Usar {STRING}{NBSP}día{P 0:2 "" s} para el cálculo del gráfico de distribución +STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Tiempo a emplear en el cálculo de cada uno de los componentes del gráfico de distribución. Cuanto menor sea este valor, más probable es que se produzca ralentización en el juego. Cuanto mayor sea, más tiempo tardará la distribución en actualizarse cuando se producen cambios en las rutas. STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manual STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asimétrico STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :simétrico @@ -1623,7 +1623,7 @@ STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :La clase de car STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Modo de distribución para otras clases de carga: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asimétrico" significa que se pueden mover cantidades arbitrarias de carga en ambas direcciones. "Manual" significa que no habrá distribución automática para estos tipos de carga. STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Precisión de la distribución: {STRING} -STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Este valor determina el tiempo de CPU empleado en calcular el grafo de distribución. Si es demasiado elevado puede producir ralentización en el juego. Si es demasiado bajo la distribución puede ser poco precisa, causando que ocasionalmente se produzcan errores en los lugares a los que va la carga +STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Este valor determina el tiempo de CPU empleado en calcular el gráfico de distribución. Si es demasiado elevado puede producir ralentización en el juego. Si es demasiado bajo la distribución puede ser poco precisa, causando que ocasionalmente se produzcan errores en los lugares a los que va la carga. STR_CONFIG_SETTING_DEMAND_DISTANCE :Efecto de la distancia en la demanda: {STRING} STR_CONFIG_SETTING_DEMAND_DISTANCE_HELPTEXT :Si se fija a un valor superior a 0, la distancia entre la estación origen A de cierta carga y un posible destino B afectará a la cantidad de carga que se enviará de A a B. Cuanto más lejos esté B de A, menos carga se enviará. Cuanto mayor sea el valor de esta opción, menos carga se enviará a estaciones distantes en favor de estaciones cercanas STR_CONFIG_SETTING_DEMAND_SIZE :Cantidad de carga a devolver en modo simétrico: {STRING} @@ -1868,7 +1868,7 @@ STR_FACE_FACECODE :{BLACK}Cara del STR_FACE_FACECODE_TOOLTIP :{BLACK}Ver y/o asignar número de cara de presidente STR_FACE_FACECODE_CAPTION :{WHITE}Ver y/o asignar número de cara de presidente STR_FACE_FACECODE_SET :{WHITE}Nuevo código de cara ha sido asignado -STR_FACE_FACECODE_ERR :{WHITE}No se puede asignar número de cara de presidente - ¡debe ser un número entre 0 y 4,294,967,295! +STR_FACE_FACECODE_ERR :{WHITE}No se puede asignar número de cara de presidente - ¡Ha de ser un número entre 0 y 4,294,967,295! STR_FACE_SAVE :{BLACK}Guardar STR_FACE_SAVE_TOOLTIP :{BLACK}Guardar cara favorita STR_FACE_SAVE_DONE :{WHITE}Esta cara ha sido guardada como tu favorita en el fichero de configuración @@ -2286,6 +2286,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Leyenda STR_LINKGRAPH_LEGEND_ALL :{BLACK}Todas STR_LINKGRAPH_LEGEND_NONE :{BLACK}Ninguna STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Seleccione las compañías a mostrar +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}sin uso @@ -2694,6 +2695,34 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Copyrigh STR_ABOUT_VERSION :{BLACK}OpenTTD versión {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 El equipo OpenTTD +# Framerate display window +STR_FRAMERATE_CAPTION :{WHITE}Fotogramas por segundo - FPS +STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Número de fotogramas renderizados por segundo. +STR_FRAMERATE_CURRENT :{WHITE}Actual +STR_FRAMERATE_AVERAGE :{WHITE}Medio +STR_FRAMERATE_DATA_POINTS :{BLACK}Datos basados en {COMMA} medidas +STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms +STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms +STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} ms +STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} frames/s +STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} frames/s +STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} frames/s +STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms +STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s +############ Leave those lines in this order!! +STR_FRAMERATE_GL_TRAINS :{BLACK} Ticks de trenes: +STR_FRAMERATE_GL_ROADVEHS :{BLACK} Ticks de vehículos de carretera: +STR_FRAMERATE_GL_SHIPS :{BLACK} Ticks de barcos: +STR_FRAMERATE_GL_AIRCRAFT :{BLACK} Ticks de aeronaves: +STR_FRAMERATE_DRAWING :{BLACK}Renderizado gráfico: +############ End of leave-in-this-order +############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_DRAWING :Renderizado gráfico +STR_FRAMETIME_CAPTION_VIDEO :Salida de vídeo +STR_FRAMETIME_CAPTION_SOUND :Mezcla de sonido +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Guardar Juego STR_SAVELOAD_LOAD_CAPTION :{WHITE}Cargar Juego @@ -2716,6 +2745,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Detalles STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}No hay información disponible STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} +STR_SAVELOAD_FILTER_TITLE :{BLACK}Patrón de filtrado: STR_SAVELOAD_OSKTITLE :{BLACK}Introduce un nombre para el juego guardado @@ -2782,7 +2812,7 @@ STR_GENERATION_ABORT_MESSAGE :{YELLOW}¿Desea STR_GENERATION_PROGRESS :{WHITE}{NUM}% completado STR_GENERATION_PROGRESS_NUM :{BLACK}{NUM} / {NUM} STR_GENERATION_WORLD_GENERATION :{BLACK}Generación de mundo -STR_GENERATION_RIVER_GENERATION :{BLACK}Generación de Ríos +STR_GENERATION_RIVER_GENERATION :{BLACK}Generación de ríos STR_GENERATION_TREE_GENERATION :{BLACK}Generación de árboles STR_GENERATION_OBJECT_GENERATION :{BLACK}Generación de inamovibles STR_GENERATION_CLEARING_TILES :{BLACK}Generación de áreas ásperas o rocosas @@ -2914,6 +2944,7 @@ STR_NEWGRF_ERROR_READ_BOUNDS :Lectura más al STR_NEWGRF_ERROR_GRM_FAILED :Recursos GRF solicitados no disponibles (sprite {3:NUM}) STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING} fue desactivado por {STRING} STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Formato de colocación de sprites inválido o desconocido (sprite {3:NUM}) +STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG :Demasiados elementos en la lista de valores de propiedad (sprite {3:NUM}, propiedad {4:HEX}) # NewGRF related 'general' warnings STR_NEWGRF_POPUP_CAUTION_CAPTION :{WHITE}¡Precaución! @@ -2978,6 +3009,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Introduc STR_TOWN_DIRECTORY_CAPTION :{WHITE}Municipios STR_TOWN_DIRECTORY_NONE :{ORANGE}- Ninguna - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Ciudad){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Nombres de los municipios - click sobre un nombre para centrar la vista principal en él. Ctrl+Click abre una ventana de visualización en dicha posición STR_TOWN_POPULATION :{BLACK}Población mundial: {COMMA} @@ -2985,8 +3017,7 @@ STR_TOWN_POPULATION :{BLACK}Poblaci STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Ciudad) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Habitantes: {ORANGE}{COMMA}{BLACK} Casas: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Pasajeros último mes: {ORANGE}{COMMA}{BLACK} Máx.: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Correo último mes: {ORANGE}{COMMA}{BLACK} Máx.: {ORANGE}{COMMA} +STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} último mes: {ORANGE}{COMMA}{BLACK} máx: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Carga necesaria para crecimiento del municipio: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} requeridos STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} requerido en invierno @@ -2994,7 +3025,7 @@ STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_DELIVERED_GENERAL :{ORANGE}{STRING STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED :{ORANGE}{CARGO_TINY} / {CARGO_LONG}{RED} (todavía requerido) STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_DELIVERED :{ORANGE}{CARGO_TINY} / {CARGO_LONG}{GREEN} (entregado) STR_TOWN_VIEW_TOWN_GROWS_EVERY :{BLACK}El municipio crece cada {ORANGE}{COMMA}{BLACK}{NBSP}día{P "" s} -STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED :{BLACK}El municipio crece cada {ORANGE}{COMMA}{BLACK}{NBSP}días{P "" s} (edificios fundados) +STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED :{BLACK}El municipio crece cada {ORANGE}{COMMA}{BLACK}{NBSP}día{P "" s} (edificios fundados) STR_TOWN_VIEW_TOWN_GROW_STOPPED :{BLACK}El municipio {RED}no{BLACK} está creciendo STR_TOWN_VIEW_NOISE_IN_TOWN :{BLACK}Nivel de ruido en municipio: {ORANGE}{COMMA}{BLACK} Máx.: {ORANGE}{COMMA} STR_TOWN_VIEW_CENTER_TOOLTIP :{BLACK}Centrar vista sobre el municipio. Ctrl+Click abre un punto de vista en dicha posición @@ -3993,7 +4024,7 @@ STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}La vent # AI configuration window STR_AI_CONFIG_CAPTION :{WHITE}Configuración de Scripts de Juego / IA -STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Script de Juego que será cargada en la próxima partida +STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Script de Juego que será cargado en la próxima partida STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}IAs que serán cargadas en la próxima partida STR_AI_CONFIG_HUMAN_PLAYER :Jugador Humano STR_AI_CONFIG_RANDOM_AI :IA aleatoria @@ -4178,7 +4209,7 @@ STR_ERROR_PROTECTED :{WHITE}Esta emp STR_ERROR_CAN_T_GENERATE_TOWN :{WHITE}No se puede construir ningún municipio STR_ERROR_CAN_T_RENAME_TOWN :{WHITE}No se puede renombrar el municipio... STR_ERROR_CAN_T_FOUND_TOWN_HERE :{WHITE}No se puede construir un municipio aquí... -STR_ERROR_CAN_T_EXPAND_TOWN :{WHITE}No se puede expandir municipio... +STR_ERROR_CAN_T_EXPAND_TOWN :{WHITE}No se puede expandir este municipio... STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... demasiado cercano al borde del mapa STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... demasiado cercano a otro municipio STR_ERROR_TOO_MANY_TOWNS :{WHITE}... demasiados municipios @@ -4225,7 +4256,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Demasiad STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Demasiadas partes de estación de tren STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Demasiadas paradas de autobús STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Demasiadas paradas de camión -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Demasiado cerca de otra estación/zona de carga STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Demasiado cerca de otro muelle STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Demasiado cerca de otro aeropuerto STR_ERROR_CAN_T_RENAME_STATION :{WHITE}No se puede renombrar estación... @@ -4233,6 +4263,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... esta STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... carretera en la dirección incorrecta STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... las estaciones de autobús de paso no pueden tener esquinas STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... las estaciones de autobús de paso no pueden tener intersecciones +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... carretera de un solo sentido o bloqueada # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}No se puede retirar parte de la estación... @@ -4477,13 +4508,15 @@ STR_ERROR_CAN_T_DELETE_SIGN :{WHITE}No se pu STR_DESKTOP_SHORTCUT_COMMENT :Un juego de simulación basado en Transport Tycoon Deluxe # Translatable descriptions in media/baseset/*.ob* files -STR_BASEGRAPHICS_DOS_DESCRIPTION :Gráficos originales de Transport Tycoon Deluxe versión DOS. -STR_BASEGRAPHICS_DOS_DE_DESCRIPTION :Gráficos originales de Transport Tycoon Deluxe versión DOS (Alemán). -STR_BASEGRAPHICS_WIN_DESCRIPTION :Gráficos originales de Transport Tycoon Deluxe versión Windows. -STR_BASESOUNDS_DOS_DESCRIPTION :Sonidos originales de Transport Tycoon Deluxe versión DOS. -STR_BASESOUNDS_WIN_DESCRIPTION :Sonidos originales de Transport Tycoon Deluxe versión Windows. +STR_BASEGRAPHICS_DOS_DESCRIPTION :Gráficos originales de Transport Tycoon Deluxe, versión DOS. +STR_BASEGRAPHICS_DOS_DE_DESCRIPTION :Gráficos originales de Transport Tycoon Deluxe, versión DOS (Alemán). +STR_BASEGRAPHICS_WIN_DESCRIPTION :Gráficos originales de Transport Tycoon Deluxe, versión Windows. +STR_BASESOUNDS_DOS_DESCRIPTION :Sonidos originales de Transport Tycoon Deluxe, versión DOS. +STR_BASESOUNDS_WIN_DESCRIPTION :Sonidos originales de Transport Tycoon Deluxe, versión Windows. STR_BASESOUNDS_NONE_DESCRIPTION :Un conjunto de sonidos vacío. -STR_BASEMUSIC_WIN_DESCRIPTION :Música original de Transport Tycoon Deluxe versión Windows. +STR_BASEMUSIC_WIN_DESCRIPTION :Música original de Transport Tycoon Deluxe, versión Windows. +STR_BASEMUSIC_DOS_DESCRIPTION :Música original de Transport Tycoon Deluxe, versión DOS. +STR_BASEMUSIC_TTO_DESCRIPTION :Música original de Transport Tycoon (Original/Editor de Mundos), versión DOS. STR_BASEMUSIC_NONE_DESCRIPTION :Un conjunto de música vacío. ##id 0x2000 diff --git a/src/lang/spanish_MX.txt b/src/lang/spanish_MX.txt index afca51643c..113300b766 100644 --- a/src/lang/spanish_MX.txt +++ b/src/lang/spanish_MX.txt @@ -283,7 +283,7 @@ STR_SORT_BY_CAPTION_DATE :{BLACK}Fecha STR_SORT_BY_NAME :Nombre STR_SORT_BY_PRODUCTION :Producción STR_SORT_BY_TYPE :Tipo -STR_SORT_BY_TRANSPORTED :Entregado +STR_SORT_BY_TRANSPORTED :Transportado STR_SORT_BY_NUMBER :Número STR_SORT_BY_PROFIT_LAST_YEAR :Utilidad año pasado STR_SORT_BY_PROFIT_THIS_YEAR :Utilidad este año @@ -317,7 +317,7 @@ STR_SORT_BY_RATING :Evaluación STR_TOOLBAR_TOOLTIP_PAUSE_GAME :{BLACK}Poner en pausa STR_TOOLBAR_TOOLTIP_FORWARD :{BLACK}Avance rápido STR_TOOLBAR_TOOLTIP_OPTIONS :{BLACK}Opciones -STR_TOOLBAR_TOOLTIP_SAVE_GAME_ABANDON_GAME :{BLACK}Guardar partida, retirarse, salir +STR_TOOLBAR_TOOLTIP_SAVE_GAME_ABANDON_GAME :{BLACK}Guardar partida, salir STR_TOOLBAR_TOOLTIP_DISPLAY_MAP :{BLACK}Mostrar mapa, ventana de vista adicional o lista de carteles STR_TOOLBAR_TOOLTIP_DISPLAY_TOWN_DIRECTORY :{BLACK}Mostrar guía de pueblos STR_TOOLBAR_TOOLTIP_DISPLAY_SUBSIDIES :{BLACK}Mostrar subsidios @@ -391,7 +391,7 @@ STR_SETTINGS_MENU_TRANSPARENT_SIGNS :Carteles transp ############ range for file menu starts STR_FILE_MENU_SAVE_GAME :Guardar partida STR_FILE_MENU_LOAD_GAME :Cargar partida -STR_FILE_MENU_QUIT_GAME :Retirarse de la partida +STR_FILE_MENU_QUIT_GAME :Salir de la partida STR_FILE_MENU_SEPARATOR : STR_FILE_MENU_EXIT :Salir ############ range ends here @@ -476,6 +476,7 @@ STR_ABOUT_MENU_SCREENSHOT :Captura de pant STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Captura con acercamiento completo STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Captura con acercamiento predeterminado STR_ABOUT_MENU_GIANT_SCREENSHOT :Captura de mapa completo +STR_ABOUT_MENU_SHOW_FRAMERATE :Mostrar FPS STR_ABOUT_MENU_ABOUT_OPENTTD :Acerca de 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Alineador de sprites STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Activar cajas delimitadoras @@ -651,6 +652,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}No hay música disponible STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Pista STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Título @@ -670,15 +672,15 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Elegir p STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Encender o apagar mezclador STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Mostrar ventana de selección de pistas musicales -STR_ERROR_NO_SONGS :{WHITE}Se eligió una colección vacía. No se reproducirá música - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Selección del programa musical +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Programa musical - "{STRING}" STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Lista de reproducción STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programa: '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Eliminar +STR_PLAYLIST_CHANGE_SET :{BLACK}Cambiar lista musical STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Eliminar programa actual (solo Personal 1 y Personal 2) +STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Cambiar la selección musical a otra lista instalada STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Clic en la pista de música para añadirla al programa actual (solo Personal 1 y 2) STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Clic en la pista de música para quitarla del programa actual (solo Personal 1 y 2) @@ -814,6 +816,7 @@ STR_NEWS_MERGER_TAKEOVER_TITLE :{BIG_FONT}{BLAC STR_PRESIDENT_NAME_MANAGER :{BLACK}{PRESIDENT_NAME}{}(Presidente) STR_NEWS_NEW_TOWN :{BLACK}{BIG_FONT}¡{STRING} patrocina la creación del nuevo pueblo de {TOWN}! +STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK}{BIG_FONT}¡El nuevo pueblo de {TOWN} ha sido formado! STR_NEWS_INDUSTRY_CONSTRUCTION :{BIG_FONT}{BLACK}¡Nuev{G o a} {STRING} en construcción cerca de {TOWN}! STR_NEWS_INDUSTRY_PLANTED :{BIG_FONT}{BLACK}¡Nuev{G o a} {STRING} fundad{G o a} cerca de {TOWN}! @@ -881,10 +884,10 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC # Extra view window STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Vista {COMMA} -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Copiar ventana de vista +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Cambiar ventana de vista STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Copiar la vista principal a esta ventana de vista -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Pegar ventana de vista -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Pegar esta ventana de vista en la principal +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Cambiar vista principal +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Copiar ubicación en esta vista a la principal # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opciones de juego @@ -926,6 +929,7 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :Rand sudafrican STR_GAME_OPTIONS_CURRENCY_CUSTOM :Personalizada... STR_GAME_OPTIONS_CURRENCY_GEL :Lari georgiano (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :Rial iraní (IRR) +STR_GAME_OPTIONS_CURRENCY_RUB :Nuevo rublo ruso (RUR) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Vehículos de carretera @@ -1302,7 +1306,7 @@ STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :Número de indu STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Distancia máxima de refinerías de petróleo con los bordes del mapa: {STRING} STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Las refinerías de petróleo se construyen cerca del borde del mapa, el cual es costa en mapas con borde marítimo STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Nivel de inicio de nieve: {STRING} -STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :En los mapas de clima Subártico, la elevación a la cual la nieve comienza. La nieve también afecta a la generación de industrias y a los requisitos de crecimiento de los pueblos +STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :En los mapas de clima Subártico, la elevación a la cual la nieve comienza. La nieve también afecta la generación de industrias y los requisitos de crecimiento de los pueblos STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :Irregularidad del terreno: {STRING} STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_HELPTEXT :(Solo TerraGenesis) Cantidad de colinas: los terrenos más planos tienen menos colinas, aunque suelen ser más extensas. Los terrenos más accidentados tienen múltiples colinas, lo cual puede resultar repetitivo STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Muy suave @@ -1338,8 +1342,12 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Color para el t STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Verde STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Verde oscuro STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Violeta -STR_CONFIG_SETTING_REVERSE_SCROLLING :Desplazamiento de vista invertido: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Efecto al arrastrar el mapa con el botón derecho. Si se desactiva, el ratón mueve la cámara. Si se activa, el ratón mueve el mapa +STR_CONFIG_SETTING_SCROLLMODE :Desplazamiento de vista: {STRING} +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Modo de recorrer la vista sobre el mapa +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Desplazar la vista con clic derecho, ratón en posición fija +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Recorrer mapa con clic derecho, ratón en posición fija +STR_CONFIG_SETTING_SCROLLMODE_RMB :Recorrer mapa con clic derecho +STR_CONFIG_SETTING_SCROLLMODE_LMB :Recorrer mapa con clic izquierdo STR_CONFIG_SETTING_SMOOTH_SCROLLING :Desplazamiento de vista suavizado: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Forma en la que la vista principal se mueve a una ubicación específica al hacer clic en el minimapa o tras una orden de moverse a un objeto determinado del mapa. Si se activa, la vista se mueve de forma suave. Si se desactiva, la vista se mueve instantáneamente al sitio indicado STR_CONFIG_SETTING_MEASURE_TOOLTIP :Mostrar información de medidas al usar las herramientas de construcción: {STRING} @@ -1371,8 +1379,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command+Clic STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+Clic STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Ninguno -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Desplazamiento con botón izquierdo: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Activar el desplazamiento del mapa al arrastrar con el botón izquierdo. Esto es especialmente útil al usar pantallas táctiles STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Cerrar ventana con clic derecho: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Cerrar la ventana haciendo clic derecho sobre ella. ¡Desactiva los mensajes de ayuda con clic derecho! @@ -1786,8 +1792,8 @@ STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS # Abandon game -STR_ABANDON_GAME_CAPTION :{WHITE}Retirarse de la partida -STR_ABANDON_GAME_QUERY :{YELLOW}¿Estás seguro de que deseas retirarte de esta partida? +STR_ABANDON_GAME_CAPTION :{WHITE}Salir de la partida +STR_ABANDON_GAME_QUERY :{YELLOW}¿Estás seguro de que deseas salir de esta partida? STR_ABANDON_SCENARIO_QUERY :{YELLOW}¿Estás seguro de que deseas salir de este mapa? # Cheat window @@ -2286,6 +2292,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Leyenda STR_LINKGRAPH_LEGEND_ALL :{BLACK}Todas STR_LINKGRAPH_LEGEND_NONE :{BLACK}Ninguna STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Elegir las empresas a mostrar +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}sin uso @@ -2563,7 +2570,7 @@ STR_INDUSTRY_CARGOES_HOUSES :{WHITE}Casas STR_INDUSTRY_CARGOES_INDUSTRY_TOOLTIP :{BLACK}Clic en la industria para ver sus industrias proveedoras y receptoras STR_INDUSTRY_CARGOES_CARGO_TOOLTIP :{BLACK}{STRING}{}Clic en el cargamento para ver sus industrias proveedoras y receptoras STR_INDUSTRY_DISPLAY_CHAIN :{BLACK}Mostrar cadena -STR_INDUSTRY_DISPLAY_CHAIN_TOOLTIP :{BLACK}Mostrar las industrias que proveen y reciben el cargamento +STR_INDUSTRY_DISPLAY_CHAIN_TOOLTIP :{BLACK}Mostrar las industrias que proveen y aceptan el cargamento STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP :{BLACK}Ver en minimapa STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP_TOOLTIP :{BLACK}Elegir y ver en el minimapa las industrias mostradas en el mapa principal STR_INDUSTRY_CARGOES_SELECT_CARGO :{BLACK}Elegir cargamento @@ -2591,7 +2598,7 @@ STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Tipo de STR_LAND_AREA_INFORMATION_AIRPORT_NAME :{BLACK}Nombre del aeropuerto: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_AIRPORTTILE_NAME :{BLACK}Nombre de casilla del aeropuerto: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: {LTBLUE}{STRING} -STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Cargamento recibido: {LTBLUE} +STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Cargamento aceptado: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Tipo de vía: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Límite de velocidad de ferrocarril: {LTBLUE}{VELOCITY} @@ -2694,6 +2701,56 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Copyrigh STR_ABOUT_VERSION :{BLACK}OpenTTD versión {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018, el equipo de OpenTTD +# Framerate display window +STR_FRAMERATE_CAPTION :{WHITE}FPS +STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) +STR_FRAMERATE_RATE_GAMELOOP :{BLACK}Simulación: {STRING} +STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Número de ticks simulados por segundo. +STR_FRAMERATE_RATE_BLITTER :{BLACK}FPS de gráficos: {STRING} +STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Número de cuadros por segundo. +STR_FRAMERATE_SPEED_FACTOR :{BLACK}Factor de velocidad de juego actual: {DECIMAL}x +STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Rapidez actual del juego comparada con la esperada durante una simulación normal. +STR_FRAMERATE_CURRENT :{WHITE}Actual +STR_FRAMERATE_AVERAGE :{WHITE}Promedio +STR_FRAMERATE_DATA_POINTS :{BLACK}Información de {COMMA} mediciones +STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms +STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms +STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} ms +STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} cuadros/s +STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} cuadros/s +STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} cuadros/s +STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms +STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s +############ Leave those lines in this order!! +STR_FRAMERATE_GAMELOOP :{BLACK}Bucles de juego totales: +STR_FRAMERATE_GL_ECONOMY :{BLACK} Manejo de cargamento: +STR_FRAMERATE_GL_TRAINS :{BLACK} Ticks de trenes: +STR_FRAMERATE_GL_ROADVEHS :{BLACK} Ticks de vehículos de carretera: +STR_FRAMERATE_GL_SHIPS :{BLACK} Ticks de barcos: +STR_FRAMERATE_GL_AIRCRAFT :{BLACK} Ticks de aeronaves: +STR_FRAMERATE_GL_LANDSCAPE :{BLACK} Ticks de mapa: +STR_FRAMERATE_GL_LINKGRAPH :{BLACK} Retraso en gráfica de distribución: +STR_FRAMERATE_DRAWING :{BLACK}Presentación de gráficos: +STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK} Ventanas de vista generales: +STR_FRAMERATE_VIDEO :{BLACK}Salida de video: +STR_FRAMERATE_SOUND :{BLACK}Mezcla de sonido: +############ End of leave-in-this-order +############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_GAMELOOP :Bucle de juego +STR_FRAMETIME_CAPTION_GL_ECONOMY :Manejo de cargamento +STR_FRAMETIME_CAPTION_GL_TRAINS :Ticks de trenes +STR_FRAMETIME_CAPTION_GL_ROADVEHS :Ticks de vehículos de carretera +STR_FRAMETIME_CAPTION_GL_SHIPS :Ticks de barcos +STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Ticks de areonaves +STR_FRAMETIME_CAPTION_GL_LANDSCAPE :Ticks de mapa +STR_FRAMETIME_CAPTION_GL_LINKGRAPH :Retraro en gráfica de distribución +STR_FRAMETIME_CAPTION_DRAWING :Presentación de gráficos +STR_FRAMETIME_CAPTION_DRAWING_VIEWPORTS :Presentación de ventanas de vista generales +STR_FRAMETIME_CAPTION_VIDEO :Salida de video +STR_FRAMETIME_CAPTION_SOUND :Mezcla de sonido +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Guardar partida STR_SAVELOAD_LOAD_CAPTION :{WHITE}Cargar partida @@ -2716,6 +2773,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Detalles STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}No hay información disponible STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} +STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtrar palabras: STR_SAVELOAD_OSKTITLE :{BLACK}Indicar un nombre para la partida a guardar @@ -2914,6 +2972,8 @@ STR_NEWGRF_ERROR_READ_BOUNDS :La lectura exce STR_NEWGRF_ERROR_GRM_FAILED :Recursos GRF solicitados no disponibles (sprite {3:NUM}) STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING} fue desactivado por {STRING} STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Formato de colocación de sprites no válido o desconocido (sprite {3:NUM}) +STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG :Demasiados elementos en la lista de valores de propiedad (sprite {3:NUM}, property {4:HEX}) +STR_NEWGRF_ERROR_INDPROD_CALLBACK :Llamada de producción de industria no válida (sprite {3:NUM}, "{1:STRING}") # NewGRF related 'general' warnings STR_NEWGRF_POPUP_CAUTION_CAPTION :{WHITE}¡Precaución! @@ -2978,6 +3038,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Indicar STR_TOWN_DIRECTORY_CAPTION :{WHITE}Pueblos STR_TOWN_DIRECTORY_NONE :{ORANGE}- Ninguno - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (ciudad){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Nombres de pueblos. Clic en un nombre para centrar la vista principal en el pueblo. Ctrl+Clic abre una ventana de vista en dicha ubicación STR_TOWN_POPULATION :{BLACK}Población mundial: {COMMA} @@ -2985,8 +3046,7 @@ STR_TOWN_POPULATION :{BLACK}Poblaci STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (ciudad) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Habitantes: {ORANGE}{COMMA}{BLACK} Casas: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Pasajeros mes pasado: {ORANGE}{COMMA}{BLACK} Máx.: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Correo mes pasado: {ORANGE}{COMMA}{BLACK} Máx.: {ORANGE}{COMMA} +STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} mes pasado: {ORANGE}{COMMA}{BLACK} máx.: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Cargamento necesario para crecimiento: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} requeridos STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} requerido en invierno @@ -3278,15 +3338,15 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Industrias STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Ninguna - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% entregado) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}, {CARGO_LONG}{STRING}){YELLOW} ({COMMA}%, {COMMA}% entregado) +STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% transportado) +STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}, {CARGO_LONG}{STRING}){YELLOW} ({COMMA}%, {COMMA}% transportado) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Nombre de industria: Clic en un nombre para centrar la vista principal en la industria. Ctrl+Clic abre una ventana de vista en dicha ubicación # Industry view STR_INDUSTRY_VIEW_CAPTION :{WHITE}{INDUSTRY} STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE :{BLACK}Producción mes pasado: -STR_INDUSTRY_VIEW_TRANSPORTED :{YELLOW}{CARGO_LONG}{STRING}{BLACK} ({COMMA}% entregado) +STR_INDUSTRY_VIEW_TRANSPORTED :{YELLOW}{CARGO_LONG}{STRING}{BLACK} ({COMMA}% transportado) STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Centrar la vista sobre la industria. Ctrl+Clic abre una ventana de vista en dicha ubicación STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Nivel de producción: {YELLOW}{COMMA}% STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}¡La industria ha anunciado su cierre inminente! @@ -4225,7 +4285,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Demasiad STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Demasiadas partes de estación de tren STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Demasiadas paradas de autobuses STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Demasiadas estaciones de camiones -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Demasiado cerca de otra estación o zona de carga STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Demasiado cerca de otro muelle STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Demasiado cerca de otro aeropuerto STR_ERROR_CAN_T_RENAME_STATION :{WHITE}No se puede cambiar nombre de la estación... @@ -4233,6 +4292,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... esta STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... carretera en el sentido incorrecto STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... las estaciones y paradas intermedias no pueden ponerse sobre esquinas STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... las estaciones y paradas intermedias no pueden ponerse sobre intersecciones +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... la carretera está bloqueada o es de un solo sentido # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}No se puede quitar parte de la estación... @@ -4484,6 +4544,8 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Sonidos origina STR_BASESOUNDS_WIN_DESCRIPTION :Sonidos originales de Transport Tycoon Deluxe para Windows. STR_BASESOUNDS_NONE_DESCRIPTION :Paquete de sonidos vacío STR_BASEMUSIC_WIN_DESCRIPTION :Música original de Transport Tycoon Deluxe para Windows. +STR_BASEMUSIC_DOS_DESCRIPTION :Música original de Transport Tycoon Deluxe para DOS. +STR_BASEMUSIC_TTO_DESCRIPTION :Música original de Transport Tycoon versión World Editor para DOS. STR_BASEMUSIC_NONE_DESCRIPTION :Paquete de música vacío ##id 0x2000 diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt index 255967c9d7..1e9fe336a7 100644 --- a/src/lang/swedish.txt +++ b/src/lang/swedish.txt @@ -669,10 +669,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Välj sp STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Växla slumpning av/på STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Visa fönstret för val av musikspår -STR_ERROR_NO_SONGS :{WHITE}Ett musikpaket utan låtar har valts. Ingen musik kommer att spelas - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Konstruera spellista STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Spårindex STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Spellista - '{STRING}' @@ -1337,8 +1334,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Terrängens fä STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Grön STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Mörkgrön STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Violett -STR_CONFIG_SETTING_REVERSE_SCROLLING :Omvänd scrollriktning: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Beteende för skrollning av kartan med den högra musknappen. När det är inaktiverat rör musen kameran. När det är aktiverat rör musen kartan STR_CONFIG_SETTING_SMOOTH_SCROLLING :Mjuk scrollning av vy: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Kontrollera hur huvudvyn skrollar till en specifik position vid klick på minikartan eller när ett kommando används för att skrolla till ett specifikt objekt på kartan. Om det är aktiverat skrollar vyn mjukt, om det är inaktiverat hoppar den direkt till målet STR_CONFIG_SETTING_MEASURE_TOOLTIP :Visa måtthjälptext vid användning av byggverktyg: {STRING} @@ -1370,8 +1365,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command-klick STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Control-klick STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Av -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Scrolla med vänster musknappsklick: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Aktivera skrollning av kartan genom att dra den med den vänstra musknappen. Detta är särskilt användbart för skrollning vid användning av en pekskärm STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Stäng fönster med högerklick: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Stänger fönster när man högerklickar inuti dem. Denna inställning inaktiverar tooltips vid högerklick! @@ -2693,6 +2686,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Ursprung STR_ABOUT_VERSION :{BLACK}OpenTTD-version {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 OpenTTD-teamet +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Spara spel STR_SAVELOAD_LOAD_CAPTION :{WHITE}Ladda spel @@ -2984,8 +2984,6 @@ STR_TOWN_POPULATION :{BLACK}Global f STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Stad) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Invånare: {ORANGE}{COMMA}{BLACK} Hus: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passagerare förra månaden: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Post förra månaden: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Fraktgods behövs för ortens tillväxt: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} krävs STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} krävs under vintern @@ -4224,7 +4222,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}För må STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}För många delar på järnvägsstationen STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}För många busshållplatser STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}För många lastbryggor -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}För nära en annan station/hållplats STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}För nära en annan hamn STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}För nära en annan flygplats STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Kan inte byta namn på station... diff --git a/src/lang/tamil.txt b/src/lang/tamil.txt index ec3ef56fff..d123db86e1 100644 --- a/src/lang/tamil.txt +++ b/src/lang/tamil.txt @@ -659,10 +659,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}'பய STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}'பயனரால் மாற்றியமைக்கப்பட்ட 2' பிரோகிராமினைத் தேர்ந்தெடுக்கவும் STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}இசைத் த்டத்தினைத் தேர்ந்தெடுக்கும் திரையினைக் காட்டு -STR_ERROR_NO_SONGS :{WHITE}இசைத்தடமே இல்லாதப் பட்டியல் தேர்ந்தெடுக்கப்பட்டுள்ளது. எந்த பாட்டும் ஒலிக்காது - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}இசை பிரோகிராம் தேர்ந்தெடுத்தல் STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}இசைத்தடம் வரிசை STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}பிரோகிராம் - '{STRING}' @@ -1231,7 +1228,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :சிறுப STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :பச்சை STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :கரும் பச்சை STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :ஊதா -STR_CONFIG_SETTING_REVERSE_SCROLLING :திருப்பப்பட்ட பக்கமுருட்டி திசை : {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING :பார்படத்தின் இலகுவான பக்கமுருட்டல்: {STRING} STR_CONFIG_SETTING_LIVERIES :நிறுவன livery களைக் காட்டு: {STRING} STR_CONFIG_SETTING_LIVERIES_NONE :ஒன்றுமில்லை @@ -2380,6 +2376,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}அச STR_ABOUT_VERSION :{BLACK}OpenTTD பதிப்பு {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 OpenTTD குழுமம் +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}ஆட்டத்தை பதிவு செய் STR_SAVELOAD_LOAD_CAPTION :{WHITE}பதிவு செய்த ஆட்டத்தை தொடரு @@ -2624,8 +2627,6 @@ STR_TOWN_POPULATION :{BLACK}உல STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (மாநகரம்) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}மக்கள்தொகை: {ORANGE}{COMMA}{BLACK} வீடுகள்: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}சென்ற மாத பயணிகள்: {ORANGE}{COMMA}{BLACK} அதிகம்: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}சென்ற மாத அஞ்சல்கள்: {ORANGE}{COMMA}{BLACK} அதிகம்: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}நகரத்தின் வளர்ச்சியிற்கு தேவையான சரக்குகள்: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} தேவை STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} குளிர்காலத்தில் தேவை @@ -3756,7 +3757,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}மி STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}மிக அதிகமான இரயில்வே நிலைய பாகங்கள் STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}மிக அதிகமான பேருந்து நிறுத்தங்கள் STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}மிக அதிகமான லாரி நிலையங்கள் -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}மற்றொரு நிலையத்திற்கு மிக அருகில் உள்ளது STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}மற்றொரு துறைமுகத்திற்கு மிக அருகில் உள்ளது STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}மற்றொரு விமான நிலையத்தின் அருகாமையில் உள்ளது STR_ERROR_CAN_T_RENAME_STATION :{WHITE}நிறுத்தத்தின் பெயரை மாற்ற இயலாது... diff --git a/src/lang/thai.txt b/src/lang/thai.txt index d939eeeeac..878b9c26c5 100644 --- a/src/lang/thai.txt +++ b/src/lang/thai.txt @@ -661,10 +661,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}เล STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}เปิด/ปิด Toggle programme shuffle on/off STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}แสดงหน้าต่างเลือกรายการเพลง -STR_ERROR_NO_SONGS :{WHITE}ชุดเพลงประกอบนี้ไม่มีการเลือกเพลงไว้ - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}รายการเลือกโปรแกรมเพลง STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}รายการเพลง STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}โปรแกรม - '{STRING}' @@ -1300,8 +1297,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :สีของ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :สีเขียว STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :สีเขียวแก่ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :สีม่วง -STR_CONFIG_SETTING_REVERSE_SCROLLING :กลับทิศการเลื่อนหน้าจอ: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :เลือกลักษณะการเลื่อนแผนที่ เมื่อใช้ปุ่มคลิ๊กเมาส์ขวา หากเปิดการใช้งาน หน้าจอจะเคลื่อนที่ไปในทิศตรงกันข้ามกับการคลิ๊กเมาส์ค้างแล้วลากเมาส์ไป STR_CONFIG_SETTING_SMOOTH_SCROLLING :เลื่อนอย่างนิ่มนวลบนจอภาพ: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :ควบคุมการเคลื่อนที่ของจอภาพ เวลาคลิ๊กเลือกตำแหน่งในแผนที่ย่อ หากไม่เปิดใช้งาน ตำแหน่งของจอจะย้ายไปที่ตำแหน่งที่เลือกทันที แต่หากเปิดใช้งาน จะเคลื่อนที่ไปยังตำแหน่งอย่างนุ่มนวล STR_CONFIG_SETTING_MEASURE_TOOLTIP :แสดงบอลลูนข้อความแสดงระยะทางหรือข้อมูลอื่นๆ เมื่อใช่เครื่องมือสร้าง: {STRING} @@ -1333,8 +1328,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command+คล STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+Click STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :ปิด -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :เลื่อนหน้าจอด้วยการคลิ๊กเมาส์ซ้าย: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :เปิดใช้งานเพื่อให้สามารถใช้การคลิ๊กเมาส์ซ้ายในการเลื่อนภาพหน้าจอได้ STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES :ใช้รูปแบบวันที่ {STRING} เป็นชื่อเซฟของเกม @@ -2637,6 +2630,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}ลิ STR_ABOUT_VERSION :{BLACK}OpenTTD รุ่นที่ {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}ลิขสิทธิ์ OpenTTD {COPYRIGHT}2002-2018 ของ The OpenTTD team +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}บันทึกเกม STR_SAVELOAD_LOAD_CAPTION :{WHITE}โหลดเกม @@ -2912,8 +2912,6 @@ STR_TOWN_POPULATION :{BLACK}ปร STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}นคร {TOWN} STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}จำนวนประชากร: {ORANGE}{COMMA}{BLACK} จำนวนอาคาร: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}ผู้โดยสารเมื่อเดือนที่แล้ว: {ORANGE}{COMMA}{BLACK} จำนวนสูงสุด: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}ไปรษณีย์ภัณฑ์เมื่อเดือนที่แล้ว: {ORANGE}{COMMA}{BLACK} จำนวนสูงสุด: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}ความต้องการสินค้าสำหรับการขยายตัวของเมือง: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} required STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} ต้องการหิมะ @@ -4118,7 +4116,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}มี STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}ชิ้นส่วนสถานีมากเกินไป STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}ป้ายรถเมล์มากเกินไป STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}มีจุดขนถ่ายสินค้ามากเกินไป -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}ใกล้กับสถานี/จุดขนถ่ายสินค้าอื่นเกินไป STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}ใกล้กับท่าเทียบเรืออื่นมากเกินไป STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}ใกล้กับท่าอากาศยานอื่นมากเกินไป STR_ERROR_CAN_T_RENAME_STATION :{WHITE}ไม่สามารถเปลี่ยนชื่อได้... diff --git a/src/lang/traditional_chinese.txt b/src/lang/traditional_chinese.txt index 7ce922edc1..e837d1efef 100644 --- a/src/lang/traditional_chinese.txt +++ b/src/lang/traditional_chinese.txt @@ -669,10 +669,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}選擇 STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}開關播放清單亂序播放 STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}於選擇視窗顯示樂軌 -STR_ERROR_NO_SONGS :{WHITE}已選擇不含音樂的音樂集,不會播放任何音樂 - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}背景音樂播放清單選擇 STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM}「{STRING}」 STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}音軌索引 STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}播放清單 - 「{STRING}」 @@ -1337,8 +1334,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :設定在小地 STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :綠 STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :暗綠 STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :紫 -STR_CONFIG_SETTING_REVERSE_SCROLLING :反轉捲軸方向:{STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :設定在右撳拖曳滑鼠時的系統反應。如停用此選項,移動滑鼠時會移動顯示範圍 (即影像的移動方向與滑鼠的移動方向相反)。如啟用此選項,移動滑鼠時會移動顯示地圖 (即影像的移動方向與滑鼠的移動方向相同) STR_CONFIG_SETTING_SMOOTH_SCROLLING :視野平滑移動:{STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :設定在小地圖中點選一個位置時,主視野的顯示反應。如啟用此選項,影像會移動直至到達點選的位置;否則影像會直接跳到點選的位置 STR_CONFIG_SETTING_MEASURE_TOOLTIP :使用某些建設工具時顯示度量提示:{STRING} @@ -1370,8 +1365,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command 鍵 STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Control 鍵 STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :無 -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :滑鼠左鍵捲動:{STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :容許以左撳並拖曳滑鼠捲動地圖。此選項對使用觸控螢幕進行捲動動作很有幫助 STR_CONFIG_SETTING_AUTOSAVE :自動儲存: {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :選擇自動存檔的週期 @@ -2689,6 +2682,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}原著 STR_ABOUT_VERSION :{BLACK}OpenTTD 版本 {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 OpenTTD 開發小組 +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}儲存遊戲 STR_SAVELOAD_LOAD_CAPTION :{WHITE}載入遊戲 @@ -2980,8 +2980,6 @@ STR_TOWN_POPULATION :{BLACK}世界 STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (城市) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}人口:{ORANGE}{COMMA}{BLACK} 房屋:{ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}上月乘客數字:{ORANGE}{COMMA}{BLACK} 紀錄最高:{ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}上月郵件數量:{ORANGE}{COMMA}{BLACK} 紀錄最高:{ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}市鎮成長所需貨物: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{RED}需要 {ORANGE}{STRING} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} 必須是冬天 @@ -4205,7 +4203,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}太多 STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}太多火車站元件 STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}太多公車站 STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}太多貨運站 -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}太接近另一個車站/載貨區 STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}太接近另一個碼頭 STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}太接近另一個機場 STR_ERROR_CAN_T_RENAME_STATION :{WHITE}無法修改車站名稱... diff --git a/src/lang/turkish.txt b/src/lang/turkish.txt index 763fb2a65a..c7b456f68d 100644 --- a/src/lang/turkish.txt +++ b/src/lang/turkish.txt @@ -670,10 +670,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}'Özel 2 STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Rastgele programı aç/kapa STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Şarkı seçim penceresini göster -STR_ERROR_NO_SONGS :{WHITE}Şarkısız bir müzik kümesi seçildi. Hiçbir şarkı çalınmayacak - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Müzik Program Seçimi STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Parça Listesi STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Program - '{STRING}' @@ -1338,8 +1335,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Küçük harita STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Yeşil STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Koyu yeşil STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Mor -STR_CONFIG_SETTING_REVERSE_SCROLLING :Fareyle kaydırma hareketini ters çevir: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Haritayı sağ fare tuşuyla kaydırırken davranış biçimi. Etkisiz kılındığında, fare kamerayı hareket ettirir. Etkinleştirildiğinde ise fare haritayı hareket ettirir. STR_CONFIG_SETTING_SMOOTH_SCROLLING :Düzgün viewport kaydırması: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Küçük haritaya tıklandığında veya harita üzerindeki belli bir nesneye gidilmesi için komut verildiğinde ana görüntünün nasıl kaydırılacağını kontrol eder. Etkinleştirildiğinde harita kayarak ilerler, kapatıldığında ise doğrudan hedeflenen noktaya atlama yapar. STR_CONFIG_SETTING_MEASURE_TOOLTIP :İnşa araçları kullanılırken ölçüm ipucu göster: {STRING} @@ -1371,8 +1366,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Komut-tıklama STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Kontrol-tıklama STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Kapalı -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Sol tık ile ekran kaydır: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Sol fare tuşuyla sürükleyerek harita kaydırma özelliğini etkinleştir. Özellikle dokunmatik-ekran kullanırken kaydırma yapmak için kullanılabilir. STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Sağ tıklama ile pencereyi kapat: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :İçerisinde sağ tıklandığında pencereyi kapatır. Sağ tıklandığında ipuçları gösterimini devre dışı bırakır! @@ -2694,6 +2687,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Telif ha STR_ABOUT_VERSION :{BLACK}OpenTTD sürüm {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 OpenTTD ekibi +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Oyunu Kaydet STR_SAVELOAD_LOAD_CAPTION :{WHITE}Yükle @@ -2985,8 +2985,6 @@ STR_TOWN_POPULATION :{BLACK}Dünya n STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Şehir) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Nüfus: {ORANGE}{COMMA}{BLACK} Ev: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Geçen ayki yolcu: {ORANGE}{COMMA}{BLACK} azami: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Geçen ayki posta: {ORANGE}{COMMA}{BLACK} azami: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Kasaba büyümesi için gerekli kargo: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} gerekli STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} kışın gerekir @@ -4225,7 +4223,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Haritada STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Çok fazla demiryolu istasyon parçası var STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Çok fazla durak var STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Çok fazla kamyon yükleme yeri var -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Başka bir istasyona çok yakın STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Başka bir limana çok yakın STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Başka bir havalimanına çok yakın STR_ERROR_CAN_T_RENAME_STATION :{WHITE}İsim değiştirilemiyor... diff --git a/src/lang/ukrainian.txt b/src/lang/ukrainian.txt index dbb815d2dc..d4f33017f1 100644 --- a/src/lang/ukrainian.txt +++ b/src/lang/ukrainian.txt @@ -797,10 +797,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Вибр STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Вкл./відкл. випадкову програму STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Показує вікно вибору музичної програми -STR_ERROR_NO_SONGS :{WHITE}Був обраний музичний набір без пісень. Пісні не будуть програватись - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Вибір музичної програми STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Назва доріжки STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Програма - '{STRING}' @@ -1465,8 +1462,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Колір по STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :зелений STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :темнозелений STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :фіолетовий -STR_CONFIG_SETTING_REVERSE_SCROLLING :Змінити напрямок прокрутки: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Налаштування переміщення по карті правою кнопкою миші. При включенні переміщується карта. При виключенні - камера. STR_CONFIG_SETTING_SMOOTH_SCROLLING :Плавна прокрутка у вікні: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Налаштування способу прокрутки основного екрану при клацанні мишою по зменшенній карті, або інших діях, що призводять до переміщення по карті (кнопки "Оглянути", тощо). При включенні опції переміщення карти відбувається плавно. При виключенні - відбувається моментальне переміщення в необхідну точку STR_CONFIG_SETTING_MEASURE_TOOLTIP :Показувати підказки про розміри під час будівництва: {STRING} @@ -1498,8 +1493,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Команда+ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+клац мишою STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :не емулювати -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Прокрутка по лівому клацу миші: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Дозволяє "тягати" карту утримуючи ліву кнопку миші, що дає можливість використовувати сенсорні екрани природнім способом.. STR_CONFIG_SETTING_AUTOSAVE :Автозбереження: {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :Оберіть проміжок між автоматичними збереженнями гри @@ -2820,6 +2813,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Авто STR_ABOUT_VERSION :{BLACK}OpenTTD версія {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 команда OpenTTD +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Зберегти гру STR_SAVELOAD_LOAD_CAPTION :{WHITE}Завантажити гру @@ -3111,8 +3111,6 @@ STR_TOWN_POPULATION :{BLACK}Насе STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (місто) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Населення: {ORANGE}{COMMA}{BLACK} Будинки: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Пасажирів за місяць: {ORANGE}{COMMA}{BLACK} найбільше: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Пошти за місяць: {ORANGE}{COMMA}{BLACK} найбільше: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Вантаж, потрібний для зростання міста: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} потрібно STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} потрібно взимку @@ -4336,7 +4334,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Дуже STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Забагато частин залізничної станції STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Дуже багато зупинок STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Дуже багато вантажних станцій -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Дуже близько до іншої станції STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Дуже близько до іншого порту STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Дуже близько до іншого аеропорту STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Неможливо перейменувати станцію... diff --git a/src/lang/unfinished/chuvash.txt b/src/lang/unfinished/chuvash.txt index a9f98fe138..474c328f96 100644 --- a/src/lang/unfinished/chuvash.txt +++ b/src/lang/unfinished/chuvash.txt @@ -403,7 +403,6 @@ STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKG STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Кӗвӗ STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Ят - # Playlist window STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Тасат @@ -971,6 +970,13 @@ STR_LAI_OBJECT_DESCRIPTION_LIGHTHOUSE :Маяк # About OpenTTD window STR_ABOUT_VERSION :{BLACK}OpenTTD верси {REV} +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario diff --git a/src/lang/unfinished/frisian.txt b/src/lang/unfinished/frisian.txt index 051b62c843..624eec2f33 100644 --- a/src/lang/unfinished/frisian.txt +++ b/src/lang/unfinished/frisian.txt @@ -669,10 +669,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Selektea STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Set musyk mjokselje oan/út STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Lit musykseleksjeskerm sjen. -STR_ERROR_NO_SONGS :{WHITE}In musykset sûnder nûmers is selektearre. Gjin nûmers sille spile wurden - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Musykprogramseleksje STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Nûmeryndeks STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Program - '{STRING}' @@ -1329,8 +1326,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Kleur fan it l STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Grien STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Donker grien STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Fiolet -STR_CONFIG_SETTING_REVERSE_SCROLLING :Draai scrollrjochtig om: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :By útskeakeljen beweecht de mûs de kamera. By ynskeakeljen beweecht de mûs de kaart STR_CONFIG_SETTING_SMOOTH_SCROLLING :Loaitsfinster floeiend scrolle : {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Bepaalt hoe it haadfinster scrollt. By ynskeakeljen sil dit floeiend wêze. By útskeakeljen ljept it byld direktst nei de selektearre lokaasje STR_CONFIG_SETTING_MEASURE_TOOLTIP :Under it gebrûk fan de ferskate bou-arken diminsjes sjen litte: {STRING} @@ -1362,8 +1357,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Kommando+Klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+Klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Ut -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Scrolle mei lofter mûsknop: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Skeakel scrollen mei de lofter mûsknop oan. Dit is brûksum foar scollen op oanreitsskermen STR_CONFIG_SETTING_AUTOSAVE :Automatysk bewarje: {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :Selektearje de tiid tusken automatysk bewarje fan it spul @@ -2477,6 +2470,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Orizjine STR_ABOUT_VERSION :{BLACK}OpenTTD-ferzje {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2018 It OpenTTD team +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Spul Opslaan STR_SAVELOAD_LOAD_CAPTION :{WHITE}Spul Lade @@ -2754,8 +2754,6 @@ STR_TOWN_POPULATION :{BLACK}Wrâldpo STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (City) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Ynwenners: {ORANGE}{COMMA}{BLACK} Hûzen: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passazjiers lêste moanne: {ORANGE}{COMMA}{BLACK} maks: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Post lêste moanne: {ORANGE}{COMMA}{BLACK} maks: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Guod nedich foar stêdsgroei: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} ferplichte STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} ferplichte yn de winter @@ -3758,7 +3756,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Te folle STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Te folle stasjonsdielen STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Te folle bushaltes STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Te folle frachtstasjons -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Te ticht by in oar stasjon STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Te ticht by in oare haven STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Te ticht by in oar fleanfjild STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Kin namme fan stasjon net feroarje diff --git a/src/lang/unfinished/ido.txt b/src/lang/unfinished/ido.txt index 4f4d4846ff..114c434f36 100644 --- a/src/lang/unfinished/ido.txt +++ b/src/lang/unfinished/ido.txt @@ -377,7 +377,6 @@ STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKG STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" - # Playlist window # Highscore window @@ -778,6 +777,13 @@ STR_LAI_OBJECT_DESCRIPTION_COMPANY_HEADQUARTERS :Stabeyo di komp STR_ABOUT_VERSION :{BLACK}OpenTTD versiono {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2018 La kruo OpenTTD +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Ludo Detali STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} diff --git a/src/lang/unfinished/macedonian.txt b/src/lang/unfinished/macedonian.txt index 6a0157c5a8..30a0f142b1 100644 --- a/src/lang/unfinished/macedonian.txt +++ b/src/lang/unfinished/macedonian.txt @@ -641,10 +641,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Избе STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Вклучи/исклучи мешање за програм STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Прикажи диалог за избор на песна -STR_ERROR_NO_SONGS :{WHITE}Музички сет без песни е избран. Не песни ќе се одигра - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Избор на музички програм STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Индекс на песната STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Програм - '{STRING}' @@ -1204,6 +1201,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Ориг STR_ABOUT_VERSION :{BLACK}OpenTTD верзија {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2018 OpenTTD тимот +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_LOAD_BUTTON :{BLACK}Оптоварување STR_SAVELOAD_LOAD_TOOLTIP :{BLACK}Оптоварување на избраната игра diff --git a/src/lang/unfinished/maltese.txt b/src/lang/unfinished/maltese.txt index 628fe94cfc..4fc0e8cb10 100644 --- a/src/lang/unfinished/maltese.txt +++ b/src/lang/unfinished/maltese.txt @@ -346,7 +346,6 @@ STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKG STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" - # Playlist window # Highscore window @@ -683,6 +682,13 @@ STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Aghzel i # About OpenTTD window +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario diff --git a/src/lang/unfinished/marathi.txt b/src/lang/unfinished/marathi.txt index 2437182361..4576bccbae 100644 --- a/src/lang/unfinished/marathi.txt +++ b/src/lang/unfinished/marathi.txt @@ -628,10 +628,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}'कस STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}कार्यक्रम चुळबूळ - प्रारंभ / बंद STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}संगीत ट्रॅक निवड दाखवा -STR_ERROR_NO_SONGS :{WHITE}संगीत न संगीत संच निवडले गेले आहे. एकही गाणी खेळला जाईल. - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}संगीत कार्यक्रम निवड. STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}गाणे क्रमांक STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}कार्यक्रम - '{STRING}' @@ -1110,6 +1107,13 @@ STR_LAI_WATER_DESCRIPTION_RIVER :नदी # About OpenTTD window STR_ABOUT_OPENTTD :{WHITE}ओपेन टीटीडी बद्दल +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_BYTES_FREE :{BLACK}{BYTES} मोकळ STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} diff --git a/src/lang/unfinished/persian.txt b/src/lang/unfinished/persian.txt index 9701899630..231f11af81 100644 --- a/src/lang/unfinished/persian.txt +++ b/src/lang/unfinished/persian.txt @@ -658,10 +658,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}انتخ STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}پخش به صورت لیست برهم ریخته STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}نمایش پنجره لیست آهنگهای انتخابی -STR_ERROR_NO_SONGS :{WHITE}در مجموعه موسیقی آهنگی انتخاب نشده است. هیچ آهنگی پخش نخواهد شد - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}انتخاب برنامه پخش موسیقی STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}شماره ی آهنگ STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}برنامه - '{STRING}' @@ -1227,7 +1224,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR :رنگ استف STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :سبز STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :سبز تیره STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :بنفش -STR_CONFIG_SETTING_REVERSE_SCROLLING :برعکس کردن جهت حرکت کردن صفحه: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING :تصویر صاف در نمای اضافه: {STRING} STR_CONFIG_SETTING_MEASURE_TOOLTIP :نمایش متن کمکی وقتی از چندین ابزار استفاده می شود: {STRING} STR_CONFIG_SETTING_LIVERIES :نمایش طراحی مخصوص وسیله نقلیه : {STRING} @@ -1247,7 +1243,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :دستور+کل STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :کنترل+کلیک STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :خاموش -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :حرکت در نقشه با کلیک چپ:: {STRING} STR_CONFIG_SETTING_AUTOSAVE :ذخیره خودکار: {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :انتخاب فاصله زمانی بین ذخیره کردن های خودکار @@ -2391,6 +2386,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Original STR_ABOUT_VERSION :{BLACK}OpenTTD ویرایش {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2018 The OpenTTD team +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}ذخیره ی بازی STR_SAVELOAD_LOAD_CAPTION :{WHITE}ادامه ی بازی @@ -2663,8 +2665,6 @@ STR_TOWN_POPULATION :{BLACK}جمعی STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (شهر) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}جمعیت: {ORANGE}{COMMA}{BLACK} خانه ها: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}مسافران در ماه گذشته: {ORANGE}{COMMA}{BLACK} حداکثر: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}نامه ها در ماه گذشته: {ORANGE}{COMMA}{BLACK} حداکثر: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}نوع بار برای رشد شهر: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} ضروری STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} در زمستان ضروری است @@ -3412,7 +3412,6 @@ STR_ERROR_CAN_T_BUILD_AIRPORT_HERE :{WHITE}نمی STR_ERROR_STATION_TOO_SPREAD_OUT :{WHITE}ایستگاه زیادی پراکنده شده است STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}تعداد محوطه های بارگیری/ایستگاه بسیار زیاد شده -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}به محوطه ی بارگیری/ایستگاه دیگری بسیار نزدیک است STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}به بندر دیگری بسییار نزدیک است STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}به فرودگاه دیگری بسیار نزدیک شده STR_ERROR_CAN_T_RENAME_STATION :{WHITE}نام این ایستگاه را نمی شود تغییر داد diff --git a/src/lang/unfinished/urdu.txt b/src/lang/unfinished/urdu.txt index 324e073aa4..b5fd180e01 100644 --- a/src/lang/unfinished/urdu.txt +++ b/src/lang/unfinished/urdu.txt @@ -649,10 +649,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}'اپن STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}پروگرام ہلانے کی تدویم کیجئیے STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}گانا چننے کا اختیار دینے والی ونڈو دکھائیں -STR_ERROR_NO_SONGS :{WHITE}کوئی گانا دستیاب نہیں ہے - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}موسیقی کے پروگرام کا انتخاب کریں STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}گانوں کی فہرست STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}پروگرام - '{STRING}' @@ -2129,6 +2126,13 @@ STR_FOUND_TOWN_SELECT_LAYOUT_RANDOM :{G=f}{BLACK}ک STR_ABOUT_OPENTTD :{WHITE}اوپن ٹی ٹی ڈی کے متعلق STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} ٢٠٠٢ - ٢٠١٦ OpenTTD ٹیم +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario diff --git a/src/lang/vietnamese.txt b/src/lang/vietnamese.txt index 19fbce1cfd..61a15d3681 100644 --- a/src/lang/vietnamese.txt +++ b/src/lang/vietnamese.txt @@ -475,6 +475,7 @@ STR_ABOUT_MENU_SCREENSHOT :Ảnh chụp m STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Phóng to đầy đủ ảnh chụp màn hình STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Phóng to mặc định ảnh chụp màn hình STR_ABOUT_MENU_GIANT_SCREENSHOT :Ảnh màn hình toàn bản đồ +STR_ABOUT_MENU_SHOW_FRAMERATE :Hiển thị tốc độ khung hình STR_ABOUT_MENU_ABOUT_OPENTTD :Giới thiệu 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Trình điều chỉnh sprite STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Bật/tắt hiển thị khối nhà @@ -650,6 +651,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}Không sẵn có nhạc nền STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Bài Nhạc STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Tên @@ -669,15 +671,15 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Chọn k STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Bật/tắt chơi nhạc ngẫu nhiên STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Hiện cửa số chọn bài nhạc -STR_ERROR_NO_SONGS :{WHITE}Đã chọn gói nhạc chuẩn nhưng không có bài nào. Không có bài nào để chơi - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Chọn Kiểu Chơi Nhạc +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Danh sách nhạc - '{STRING}' STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Bảng Bài Nhạc STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Chương Trình - '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Xóa +STR_PLAYLIST_CHANGE_SET :{BLACK}Tập danh sách thay đổi STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Xóa chương trình đang chọn ("Tự chọn 1" và "Tự chọn 2") +STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Thay đổi lựa chọn danh sách nhạc khác STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Click vào bài nhạc để thêm vào chương trình hiện tại (cho "Tự chọn 1" hay "Tự chọn 2") STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Click vào bài nhạc để xóa khỏi chương trình hiện tại (cho "Tự chọn 1" hay "Tự chọn 2") @@ -813,6 +815,7 @@ STR_NEWS_MERGER_TAKEOVER_TITLE :{BIG_FONT}{BLAC STR_PRESIDENT_NAME_MANAGER :{BLACK}{PRESIDENT_NAME}{}(Giám Đốc) STR_NEWS_NEW_TOWN :{BLACK}{BIG_FONT}{STRING} Tài trợ xây dựng Thị Xã mới {TOWN}! +STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK}{BIG_FONT}Một đô thị mới vừa được xây dựng, có tên là {TOWN}! STR_NEWS_INDUSTRY_CONSTRUCTION :{BIG_FONT}{BLACK}{STRING} mới đang được xây dựng gần {TOWN}! STR_NEWS_INDUSTRY_PLANTED :{BIG_FONT}{BLACK}{STRING} được lên kế hoạch xây gần {TOWN}! @@ -880,10 +883,10 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC # Extra view window STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Cửa sổ {COMMA} -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Nhìn ở cửa sổ lớn +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Đổi khung nhìn STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Nhìn vị trí này ở cửa sổ lớn chính -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Chuyển về cửa sổ nhỏ -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Chuyển vị trí từ cửa sổ lớn về cửa sổ nhỏ +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Chuyển về cửa sổ chính +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Sao chép vị trí từ cửa sổ này về cửa sổ lớn # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Cấu Hình Trò Chơi @@ -925,6 +928,7 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :Rand Nam Phi (Z STR_GAME_OPTIONS_CURRENCY_CUSTOM :Tùy chọn... STR_GAME_OPTIONS_CURRENCY_GEL :Lari Georgia (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :Rial Iran (IRR) +STR_GAME_OPTIONS_CURRENCY_RUB :Đồng Rúp Nga mới (RUB) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Xe cộ @@ -1337,8 +1341,12 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Màu sắc củ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Lục STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Lục tối STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Tím -STR_CONFIG_SETTING_REVERSE_SCROLLING :Đảo ngược hướng cuộn: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Phản ứng khi cuộn bản đồ bằng nút chuột phải. Nếu tắt, thì chuột di chuyển theo vùng nhìn. Nếu bật thì chuột di chuyển theo bản đồ +STR_CONFIG_SETTING_SCROLLMODE :Kiểu cuộn khung nhìn: {STRING} +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Hành xử khi kéo, cuộn bản đồ +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Kéo cuộn khung nhìn kiểu RMB, khoá vị trí con trỏ chuột +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Kéo cuộn kiểu RMB, khoá vị trí con trỏ chuột +STR_CONFIG_SETTING_SCROLLMODE_RMB :Kéo cuộn bản đồ kiểu RMB +STR_CONFIG_SETTING_SCROLLMODE_LMB :Kéo cuộn bản đồ kiểu LMB STR_CONFIG_SETTING_SMOOTH_SCROLLING :Cuộn uyển chuyển cửa sổ: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Điều khiển cách màn hình chính cuộn tới vị trí cụ thể khi nháy chuột vào bản đồ nhỏ hoặc khi gõ lệnh cuộn tới đối tượng trên bản đồ. Nếu bật, thì sẽ cuộn trượt, nếu tắt thì nhảy thẳng tới vị trí đó. STR_CONFIG_SETTING_MEASURE_TOOLTIP :Hiện bảng chú giải đo lường khi dùng các công cụ xây dựng: {STRING} @@ -1370,8 +1378,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command+Click STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+Click STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Tắt -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Cuộn chuột trái: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Cho phép cuộn bản đồ bằng cách kéo với nút trái chuột. Tùy chọn này sẽ hữu ích khi dùng màn hình cảm ứng STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Đóng cửa số khi click chuột phải: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Đóng cửa sổ bằng cách bấm chuột phải vào đó. Ngăn tooltip bằng cách bấm phải! @@ -2285,6 +2291,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Ghi chú STR_LINKGRAPH_LEGEND_ALL :{BLACK}Tất cả STR_LINKGRAPH_LEGEND_NONE :{BLACK}Không STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Lựa chọn công ty nào sẽ được hiển thị +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}không sử dụng @@ -2693,6 +2700,56 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Nguyên STR_ABOUT_VERSION :{BLACK}OpenTTD phiên bản {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 Nhóm OpenTTD +# Framerate display window +STR_FRAMERATE_CAPTION :{WHITE}Tốc độ khung hình +STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) +STR_FRAMERATE_RATE_GAMELOOP :{WHITE}Tốc độ khung giả lập game: {STRING} +STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Số nhịp đếm giả lập trong mỗi giây +STR_FRAMERATE_RATE_BLITTER :{WHITE}Tốc độ khung hình: {STRING} +STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Số khu hình vẽ lại mỗi giây. +STR_FRAMERATE_SPEED_FACTOR :{WHITE}Chỉ số vận tốc game hiện tại: {DECIMAL}x +STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Tốc độ chạy game hiện tại, so với tốc độ bình thường +STR_FRAMERATE_CURRENT :{WHITE}Hiện tại +STR_FRAMERATE_AVERAGE :{WHITE}Trung bình +STR_FRAMERATE_DATA_POINTS :{WHITE}Dữ liệu được tính theo số đo {COMMA} +STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL}{WHITE} ms +STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL}{WHITE} ms +STR_FRAMERATE_MS_BAD :{RED}{DECIMAL}{WHITE} ms +STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL}{WHITE} khung/s +STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL}{WHITE} khung/s +STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL}{WHITE} khung/s +STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms +STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s +############ Leave those lines in this order!! +STR_FRAMERATE_GAMELOOP :{WHITE}Tổng vòng lặp khung hình game: +STR_FRAMERATE_GL_ECONOMY :{WHITE} Xử lý bốc dỡ hàng: +STR_FRAMERATE_GL_TRAINS :{WHITE} Nhịp của tàu hoả: +STR_FRAMERATE_GL_ROADVEHS :{WHITE} Nhịp của xe ô-tô +STR_FRAMERATE_GL_SHIPS :{WHITE} Số nhịp của tàu thủy: +STR_FRAMERATE_GL_AIRCRAFT :{WHITE} Số nhịp của máy bay: +STR_FRAMERATE_GL_LANDSCAPE :{WHITE} Nhịp của bản đồ game: +STR_FRAMERATE_GL_LINKGRAPH :{WHITE} Độ trễ tính toán đồ thị: +STR_FRAMERATE_DRAWING :{WHITE}Cách vẽ đồ hoạ game: +STR_FRAMERATE_DRAWING_VIEWPORTS :{WHITE} Khung nhìn toàn bản đồ: +STR_FRAMERATE_VIDEO :Nguồn xuất hình: +STR_FRAMERATE_SOUND :{WHITE}Trộn âm thanh: +############ End of leave-in-this-order +############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_GAMELOOP :Vòng lặp khung hình game +STR_FRAMETIME_CAPTION_GL_ECONOMY :Bốc dỡ hàng +STR_FRAMETIME_CAPTION_GL_TRAINS :Nhịp cho tàu hoả +STR_FRAMETIME_CAPTION_GL_ROADVEHS :Số nhịp xe ôtô +STR_FRAMETIME_CAPTION_GL_SHIPS :Nhịp của tàu thủy +STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Nhịp cho máy bay +STR_FRAMETIME_CAPTION_GL_LANDSCAPE :Nhịp của bản đồ +STR_FRAMETIME_CAPTION_GL_LINKGRAPH :Độ trễ tính toán đồ thị +STR_FRAMETIME_CAPTION_DRAWING :Cách vẽ đồ hoạ game +STR_FRAMETIME_CAPTION_DRAWING_VIEWPORTS :Khung vẽ cả bản đồ game +STR_FRAMETIME_CAPTION_VIDEO :Ngõ xuất hình +STR_FRAMETIME_CAPTION_SOUND :Trộn âm thanh +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Lưu Ván Chơi STR_SAVELOAD_LOAD_CAPTION :{WHITE}Nạp Ván Chơi @@ -2977,6 +3034,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Nhập t STR_TOWN_DIRECTORY_CAPTION :{WHITE}Đô Thị STR_TOWN_DIRECTORY_NONE :{ORANGE}- Không Có - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (đô thị){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Tên các đô thị - nháy vào tên để xem trung tâm đô thị. Ctrl+Click mở cửa sổ mới về vị trí đô thị STR_TOWN_POPULATION :{BLACK}Dân số thế giới: {COMMA} @@ -2984,8 +3042,7 @@ STR_TOWN_POPULATION :{BLACK}Dân s STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Thành Phố) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Dân số: {ORANGE}{COMMA}{BLACK} Toà nhà: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Du khách tháng trước: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Bưu kiện tháng trước: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} +STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} tháng trước: {ORANGE}{COMMA}{BLACK} tối đa: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Hàng hoá cần để đô thị tăng trưởng: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} được yêu cầu STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} Yêu cầu trong mùa đông @@ -4224,7 +4281,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Quá nhi STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Quá nhiều mảnh của ga tàu hoả STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Quá nhiều điểm đừng xe buýt STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Quá nhiều trạm bốc dỡ hàng xe tải -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Quá sát với một bến khác STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Quá sát với hải cảng khác STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Quá sát với sân bay khác STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Không thể đổi tên ga, bến,cảng... @@ -4232,6 +4288,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... đâ STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... đường quay mặt sai hướng STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... đi qua điểm dừng không thể đi qua góc STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... đi qua điểm dừng không thể có ngã rẽ +STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... đường 1 chiều hoặc bị chặn # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Không thể xoá bỏ một phần của ga... @@ -4483,6 +4540,8 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Âm thanh gốc STR_BASESOUNDS_WIN_DESCRIPTION :Âm thanh gốc từ phiên bản Transport Tycoon Deluxe trên Windows STR_BASESOUNDS_NONE_DESCRIPTION :Gói âm thanh này không có âm thanh nào. STR_BASEMUSIC_WIN_DESCRIPTION :Nhạc gốc từ phiên bản Transport Tycoon Deluxe trên Windows +STR_BASEMUSIC_DOS_DESCRIPTION :Nhạc của nguyên bản Transport Tycoon Deluxe cho DOS. +STR_BASEMUSIC_TTO_DESCRIPTION :Nhạc của nguyên bản Transport Tycoon (Original/World Editor) cho DOS. STR_BASEMUSIC_NONE_DESCRIPTION :Gói âm nhạc này không có nhạc nào. ##id 0x2000 diff --git a/src/lang/welsh.txt b/src/lang/welsh.txt index 6e77712da4..9561354fb0 100644 --- a/src/lang/welsh.txt +++ b/src/lang/welsh.txt @@ -669,10 +669,7 @@ STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Dewis y STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Toglu cymysgu trefn rhaglen ymlaen neu i ffwrdd STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Dangos y ffenestr dewis traciau cerddoriaeth -STR_ERROR_NO_SONGS :{WHITE}Dewiswyd set caneuon heb ganeuon ynddo. Ni chwaraeir unrhyw ganeuon - # Playlist window -STR_PLAYLIST_MUSIC_PROGRAM_SELECTION :{WHITE}Dewisiadau Rhaglen Gerddoriaeth STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Indecs Traciau STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Rhaglen - '{STRING}' @@ -1337,8 +1334,6 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Lliw y tirwedd STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Gwyrdd STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Gwyrdd tywyll STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Fioled -STR_CONFIG_SETTING_REVERSE_SCROLLING :Gwrthdroi'r cyfeiriad sgrolio: {STRING} -STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT :Ymddygiad pan yn sgrolio gyda botwm dde y llygoden. Pan yr analluogir, bydd y llygoden yn symyd y camera. Pan y galluogir, bydd y llygoden yn symyd y map STR_CONFIG_SETTING_SMOOTH_SCROLLING :Sgrolio prif ffenestr llyfn: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Rheoli syt y mae'r prif olygfa'n sgrolio at leoliad penodol pan yn clicio ar y map bychan neu yn rhoi gorchymyn i sgrolio at wrthrych penodol STR_CONFIG_SETTING_MEASURE_TOOLTIP :Dangos cymorth mesur wrth ddefnyddio'r offer adeiladu amrywiol: {STRING} @@ -1370,8 +1365,6 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command-clic STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+Clic STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :I ffwrdd -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING :Sgrolio Clic-chwith: {STRING} -STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT :Galluogi sgrolio ar y map drwy ei lusgo gyda botwm chwith y llygoden. Mae hyn yn arbennig o ddefnyddiol pan yn defnyddio sgrin-gyffwrdd ar gyfer sgrolio STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Cau ffenest wrth dde-glicio: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Cau ffenest wrth dde-glicio tu fewn iddo. Mae hyn yn analluogi dangos gwybodaeth ar dde-clicio! @@ -2693,6 +2686,13 @@ STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Hawlfrai STR_ABOUT_VERSION :{BLACK}fersiwn OpenTTD {REV} STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2018 Y tîm OpenTTD +# Framerate display window +############ Leave those lines in this order!! +############ End of leave-in-this-order +############ Leave those lines in this order!! +############ End of leave-in-this-order + + # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Cadw Gêm STR_SAVELOAD_LOAD_CAPTION :{WHITE}Llwytho Gêm @@ -2984,8 +2984,6 @@ STR_TOWN_POPULATION :{BLACK}Poblogae STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Dinas) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Poblogaeth: {ORANGE}{COMMA}{BLACK} Tai: {ORANGE}{COMMA} -STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Teithwyr mis diwethaf: {ORANGE}{COMMA}{BLACK} uchafswm: {ORANGE}{COMMA} -STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Post mis diwethaf: {ORANGE}{COMMA}{BLACK} uchafswm: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Nwyddau angenrheidiol ar gyfer tyfiant y dref: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{RED}Angen {ORANGE}{STRING} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} ei angen yn y gaeaf @@ -4224,7 +4222,6 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Gormod o STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Mae gan yr orsaf ormod o rannau STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Gormod o arosfannau bysus STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Gormod o orsafoedd lorïau -STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION :{WHITE}Rhy agos i orsaf/ardal lwytho STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Rhy agos i ddoc arall STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Rhy agos i faes awyr arall STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Methu ailenwi gorsaf... diff --git a/src/linkgraph/demands.cpp b/src/linkgraph/demands.cpp index f4afbabf0a..f1b714820b 100644 --- a/src/linkgraph/demands.cpp +++ b/src/linkgraph/demands.cpp @@ -115,7 +115,6 @@ public: * Check if there is any acceptance left for this node. In asymmetric distribution * nodes always accept as long as their demand > 0. * @param to The node to be checked. - * @param to_anno Unused. */ inline bool HasDemandLeft(const Node &to) { return to.Demand() > 0; } }; diff --git a/src/linkgraph/demands.h b/src/linkgraph/demands.h index c3d9dc7cda..8a639b8b15 100644 --- a/src/linkgraph/demands.h +++ b/src/linkgraph/demands.h @@ -30,7 +30,7 @@ public: /** * Call the demand calculator on the given component. - * @param graph Component to calculate the demands for. + * @param job Component to calculate the demands for. */ virtual void Run(LinkGraphJob &job) const { DemandCalculator c(job); } diff --git a/src/linkgraph/flowmapper.cpp b/src/linkgraph/flowmapper.cpp index 4b974a809e..b78b30335e 100644 --- a/src/linkgraph/flowmapper.cpp +++ b/src/linkgraph/flowmapper.cpp @@ -16,7 +16,7 @@ /** * Map the paths generated by the MCF solver into flows associated with nodes. - * @param component the link graph component to be used. + * @param job the link graph component to be used. */ void FlowMapper::Run(LinkGraphJob &job) const { diff --git a/src/linkgraph/linkgraph.cpp b/src/linkgraph/linkgraph.cpp index 50945d361f..34b3a4aa09 100644 --- a/src/linkgraph/linkgraph.cpp +++ b/src/linkgraph/linkgraph.cpp @@ -252,8 +252,6 @@ void LinkGraph::Node::RemoveEdge(NodeID to) * least the given capacity and usage, otherwise add the capacity and usage. * In any case set the respective update timestamp(s), according to the given * mode. - * @param from Start node of the edge. - * @param to End node of the edge. * @param capacity Capacity to be added/updated. * @param usage Usage to be added. * @param mode Update mode to be applied. diff --git a/src/linkgraph/linkgraph_gui.cpp b/src/linkgraph/linkgraph_gui.cpp index 1fe34fe79c..30c4451ee7 100644 --- a/src/linkgraph/linkgraph_gui.cpp +++ b/src/linkgraph/linkgraph_gui.cpp @@ -298,7 +298,7 @@ Point LinkGraphOverlay::GetStationMiddle(const Station *st) const * Set a new cargo mask and rebuild the cache. * @param cargo_mask New cargo mask. */ -void LinkGraphOverlay::SetCargoMask(uint32 cargo_mask) +void LinkGraphOverlay::SetCargoMask(CargoTypes cargo_mask) { this->cargo_mask = cargo_mask; this->RebuildCache(); @@ -319,7 +319,7 @@ void LinkGraphOverlay::SetCompanyMask(uint32 company_mask) /** Make a number of rows with buttons for each company for the linkgraph legend window. */ NWidgetBase *MakeCompanyButtonRowsLinkGraphGUI(int *biggest_index) { - return MakeCompanyButtonRows(biggest_index, WID_LGL_COMPANY_FIRST, WID_LGL_COMPANY_LAST, 3, STR_LINKGRAPH_LEGEND_SELECT_COMPANIES); + return MakeCompanyButtonRows(biggest_index, WID_LGL_COMPANY_FIRST, WID_LGL_COMPANY_LAST, 3, STR_NULL); } NWidgetBase *MakeSaturationLegendLinkGraphGUI(int *biggest_index) @@ -425,7 +425,7 @@ LinkGraphLegendWindow::LinkGraphLegendWindow(WindowDesc *desc, int window_number /** * Set the overlay belonging to this menu and import its company/cargo settings. - * @params overlay New overlay for this menu. + * @param overlay New overlay for this menu. */ void LinkGraphLegendWindow::SetOverlay(LinkGraphOverlay *overlay) { this->overlay = overlay; @@ -435,7 +435,7 @@ void LinkGraphLegendWindow::SetOverlay(LinkGraphOverlay *overlay) { this->SetWidgetLoweredState(WID_LGL_COMPANY_FIRST + c, HasBit(companies, c)); } } - uint32 cargoes = this->overlay->GetCargoMask(); + CargoTypes cargoes = this->overlay->GetCargoMask(); for (uint c = 0; c < NUM_CARGO; c++) { if (!this->IsWidgetDisabled(WID_LGL_CARGO_FIRST + c)) { this->SetWidgetLoweredState(WID_LGL_CARGO_FIRST + c, HasBit(cargoes, c)); @@ -496,10 +496,48 @@ void LinkGraphLegendWindow::DrawWidget(const Rect &r, int widget) const if (this->IsWidgetDisabled(widget)) return; CargoSpec *cargo = CargoSpec::Get(widget - WID_LGL_CARGO_FIRST); GfxFillRect(r.left + 2, r.top + 2, r.right - 2, r.bottom - 2, cargo->legend_colour); - DrawString(r.left, r.right, (r.top + r.bottom + 1 - FONT_HEIGHT_SMALL) / 2, cargo->abbrev, TC_BLACK, SA_HOR_CENTER); + DrawString(r.left, r.right, (r.top + r.bottom + 1 - FONT_HEIGHT_SMALL) / 2, cargo->abbrev, GetContrastColour(cargo->legend_colour, 73), SA_HOR_CENTER); } } +bool LinkGraphLegendWindow::OnHoverCommon(Point pt, int widget, TooltipCloseCondition close_cond) +{ + if (IsInsideMM(widget, WID_LGL_COMPANY_FIRST, WID_LGL_COMPANY_LAST + 1)) { + if (this->IsWidgetDisabled(widget)) { + GuiShowTooltips(this, STR_LINKGRAPH_LEGEND_SELECT_COMPANIES, 0, NULL, close_cond); + } else { + uint64 params[2]; + CompanyID cid = (CompanyID)(widget - WID_LGL_COMPANY_FIRST); + params[0] = STR_LINKGRAPH_LEGEND_SELECT_COMPANIES; + params[1] = cid; + GuiShowTooltips(this, STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP, 2, params, close_cond); + } + return true; + } + if (IsInsideMM(widget, WID_LGL_CARGO_FIRST, WID_LGL_CARGO_LAST + 1)) { + if (this->IsWidgetDisabled(widget)) return false; + CargoSpec *cargo = CargoSpec::Get(widget - WID_LGL_CARGO_FIRST); + uint64 params[1]; + params[0] = cargo->name; + GuiShowTooltips(this, STR_BLACK_STRING, 1, params, close_cond); + return true; + } + return false; +} + +void LinkGraphLegendWindow::OnHover(Point pt, int widget) +{ + this->OnHoverCommon(pt, widget, TCC_HOVER); +} + +bool LinkGraphLegendWindow::OnRightClick(Point pt, int widget) +{ + if (_settings_client.gui.hover_delay_ms == 0) { + return this->OnHoverCommon(pt, widget, TCC_RIGHT_CLICK); + } + return false; +} + /** * Update the overlay with the new company selection. */ @@ -519,7 +557,7 @@ void LinkGraphLegendWindow::UpdateOverlayCompanies() */ void LinkGraphLegendWindow::UpdateOverlayCargoes() { - uint32 mask = 0; + CargoTypes mask = 0; for (uint c = 0; c < NUM_CARGO; c++) { if (this->IsWidgetDisabled(c + WID_LGL_CARGO_FIRST)) continue; if (!this->IsWidgetLowered(c + WID_LGL_CARGO_FIRST)) continue; diff --git a/src/linkgraph/linkgraph_gui.h b/src/linkgraph/linkgraph_gui.h index a9be8254d4..a933bfc683 100644 --- a/src/linkgraph/linkgraph_gui.h +++ b/src/linkgraph/linkgraph_gui.h @@ -15,6 +15,7 @@ #include "../company_func.h" #include "../station_base.h" #include "../widget_type.h" +#include "../window_gui.h" #include "linkgraph_base.h" #include #include @@ -51,17 +52,17 @@ public: * @param company_mask Bitmask of companies to be shown. * @param scale Desired thickness of lines and size of station dots. */ - LinkGraphOverlay(const Window *w, uint wid, uint32 cargo_mask, uint32 company_mask, uint scale) : + LinkGraphOverlay(const Window *w, uint wid, CargoTypes cargo_mask, uint32 company_mask, uint scale) : window(w), widget_id(wid), cargo_mask(cargo_mask), company_mask(company_mask), scale(scale) {} void RebuildCache(); void Draw(const DrawPixelInfo *dpi) const; - void SetCargoMask(uint32 cargo_mask); + void SetCargoMask(CargoTypes cargo_mask); void SetCompanyMask(uint32 company_mask); /** Get a bitmask of the currently shown cargoes. */ - uint32 GetCargoMask() { return this->cargo_mask; } + CargoTypes GetCargoMask() { return this->cargo_mask; } /** Get a bitmask of the currently shown companies. */ uint32 GetCompanyMask() { return this->company_mask; } @@ -69,7 +70,7 @@ public: protected: const Window *window; ///< Window to be drawn into. const uint widget_id; ///< ID of Widget in Window to be drawn to. - uint32 cargo_mask; ///< Bitmask of cargos to be displayed. + CargoTypes cargo_mask; ///< Bitmask of cargos to be displayed. uint32 company_mask; ///< Bitmask of companies to be displayed. LinkMap cached_links; ///< Cache for links to reduce recalculation. StationSupplyList cached_stations; ///< Cache for stations to be drawn. @@ -101,6 +102,8 @@ public: virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize); virtual void DrawWidget(const Rect &r, int widget) const; + virtual void OnHover(Point pt, int widget); + virtual bool OnRightClick(Point pt, int widget); virtual void OnClick(Point pt, int widget, int click_count); virtual void OnInvalidateData(int data = 0, bool gui_scope = true); @@ -109,6 +112,7 @@ private: void UpdateOverlayCompanies(); void UpdateOverlayCargoes(); + bool OnHoverCommon(Point pt, int widget, TooltipCloseCondition close_cond); }; #endif /* LINKGRAPH_GUI_H */ diff --git a/src/linkgraph/linkgraphschedule.cpp b/src/linkgraph/linkgraphschedule.cpp index a65783a5e7..8c508d8173 100644 --- a/src/linkgraph/linkgraphschedule.cpp +++ b/src/linkgraph/linkgraphschedule.cpp @@ -15,6 +15,7 @@ #include "demands.h" #include "mcf.h" #include "flowmapper.h" +#include "../framerate_type.h" #include "../safeguards.h" @@ -151,6 +152,7 @@ void OnTick_LinkGraph() if (offset == 0) { LinkGraphSchedule::instance.SpawnNext(); } else if (offset == _settings_game.linkgraph.recalc_interval / 2) { + PerformanceMeasurer framerate(PFE_GL_LINKGRAPH); LinkGraphSchedule::instance.JoinNext(); } } diff --git a/src/linkgraph/mcf.cpp b/src/linkgraph/mcf.cpp index ecdf792afe..544584ef61 100644 --- a/src/linkgraph/mcf.cpp +++ b/src/linkgraph/mcf.cpp @@ -193,7 +193,7 @@ public: * Determines if an extension to the given Path with the given parameters is * better than this path. * @param base Other path. - * @param cap Capacity of the new edge to be added to base. + * @param free_cap Capacity of the new edge to be added to base. * @param dist Distance of the new edge. * @return True if base + the new edge would be better than the path associated * with this annotation. @@ -227,7 +227,7 @@ bool DistanceAnnotation::IsBetter(const DistanceAnnotation *base, uint cap, * Determines if an extension to the given Path with the given parameters is * better than this path. * @param base Other path. - * @param cap Capacity of the new edge to be added to base. + * @param free_cap Capacity of the new edge to be added to base. * @param dist Distance of the new edge. * @return True if base + the new edge would be better than the path associated * with this annotation. diff --git a/src/main_gui.cpp b/src/main_gui.cpp index b13920a648..199546d439 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -439,7 +439,7 @@ struct MainWindow : Window virtual void OnMouseWheel(int wheel) { - if (_settings_client.gui.scrollwheel_scrolling == 0) { + if (_settings_client.gui.scrollwheel_scrolling != 2) { ZoomInOrOutToCursorWindow(wheel < 0, this); } } diff --git a/src/map.cpp b/src/map.cpp index 252f20b607..85590c3e88 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -87,7 +87,7 @@ TileIndex TileAdd(TileIndex tile, TileIndexDiff add, seprintf(buf, lastof(buf), "TILE_ADD(%s) when adding 0x%.4X and 0x%.4X failed", exp, tile, add); -#if !defined(_MSC_VER) || defined(WINCE) +#if !defined(_MSC_VER) fprintf(stderr, "%s:%d %s\n", file, line, buf); #else _assert(buf, (char*)file, line); @@ -269,7 +269,7 @@ bool CircularTileSearch(TileIndex *tile, uint size, TestTileOnSearchProc proc, v /* If tile test is not successful, get one tile up, * ready for a test in first circle around center tile */ - *tile = TILE_ADD(*tile, TileOffsByDir(DIR_N)); + *tile = TileAddByDir(*tile, DIR_N); return CircularTileSearch(tile, size / 2, 1, 1, proc, user_data); } else { return CircularTileSearch(tile, size / 2, 0, 0, proc, user_data); diff --git a/src/map_func.h b/src/map_func.h index 9198c2cd1f..21d69b1382 100644 --- a/src/map_func.h +++ b/src/map_func.h @@ -147,7 +147,7 @@ static inline uint ScaleByMapSize1D(uint n) * An offset value between to tiles. * * This value is used for the difference between - * to tiles. It can be added to a tileindex to get + * two tiles. It can be added to a tileindex to get * the resulting tileindex of the start tile applied * with this saved difference. * @@ -362,6 +362,18 @@ static inline TileIndexDiff TileOffsByDir(Direction dir) return ToTileIndexDiff(_tileoffs_by_dir[dir]); } +/** + * Adds a Direction to a tile. + * + * @param tile The current tile + * @param dir The direction in which we want to step + * @return the moved tile + */ +static inline TileIndex TileAddByDir(TileIndex tile, Direction dir) +{ + return TILE_ADD(tile, TileOffsByDir(dir)); +} + /** * Adds a DiagDir to a tile. * diff --git a/src/map_type.h b/src/map_type.h index 620885e5da..0c57d37700 100644 --- a/src/map_type.h +++ b/src/map_type.h @@ -33,8 +33,9 @@ assert_compile(sizeof(Tile) == 8); * Look at docs/landscape.html for the exact meaning of the members. */ struct TileExtended { - byte m6; ///< General purpose - byte m7; ///< Primarily used for newgrf support + byte m6; ///< General purpose + byte m7; ///< Primarily used for newgrf support + uint16 m8; ///< General purpose }; /** @@ -70,7 +71,7 @@ static const uint MAX_MAP_SIZE = 1 << MAX_MAP_SIZE_BITS; ///< Maximal map s * Approximation of the length of a straight track, relative to a diagonal * track (ie the size of a tile side). * - * #defined instead of const so it can + * \#defined instead of const so it can * stay integer. (no runtime float operations) Is this needed? * Watch out! There are _no_ brackets around here, to prevent intermediate * rounding! Be careful when using this! diff --git a/src/misc/dbg_helpers.cpp b/src/misc/dbg_helpers.cpp index a80230de1c..22ccfa3464 100644 --- a/src/misc/dbg_helpers.cpp +++ b/src/misc/dbg_helpers.cpp @@ -117,7 +117,7 @@ void DumpTarget::WriteIndent() } } -/** Write a line with indent at the beginning and at the end. */ +/** Write a line with indent at the beginning and \ at the end. */ void DumpTarget::WriteLine(const char *format, ...) { WriteIndent(); @@ -143,7 +143,7 @@ void DumpTarget::WriteTile(const char *name, TileIndex tile) } /** - * Open new structure (one level deeper than the current one) 'name = {'. + * Open new structure (one level deeper than the current one) 'name = {\'. */ void DumpTarget::BeginStruct(size_t type_id, const char *name, const void *ptr) { @@ -167,7 +167,7 @@ void DumpTarget::BeginStruct(size_t type_id, const char *name, const void *ptr) } /** - * Close structure '}'. + * Close structure '}\'. */ void DumpTarget::EndStruct() { diff --git a/src/misc/getoptdata.h b/src/misc/getoptdata.h index 5982f01fb8..4ce916aa1e 100644 --- a/src/misc/getoptdata.h +++ b/src/misc/getoptdata.h @@ -34,7 +34,7 @@ struct GetOptData { int numleft; ///< Number of arguments left in #argv. char **argv; ///< Remaining command line arguments. const OptionData *options; ///< Command line option descriptions. - char *cont; ///< Next call to #MyGetOpt should start here (in the middle of an argument). + char *cont; ///< Next call to #GetOpt should start here (in the middle of an argument). /** * Constructor of the data store. diff --git a/src/misc/hashtable.hpp b/src/misc/hashtable.hpp index 1afe58cac7..1078f1861d 100644 --- a/src/misc/hashtable.hpp +++ b/src/misc/hashtable.hpp @@ -161,12 +161,10 @@ protected: /** static helper - return hash for the given key modulo number of slots */ inline static int CalcHash(const Tkey &key) { - int32 hash = key.CalcHash(); - if ((8 * Thash_bits) < 32) hash ^= hash >> (min(8 * Thash_bits, 31)); - if ((4 * Thash_bits) < 32) hash ^= hash >> (min(4 * Thash_bits, 31)); - if ((2 * Thash_bits) < 32) hash ^= hash >> (min(2 * Thash_bits, 31)); - if ((1 * Thash_bits) < 32) hash ^= hash >> (min(1 * Thash_bits, 31)); - hash &= (1 << Thash_bits) - 1; + uint32 hash = key.CalcHash(); + hash -= (hash >> 17); // hash * 131071 / 131072 + hash -= (hash >> 5); // * 31 / 32 + hash &= (1 << Thash_bits) - 1; // modulo slots return hash; } diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 01e8d2c45d..b122d172d1 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -132,6 +132,7 @@ public: DEBUG(misc, LANDINFOD_LEVEL, "m5 = %#x", _m[tile].m5); DEBUG(misc, LANDINFOD_LEVEL, "m6 = %#x", _me[tile].m6); DEBUG(misc, LANDINFOD_LEVEL, "m7 = %#x", _me[tile].m7); + DEBUG(misc, LANDINFOD_LEVEL, "m8 = %#x", _me[tile].m8); #undef LANDINFOD_LEVEL } @@ -193,11 +194,8 @@ public: StringID str = STR_LAND_AREA_INFORMATION_COST_TO_CLEAR_N_A; Company *c = Company::GetIfValid(_local_company); if (c != NULL) { - Money old_money = c->money; - c->money = INT64_MAX; assert(_current_company == _local_company); - CommandCost costclear = DoCommand(tile, 0, 0, DC_NONE, CMD_LANDSCAPE_CLEAR); - c->money = old_money; + CommandCost costclear = DoCommand(tile, 0, 0, DC_QUERY_COST, CMD_LANDSCAPE_CLEAR); if (costclear.Succeeded()) { Money cost = costclear.GetCost(); if (cost < 0) { @@ -313,10 +311,7 @@ public: for (CargoID i = 0; i < NUM_CARGO; ++i) { if (acceptance[i] > 0) { /* Add a comma between each item. */ - if (found) { - *strp++ = ','; - *strp++ = ' '; - } + if (found) strp = strecpy(strp, ", ", lastof(this->landinfo_data[LAND_INFO_MULTICENTER_LINE])); found = true; /* If the accepted value is less than 8, show it in 1/8:ths */ @@ -404,6 +399,7 @@ static const char * const _credits[] = { " Christoph Elsenhans (frosch) - General coding (since 0.6)", " Lo\xC3\xAF""c Guilloux (glx) - General / Windows Expert (since 0.4.5)", " Michael Lutz (michi_cc) - Path based signals (since 0.7)", + " Niels Martin Hansen (nielsm) - Music system, general coding (since 1.9)", " Owen Rudge (orudge) - Forum host, OS/2 port (since 0.1)", " Peter Nelson (peter1138) - Spiritual descendant from NewGRF gods (since 0.4.5)", " Ingo von Borstel (planetmaker) - General, Support (since 1.1)", @@ -659,7 +655,7 @@ struct TooltipsWindow : public Window this->string_id = str; assert_compile(sizeof(this->params[0]) == sizeof(params[0])); assert(paramcount <= lengthof(this->params)); - memcpy(this->params, params, sizeof(this->params[0]) * paramcount); + if (paramcount > 0) memcpy(this->params, params, sizeof(this->params[0]) * paramcount); this->paramcount = paramcount; this->close_cond = close_tooltip; @@ -737,7 +733,7 @@ struct TooltipsWindow : public Window * @param str String to be displayed * @param paramcount number of params to deal with * @param params (optional) up to 5 pieces of additional information that may be added to a tooltip - * @param use_left_mouse_button close the tooltip when the left (true) or right (false) mouse button is released + * @param close_tooltip when the left (true) or right (false) mouse button is released */ void GuiShowTooltips(Window *parent, StringID str, uint paramcount, const uint64 params[], TooltipCloseCondition close_tooltip) { @@ -1073,7 +1069,7 @@ void ShowQueryString(StringID str, StringID caption, uint maxsize, Window *paren */ struct QueryWindow : public Window { QueryCallbackProc *proc; ///< callback function executed on closing of popup. Window* points to parent, bool is true if 'yes' clicked, false otherwise - uint64 params[10]; ///< local copy of _decode_parameters + uint64 params[10]; ///< local copy of #_global_string_params StringID message; ///< message shown for query window StringID caption; ///< title of window diff --git a/src/mixer.cpp b/src/mixer.cpp index 5945bd235a..6014f6082e 100644 --- a/src/mixer.cpp +++ b/src/mixer.cpp @@ -12,8 +12,10 @@ #include "stdafx.h" #include #include "core/math_func.hpp" +#include "framerate_type.h" #include "safeguards.h" +#include "mixer.h" struct MixerChannel { bool active; @@ -37,6 +39,7 @@ struct MixerChannel { static MixerChannel _channels[8]; static uint32 _play_rate = 11025; static uint32 _max_size = UINT_MAX; +static MxStreamCallback _music_stream = NULL; /** * The theoretical maximum volume for a single sound sample. Multiple sound @@ -138,11 +141,21 @@ static void MxCloseChannel(MixerChannel *mc) void MxMixSamples(void *buffer, uint samples) { + PerformanceMeasurer framerate(PFE_SOUND); + static uint last_samples = 0; + if (samples != last_samples) { + framerate.SetExpectedRate((double)_play_rate / samples); + last_samples = samples; + } + MixerChannel *mc; /* Clear the buffer */ memset(buffer, 0, sizeof(int16) * 2 * samples); + /* Fetch music if a sampled stream is available */ + if (_music_stream) _music_stream((int16*)buffer, samples); + /* Mix each channel */ for (mc = _channels; mc != endof(_channels); mc++) { if (mc->active) { @@ -207,6 +220,17 @@ void MxSetChannelVolume(MixerChannel *mc, uint volume, float pan) void MxActivateChannel(MixerChannel *mc) { mc->active = true; +} + +/** + * Set source of PCM music + * @param music_callback Function that will be called to fill sample buffers with music data. + * @return Sample rate of mixer, which the buffers supplied to the callback must be rendered at. + */ +uint32 MxSetMusicSource(MxStreamCallback music_callback) +{ + _music_stream = music_callback; + return _play_rate; } @@ -214,5 +238,6 @@ bool MxInitialize(uint rate) { _play_rate = rate; _max_size = UINT_MAX / _play_rate; + _music_stream = NULL; /* rate may have changed, any music source is now invalid */ return true; } diff --git a/src/mixer.h b/src/mixer.h index 0ccee61092..9766682d6b 100644 --- a/src/mixer.h +++ b/src/mixer.h @@ -14,6 +14,14 @@ struct MixerChannel; +/** + * Type of callback functions for supplying PCM music. + * A music decoder/renderer implements this function and installs it with MxSetMusicSource, which also returns the sample rate used. + * @param buffer Pointer to interleaved 2-channel signed 16 bit PCM data buffer, guaranteed to be 0-initialized. + * @param samples number of samples that must be filled into \c buffer. + */ +typedef void(*MxStreamCallback)(int16 *buffer, size_t samples); + bool MxInitialize(uint rate); void MxMixSamples(void *buffer, uint samples); @@ -22,4 +30,6 @@ void MxSetChannelRawSrc(MixerChannel *mc, int8 *mem, size_t size, uint rate, boo void MxSetChannelVolume(MixerChannel *mc, uint volume, float pan); void MxActivateChannel(MixerChannel*); +uint32 MxSetMusicSource(MxStreamCallback music_callback); + #endif /* MIXER_H */ diff --git a/src/music.cpp b/src/music.cpp index 4001e621e1..3d0e40bf9b 100644 --- a/src/music.cpp +++ b/src/music.cpp @@ -11,11 +11,69 @@ #include "stdafx.h" + /** The type of set we're replacing */ #define SET_TYPE "music" #include "base_media_func.h" #include "safeguards.h" +#include "fios.h" + + +/** + * Read the name of a music CAT file entry. + * @param filename Name of CAT file to read from + * @param entrynum Index of entry whose name to read + * @return Pointer to string, caller is responsible for freeing memory, + * NULL if entrynum does not exist. + */ +char *GetMusicCatEntryName(const char *filename, size_t entrynum) +{ + if (!FioCheckFileExists(filename, BASESET_DIR)) return NULL; + + FioOpenFile(CONFIG_SLOT, filename, BASESET_DIR); + uint32 ofs = FioReadDword(); + size_t entry_count = ofs / 8; + if (entrynum < entry_count) { + FioSeekTo(entrynum * 8, SEEK_SET); + FioSeekTo(FioReadDword(), SEEK_SET); + byte namelen = FioReadByte(); + char *name = MallocT(namelen + 1); + FioReadBlock(name, namelen); + name[namelen] = '\0'; + return name; + } + return NULL; +} + +/** + * Read the full data of a music CAT file entry. + * @param filename Name of CAT file to read from. + * @param entrynum Index of entry to read + * @param[out] entrylen Receives length of data read + * @return Pointer to buffer with data read, caller is responsible for freeind memory, + * NULL if entrynum does not exist. + */ +byte *GetMusicCatEntryData(const char *filename, size_t entrynum, size_t &entrylen) +{ + entrylen = 0; + if (!FioCheckFileExists(filename, BASESET_DIR)) return NULL; + + FioOpenFile(CONFIG_SLOT, filename, BASESET_DIR); + uint32 ofs = FioReadDword(); + size_t entry_count = ofs / 8; + if (entrynum < entry_count) { + FioSeekTo(entrynum * 8, SEEK_SET); + size_t entrypos = FioReadDword(); + entrylen = FioReadDword(); + FioSeekTo(entrypos, SEEK_SET); + FioSkipBytes(FioReadByte()); + byte *data = MallocT(entrylen); + FioReadBlock(data, entrylen); + return data; + } + return NULL; +} INSTANTIATE_BASE_MEDIA_METHODS(BaseMedia, MusicSet) @@ -66,34 +124,73 @@ bool MusicSet::FillSetDetails(IniFile *ini, const char *path, const char *full_f if (ret) { this->num_available = 0; IniGroup *names = ini->GetGroup("names"); - for (uint i = 0, j = 1; i < lengthof(this->song_name); i++) { + IniGroup *catindex = ini->GetGroup("catindex"); + IniGroup *timingtrim = ini->GetGroup("timingtrim"); + uint tracknr = 1; + for (uint i = 0; i < lengthof(this->songinfo); i++) { const char *filename = this->files[i].filename; - if (names == NULL || StrEmpty(filename)) { - this->song_name[i][0] = '\0'; + if (names == NULL || StrEmpty(filename) || this->files[i].check_result == MD5File::CR_NO_FILE) { + this->songinfo[i].songname[0] = '\0'; continue; } - IniItem *item = NULL; + this->songinfo[i].filename = filename; // non-owned pointer + + IniItem *item = catindex->GetItem(_music_file_names[i], false); + if (item != NULL && !StrEmpty(item->value)) { + /* Song has a CAT file index, assume it's MPS MIDI format */ + this->songinfo[i].filetype = MTT_MPSMIDI; + this->songinfo[i].cat_index = atoi(item->value); + char *songname = GetMusicCatEntryName(filename, this->songinfo[i].cat_index); + if (songname == NULL) { + DEBUG(grf, 0, "Base music set song missing from CAT file: %s/%d", filename, this->songinfo[i].cat_index); + this->songinfo[i].songname[0] = '\0'; + continue; + } + strecpy(this->songinfo[i].songname, songname, lastof(this->songinfo[i].songname)); + free(songname); + } else { + this->songinfo[i].filetype = MTT_STANDARDMIDI; + } + + const char *trimmed_filename = filename; /* As we possibly add a path to the filename and we compare * on the filename with the path as in the .obm, we need to * keep stripping path elements until we find a match. */ - for (const char *p = filename; p != NULL; p = strchr(p, PATHSEPCHAR)) { + for (; trimmed_filename != NULL; trimmed_filename = strchr(trimmed_filename, PATHSEPCHAR)) { /* Remove possible double path separator characters from * the beginning, so we don't start reading e.g. root. */ - while (*p == PATHSEPCHAR) p++; + while (*trimmed_filename == PATHSEPCHAR) trimmed_filename++; - item = names->GetItem(p, false); + item = names->GetItem(trimmed_filename, false); if (item != NULL && !StrEmpty(item->value)) break; } - if (item == NULL || StrEmpty(item->value)) { - DEBUG(grf, 0, "Base music set song name missing: %s", filename); - return false; + if (this->songinfo[i].filetype == MTT_STANDARDMIDI) { + if (item != NULL && !StrEmpty(item->value)) { + strecpy(this->songinfo[i].songname, item->value, lastof(this->songinfo[i].songname)); + } else { + DEBUG(grf, 0, "Base music set song name missing: %s", filename); + return false; + } + } + this->num_available++; + + /* Number the theme song (if any) track 0, rest are normal */ + if (i == 0) { + this->songinfo[i].tracknr = 0; + } else { + this->songinfo[i].tracknr = tracknr++; } - strecpy(this->song_name[i], item->value, lastof(this->song_name[i])); - this->track_nr[i] = j++; - this->num_available++; + item = timingtrim->GetItem(trimmed_filename, false); + if (item != NULL && !StrEmpty(item->value)) { + const char *endpos = strchr(item->value, ':'); + if (endpos != NULL) { + this->songinfo[i].override_start = atoi(item->value); + this->songinfo[i].override_end = atoi(endpos + 1); + } + } } } return ret; diff --git a/src/music/allegro_m.cpp b/src/music/allegro_m.cpp index 77b488186a..906aec84fc 100644 --- a/src/music/allegro_m.cpp +++ b/src/music/allegro_m.cpp @@ -14,6 +14,7 @@ #include "../stdafx.h" #include "../debug.h" #include "allegro_m.h" +#include "midifile.hpp" #include #include "../safeguards.h" @@ -58,11 +59,17 @@ void MusicDriver_Allegro::Stop() if (--_allegro_instance_count == 0) allegro_exit(); } -void MusicDriver_Allegro::PlaySong(const char *filename) +void MusicDriver_Allegro::PlaySong(const MusicSongInfo &song) { + std::string filename = MidiFile::GetSMFFile(song); + if (_midi != NULL) destroy_midi(_midi); - _midi = load_midi(filename); - play_midi(_midi, false); + if (!filename.empty()) { + _midi = load_midi(filename.c_str()); + play_midi(_midi, false); + } else { + _midi = NULL; + } } void MusicDriver_Allegro::StopSong() diff --git a/src/music/allegro_m.h b/src/music/allegro_m.h index 69cf59569a..65d8ab811d 100644 --- a/src/music/allegro_m.h +++ b/src/music/allegro_m.h @@ -21,7 +21,7 @@ public: /* virtual */ void Stop(); - /* virtual */ void PlaySong(const char *filename); + /* virtual */ void PlaySong(const MusicSongInfo &song); /* virtual */ void StopSong(); diff --git a/src/music/bemidi.cpp b/src/music/bemidi.cpp index 2bc2074763..ff56d787f1 100644 --- a/src/music/bemidi.cpp +++ b/src/music/bemidi.cpp @@ -12,6 +12,8 @@ #include "../stdafx.h" #include "../openttd.h" #include "bemidi.h" +#include "../base_media_base.h" +#include "midifile.hpp" /* BeOS System Includes */ #include @@ -34,13 +36,17 @@ void MusicDriver_BeMidi::Stop() midiSynthFile.UnloadFile(); } -void MusicDriver_BeMidi::PlaySong(const char *filename) +void MusicDriver_BeMidi::PlaySong(const MusicSongInfo &song) { + std::string filename = MidiFile::GetSMFFile(song); + this->Stop(); - entry_ref midiRef; - get_ref_for_path(filename, &midiRef); - midiSynthFile.LoadFile(&midiRef); - midiSynthFile.Start(); + if (!filename.empty()) { + entry_ref midiRef; + get_ref_for_path(filename.c_str(), &midiRef); + midiSynthFile.LoadFile(&midiRef); + midiSynthFile.Start(); + } } void MusicDriver_BeMidi::StopSong() diff --git a/src/music/bemidi.h b/src/music/bemidi.h index 23c6249d59..7c546525d2 100644 --- a/src/music/bemidi.h +++ b/src/music/bemidi.h @@ -21,7 +21,7 @@ public: /* virtual */ void Stop(); - /* virtual */ void PlaySong(const char *filename); + /* virtual */ void PlaySong(const MusicSongInfo &song); /* virtual */ void StopSong(); diff --git a/src/music/cocoa_m.cpp b/src/music/cocoa_m.cpp index 925dc21ab5..2416cade0f 100644 --- a/src/music/cocoa_m.cpp +++ b/src/music/cocoa_m.cpp @@ -18,15 +18,13 @@ #include "../stdafx.h" #include "../os/macosx/macos.h" #include "cocoa_m.h" +#include "midifile.hpp" #include "../debug.h" +#include "../base_media_base.h" -#define Rect OTTDRect -#define Point OTTDPoint #include #include #include -#undef Rect -#undef Point #include "../safeguards.h" @@ -141,11 +139,13 @@ void MusicDriver_Cocoa::Stop() /** * Starts playing a new song. * - * @param filename Path to a MIDI file. + * @param song Description of music to load and play */ -void MusicDriver_Cocoa::PlaySong(const char *filename) +void MusicDriver_Cocoa::PlaySong(const MusicSongInfo &song) { - DEBUG(driver, 2, "cocoa_m: trying to play '%s'", filename); + std::string filename = MidiFile::GetSMFFile(song); + + DEBUG(driver, 2, "cocoa_m: trying to play '%s'", filename.c_str()); this->StopSong(); if (_sequence != NULL) { @@ -153,12 +153,14 @@ void MusicDriver_Cocoa::PlaySong(const char *filename) _sequence = NULL; } + if (filename.empty()) return; + if (NewMusicSequence(&_sequence) != noErr) { DEBUG(driver, 0, "cocoa_m: Failed to create music sequence"); return; } - const char *os_file = OTTD2FS(filename); + const char *os_file = OTTD2FS(filename.c_str()); CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8*)os_file, strlen(os_file), false); #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) @@ -218,7 +220,7 @@ void MusicDriver_Cocoa::PlaySong(const char *filename) if (MusicPlayerStart(_player) != noErr) return; _playing = true; - DEBUG(driver, 3, "cocoa_m: playing '%s'", filename); + DEBUG(driver, 3, "cocoa_m: playing '%s'", filename.c_str()); } diff --git a/src/music/cocoa_m.h b/src/music/cocoa_m.h index 1963bef5b7..fdb10b84e6 100644 --- a/src/music/cocoa_m.h +++ b/src/music/cocoa_m.h @@ -20,7 +20,7 @@ public: /* virtual */ void Stop(); - /* virtual */ void PlaySong(const char *filename); + /* virtual */ void PlaySong(const MusicSongInfo &song); /* virtual */ void StopSong(); diff --git a/src/music/dmusic.cpp b/src/music/dmusic.cpp index 471fb3f366..fece709fda 100644 --- a/src/music/dmusic.cpp +++ b/src/music/dmusic.cpp @@ -19,86 +19,1099 @@ #include "../debug.h" #include "../os/windows/win32.h" #include "../core/mem_func.hpp" +#include "../thread/thread.h" +#include "../fileio_func.h" +#include "../base_media_base.h" #include "dmusic.h" +#include "midifile.hpp" +#include "midi.h" #include -#undef FACILITY_DIRECTMUSIC // Needed for newer Windows SDK version. #include -#include #include -#include +#include #include "../safeguards.h" -static FMusicDriver_DMusic iFMusicDriver_DMusic; +#if defined(_MSC_VER) +# pragma comment(lib, "ole32.lib") +#endif /* defined(_MSC_VER) */ -/** the direct music object manages buffers and ports */ -static IDirectMusic *music = NULL; - -/** the performance object controls manipulation of the segments */ -static IDirectMusicPerformance *performance = NULL; - -/** the loader object can load many types of DMusic related files */ -static IDirectMusicLoader *loader = NULL; - -/** the segment object is where the MIDI data is stored for playback */ -static IDirectMusicSegment *segment = NULL; - -static bool seeking = false; +static const int MS_TO_REFTIME = 1000 * 10; ///< DirectMusic time base is 100 ns. +static const int MIDITIME_TO_REFTIME = 10; ///< Time base of the midi file reader is 1 us. -#define M(x) x "\0" -static const char ole_files[] = - M("ole32.dll") - M("CoCreateInstance") - M("CoInitialize") - M("CoUninitialize") - M("") -; -#undef M +#define FOURCC_INFO mmioFOURCC('I','N','F','O') +#define FOURCC_fmt mmioFOURCC('f','m','t',' ') +#define FOURCC_data mmioFOURCC('d','a','t','a') -struct ProcPtrs { - unsigned long (WINAPI * CoCreateInstance)(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv); - HRESULT (WINAPI * CoInitialize)(LPVOID pvReserved); - void (WINAPI * CoUninitialize)(); +/** A DLS file. */ +struct DLSFile { + /** An instrument region maps a note range to wave data. */ + struct DLSRegion { + RGNHEADER hdr; + WAVELINK wave; + WSMPL wave_sample; + + std::vector wave_loops; + std::vector articulators; + }; + + /** Instrument definition read from a DLS file. */ + struct DLSInstrument { + INSTHEADER hdr; + + std::vector articulators; + std::vector regions; + }; + + /** Wave data definition from a DLS file. */ + struct DLSWave { + long file_offset; + + PCMWAVEFORMAT fmt; + std::vector data; + + WSMPL wave_sample; + std::vector wave_loops; + + bool operator ==(long offset) const { + return this->file_offset == offset; + } + }; + + std::vector instruments; + std::vector pool_cues; + std::vector waves; + + /** Try loading a DLS file into memory. */ + bool LoadFile(const TCHAR *file); + +private: + /** Load an articulation structure from a DLS file. */ + bool ReadDLSArticulation(FILE *f, DWORD list_length, std::vector &out); + /** Load a list of regions from a DLS file. */ + bool ReadDLSRegionList(FILE *f, DWORD list_length, DLSInstrument &instrument); + /** Load a single region from a DLS file. */ + bool ReadDLSRegion(FILE *f, DWORD list_length, std::vector &out); + /** Load a list of instruments from a DLS file. */ + bool ReadDLSInstrumentList(FILE *f, DWORD list_length); + /** Load a single instrument from a DLS file. */ + bool ReadDLSInstrument(FILE *f, DWORD list_length); + /** Load a list of waves from a DLS file. */ + bool ReadDLSWaveList(FILE *f, DWORD list_length); + /** Load a single wave from a DLS file. */ + bool ReadDLSWave(FILE *f, DWORD list_length, long offset); }; -static ProcPtrs proc; +/** A RIFF chunk header. */ +PACK_N(struct ChunkHeader { + FOURCC type; ///< Chunk type. + DWORD length; ///< Length of the chunk, not including the chunk header itself. +}, 2); + +/** Buffer format for a DLS wave download. */ +PACK_N(struct WAVE_DOWNLOAD { + DMUS_DOWNLOADINFO dlInfo; + ULONG ulOffsetTable[2]; + DMUS_WAVE dmWave; + DMUS_WAVEDATA dmWaveData; +}, 2); + +struct PlaybackSegment { + uint32 start, end; + size_t start_block; + bool loop; +}; + +static struct { + bool shutdown; ///< flag to indicate playback thread shutdown + bool playing; ///< flag indicating that playback is active + bool do_start; ///< flag for starting playback of next_file at next opportunity + bool do_stop; ///< flag for stopping playback at next opportunity + + int preload_time; ///< preload time for music blocks. + byte new_volume; ///< volume setting to change to + + MidiFile next_file; ///< upcoming file to play + PlaybackSegment next_segment; ///< segment info for upcoming file +} _playback; + +/** Handle to our worker thread. */ +static ThreadObject *_dmusic_thread = NULL; +/** Event to signal the thread that it should look at a state change. */ +static HANDLE _thread_event = NULL; +/** Lock access to playback data that is not thread-safe. */ +static ThreadMutex *_thread_mutex = NULL; + +/** The direct music object manages buffers and ports. */ +static IDirectMusic *_music = NULL; +/** The port object lets us send MIDI data to the synthesizer. */ +static IDirectMusicPort *_port = NULL; +/** The buffer object collects the data to sent. */ +static IDirectMusicBuffer *_buffer = NULL; +/** List of downloaded DLS instruments. */ +static std::vector _dls_downloads; + + +static FMusicDriver_DMusic iFMusicDriver_DMusic; + + +bool DLSFile::ReadDLSArticulation(FILE *f, DWORD list_length, std::vector &out) +{ + while (list_length > 0) { + ChunkHeader chunk; + if (fread(&chunk, sizeof(chunk), 1, f) != 1) return false; + list_length -= chunk.length + sizeof(chunk); + + if (chunk.type == FOURCC_ART1) { + CONNECTIONLIST conns; + if (fread(&conns, sizeof(conns), 1, f) != 1) return false; + fseek(f, conns.cbSize - sizeof(conns), SEEK_CUR); + + /* Read all defined articulations. */ + for (ULONG i = 0; i < conns.cConnections; i++) { + CONNECTION con; + if (fread(&con, sizeof(con), 1, f) != 1) return false; + out.push_back(con); + } + } else { + fseek(f, chunk.length, SEEK_CUR); + } + } + + return true; +} + +bool DLSFile::ReadDLSRegion(FILE *f, DWORD list_length, std::vector &out) +{ + out.push_back(DLSRegion()); + DLSRegion ®ion = out.back(); + + /* Set default values. */ + region.wave_sample.cbSize = 0; + + while (list_length > 0) { + ChunkHeader chunk; + if (fread(&chunk, sizeof(chunk), 1, f) != 1) return false; + list_length -= chunk.length + sizeof(chunk); + + if (chunk.type == FOURCC_LIST) { + /* Unwrap list header. */ + if (fread(&chunk.type, sizeof(chunk.type), 1, f) != 1) return false; + chunk.length -= sizeof(chunk.type); + } + + switch (chunk.type) { + case FOURCC_RGNH: + if (fread(®ion.hdr, sizeof(region.hdr), 1, f) != 1) return false; + break; + + case FOURCC_WSMP: + if (fread(®ion.wave_sample, sizeof(region.wave_sample), 1, f) != 1) return false; + fseek(f, region.wave_sample.cbSize - sizeof(region.wave_sample), SEEK_CUR); + + /* Read all defined sample loops. */ + for (ULONG i = 0; i < region.wave_sample.cSampleLoops; i++) { + WLOOP loop; + if (fread(&loop, sizeof(loop), 1, f) != 1) return false; + region.wave_loops.push_back(loop); + } + break; + + case FOURCC_WLNK: + if (fread(®ion.wave, sizeof(region.wave), 1, f) != 1) return false; + break; + + case FOURCC_LART: // List chunk + if (!this->ReadDLSArticulation(f, chunk.length, region.articulators)) return false; + break; + + case FOURCC_INFO: + /* We don't care about info stuff. */ + fseek(f, chunk.length, SEEK_CUR); + break; + + default: + DEBUG(driver, 7, "DLS: Ignoring unkown chunk %c%c%c%c", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF)); + fseek(f, chunk.length, SEEK_CUR); + break; + } + } + + return true; +} + +bool DLSFile::ReadDLSRegionList(FILE *f, DWORD list_length, DLSInstrument &instrument) +{ + while (list_length > 0) { + ChunkHeader chunk; + if (fread(&chunk, sizeof(chunk), 1, f) != 1) return false; + list_length -= chunk.length + sizeof(chunk); + + if (chunk.type == FOURCC_LIST) { + FOURCC list_type; + if (fread(&list_type, sizeof(list_type), 1, f) != 1) return false; + + if (list_type == FOURCC_RGN) { + this->ReadDLSRegion(f, chunk.length - sizeof(list_type), instrument.regions); + } else { + DEBUG(driver, 7, "DLS: Ignoring unkown list chunk of type %c%c%c%c", (char)(list_type & 0xFF), (char)((list_type >> 8) & 0xFF), (char)((list_type >> 16) & 0xFF), (char)((list_type >> 24) & 0xFF)); + fseek(f, chunk.length - sizeof(list_type), SEEK_CUR); + } + } else { + DEBUG(driver, 7, "DLS: Ignoring chunk %c%c%c%c", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF)); + fseek(f, chunk.length, SEEK_CUR); + } + } + + return true; +} + +bool DLSFile::ReadDLSInstrument(FILE *f, DWORD list_length) +{ + this->instruments.push_back(DLSInstrument()); + DLSInstrument &instrument = this->instruments.back(); + + while (list_length > 0) { + ChunkHeader chunk; + if (fread(&chunk, sizeof(chunk), 1, f) != 1) return false; + list_length -= chunk.length + sizeof(chunk); + + if (chunk.type == FOURCC_LIST) { + /* Unwrap list header. */ + if (fread(&chunk.type, sizeof(chunk.type), 1, f) != 1) return false; + chunk.length -= sizeof(chunk.type); + } + + switch (chunk.type) { + case FOURCC_INSH: + if (fread(&instrument.hdr, sizeof(instrument.hdr), 1, f) != 1) return false; + break; + + case FOURCC_LART: // List chunk + if (!this->ReadDLSArticulation(f, chunk.length, instrument.articulators)) return false; + break; + + case FOURCC_LRGN: // List chunk + if (!this->ReadDLSRegionList(f, chunk.length, instrument)) return false; + break; + + case FOURCC_INFO: + /* We don't care about info stuff. */ + fseek(f, chunk.length, SEEK_CUR); + break; + + default: + DEBUG(driver, 7, "DLS: Ignoring unkown chunk %c%c%c%c", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF)); + fseek(f, chunk.length, SEEK_CUR); + break; + } + } + + return true; +} + +bool DLSFile::ReadDLSInstrumentList(FILE *f, DWORD list_length) +{ + while (list_length > 0) { + ChunkHeader chunk; + if (fread(&chunk, sizeof(chunk), 1, f) != 1) return false; + list_length -= chunk.length + sizeof(chunk); + + if (chunk.type == FOURCC_LIST) { + FOURCC list_type; + if (fread(&list_type, sizeof(list_type), 1, f) != 1) return false; + + if (list_type == FOURCC_INS) { + DEBUG(driver, 6, "DLS: Reading instrument %d", (int)instruments.size()); + + if (!this->ReadDLSInstrument(f, chunk.length - sizeof(list_type))) return false; + } else { + DEBUG(driver, 7, "DLS: Ignoring unkown list chunk of type %c%c%c%c", (char)(list_type & 0xFF), (char)((list_type >> 8) & 0xFF), (char)((list_type >> 16) & 0xFF), (char)((list_type >> 24) & 0xFF)); + fseek(f, chunk.length - sizeof(list_type), SEEK_CUR); + } + } else { + DEBUG(driver, 7, "DLS: Ignoring chunk %c%c%c%c", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF)); + fseek(f, chunk.length, SEEK_CUR); + } + } + + return true; +} + +bool DLSFile::ReadDLSWave(FILE *f, DWORD list_length, long offset) +{ + this->waves.push_back(DLSWave()); + DLSWave &wave = this->waves.back(); + + /* Set default values. */ + MemSetT(&wave.wave_sample, 0); + wave.wave_sample.cbSize = sizeof(WSMPL); + wave.wave_sample.usUnityNote = 60; + wave.file_offset = offset; // Store file offset so we can resolve the wave pool table later on. + + while (list_length > 0) { + ChunkHeader chunk; + if (fread(&chunk, sizeof(chunk), 1, f) != 1) return false; + list_length -= chunk.length + sizeof(chunk); + + if (chunk.type == FOURCC_LIST) { + /* Unwrap list header. */ + if (fread(&chunk.type, sizeof(chunk.type), 1, f) != 1) return false; + chunk.length -= sizeof(chunk.type); + } + + switch (chunk.type) { + case FOURCC_fmt: + if (fread(&wave.fmt, sizeof(wave.fmt), 1, f) != 1) return false; + if (chunk.length > sizeof(wave.fmt)) fseek(f, chunk.length - sizeof(wave.fmt), SEEK_CUR); + break; + + case FOURCC_WSMP: + if (fread(&wave.wave_sample, sizeof(wave.wave_sample), 1, f) != 1) return false; + fseek(f, wave.wave_sample.cbSize - sizeof(wave.wave_sample), SEEK_CUR); + + /* Read all defined sample loops. */ + for (ULONG i = 0; i < wave.wave_sample.cSampleLoops; i++) { + WLOOP loop; + if (fread(&loop, sizeof(loop), 1, f) != 1) return false; + wave.wave_loops.push_back(loop); + } + break; + + case FOURCC_data: + wave.data.resize(chunk.length); + if (fread(&wave.data[0], sizeof(BYTE), wave.data.size(), f) != wave.data.size()) return false; + break; + + case FOURCC_INFO: + /* We don't care about info stuff. */ + fseek(f, chunk.length, SEEK_CUR); + break; + + default: + DEBUG(driver, 7, "DLS: Ignoring unkown chunk %c%c%c%c", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF)); + fseek(f, chunk.length, SEEK_CUR); + break; + } + } + + return true; +} + +bool DLSFile::ReadDLSWaveList(FILE *f, DWORD list_length) +{ + long base_offset = ftell(f); + + while (list_length > 0) { + long chunk_offset = ftell(f); + + ChunkHeader chunk; + if (fread(&chunk, sizeof(chunk), 1, f) != 1) return false; + list_length -= chunk.length + sizeof(chunk); + + if (chunk.type == FOURCC_LIST) { + FOURCC list_type; + if (fread(&list_type, sizeof(list_type), 1, f) != 1) return false; + + if (list_type == FOURCC_wave) { + DEBUG(driver, 6, "DLS: Reading wave %d", (int)waves.size()); + + if (!this->ReadDLSWave(f, chunk.length - sizeof(list_type), chunk_offset - base_offset)) return false; + } else { + DEBUG(driver, 7, "DLS: Ignoring unkown list chunk of type %c%c%c%c", (char)(list_type & 0xFF), (char)((list_type >> 8) & 0xFF), (char)((list_type >> 16) & 0xFF), (char)((list_type >> 24) & 0xFF)); + fseek(f, chunk.length - sizeof(list_type), SEEK_CUR); + } + } else { + DEBUG(driver, 7, "DLS: Ignoring chunk %c%c%c%c", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF)); + fseek(f, chunk.length, SEEK_CUR); + } + } + + return true; +} + +bool DLSFile::LoadFile(const TCHAR *file) +{ + DEBUG(driver, 2, "DMusic: Try to load DLS file %s", FS2OTTD(file)); + + FILE *f = _tfopen(file, _T("rb")); + if (f == NULL) return false; + + FileCloser f_scope(f); + + /* Check DLS file header. */ + ChunkHeader hdr; + FOURCC dls_type; + if (fread(&hdr, sizeof(hdr), 1, f) != 1) return false; + if (fread(&dls_type, sizeof(dls_type), 1, f) != 1) return false; + if (hdr.type != FOURCC_RIFF || dls_type != FOURCC_DLS) return false; + + hdr.length -= sizeof(FOURCC); + + DEBUG(driver, 2, "DMusic: Parsing DLS file"); + + DLSHEADER header; + MemSetT(&header, 0); + + /* Iterate over all chunks in the file. */ + while (hdr.length > 0) { + ChunkHeader chunk; + if (fread(&chunk, sizeof(chunk), 1, f) != 1) return false; + hdr.length -= chunk.length + sizeof(chunk); + + if (chunk.type == FOURCC_LIST) { + /* Unwrap list header. */ + if (fread(&chunk.type, sizeof(chunk.type), 1, f) != 1) return false; + chunk.length -= sizeof(chunk.type); + } + + switch (chunk.type) { + case FOURCC_COLH: + if (fread(&header, sizeof(header), 1, f) != 1) return false; + break; + + case FOURCC_LINS: // List chunk + if (!this->ReadDLSInstrumentList(f, chunk.length)) return false; + break; + + case FOURCC_WVPL: // List chunk + if (!this->ReadDLSWaveList(f, chunk.length)) return false; + break; + + case FOURCC_PTBL: + POOLTABLE ptbl; + if (fread(&ptbl, sizeof(ptbl), 1, f) != 1) return false; + fseek(f, ptbl.cbSize - sizeof(ptbl), SEEK_CUR); + + /* Read all defined cues. */ + for (ULONG i = 0; i < ptbl.cCues; i++) { + POOLCUE cue; + if (fread(&cue, sizeof(cue), 1, f) != 1) return false; + this->pool_cues.push_back(cue); + } + break; + + case FOURCC_INFO: + /* We don't care about info stuff. */ + fseek(f, chunk.length, SEEK_CUR); + break; + + default: + DEBUG(driver, 7, "DLS: Ignoring unkown chunk %c%c%c%c", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF)); + fseek(f, chunk.length, SEEK_CUR); + break; + } + } + + /* Have we read as many instruments as indicated? */ + if (header.cInstruments != this->instruments.size()) return false; + + /* Resolve wave pool table. */ + for (std::vector::iterator cue = this->pool_cues.begin(); cue != this->pool_cues.end(); cue++) { + std::vector::iterator w = std::find(this->waves.begin(), this->waves.end(), cue->ulOffset); + if (w != this->waves.end()) { + cue->ulOffset = (ULONG)(w - this->waves.begin()); + } else { + cue->ulOffset = 0; + } + } + + return true; +} + + +static byte ScaleVolume(byte original, byte scale) +{ + return original * scale / 127; +} + +static void TransmitChannelMsg(IDirectMusicBuffer *buffer, REFERENCE_TIME rt, byte status, byte p1, byte p2 = 0) +{ + if (buffer->PackStructured(rt, 0, status | (p1 << 8) | (p2 << 16)) == E_OUTOFMEMORY) { + /* Buffer is full, clear it and try again. */ + _port->PlayBuffer(buffer); + buffer->Flush(); + + buffer->PackStructured(rt, 0, status | (p1 << 8) | (p2 << 16)); + } +} + +static void TransmitSysex(IDirectMusicBuffer *buffer, REFERENCE_TIME rt, byte *&msg_start, size_t &remaining) +{ + /* Find end of message. */ + byte *msg_end = msg_start; + while (*msg_end != MIDIST_ENDSYSEX) msg_end++; + msg_end++; // Also include SysEx end byte. + + if (buffer->PackUnstructured(rt, 0, msg_end - msg_start, msg_start) == E_OUTOFMEMORY) { + /* Buffer is full, clear it and try again. */ + _port->PlayBuffer(buffer); + buffer->Flush(); + + buffer->PackUnstructured(rt, 0, msg_end - msg_start, msg_start); + } + + /* Update position in buffer. */ + remaining -= msg_end - msg_start; + msg_start = msg_end; +} + +static void TransmitSysexConst(IDirectMusicBuffer *buffer, REFERENCE_TIME rt, byte *msg_start, size_t length) +{ + TransmitSysex(buffer, rt, msg_start, length); +} + +/** Transmit 'Note off' messages to all MIDI channels. */ +static void TransmitNotesOff(IDirectMusicBuffer *buffer, REFERENCE_TIME block_time, REFERENCE_TIME cur_time) +{ + for (int ch = 0; ch < 16; ch++) { + TransmitChannelMsg(_buffer, block_time + 10, MIDIST_CONTROLLER | ch, MIDICT_MODE_ALLNOTESOFF, 0); + TransmitChannelMsg(_buffer, block_time + 10, MIDIST_CONTROLLER | ch, MIDICT_SUSTAINSW, 0); + TransmitChannelMsg(_buffer, block_time + 10, MIDIST_CONTROLLER | ch, MIDICT_MODE_RESETALLCTRL, 0); + } + /* Explicitly flush buffer to make sure the note off messages are processed + * before we send any additional control messages. */ + _port->PlayBuffer(_buffer); + _buffer->Flush(); + + /* Some songs change the "Pitch bend range" registered parameter. If + * this doesn't get reset, everything else will start sounding wrong. */ + for (int ch = 0; ch < 16; ch++) { + /* Running status, only need status for first message + * Select RPN 00.00, set value to 02.00, and de-select again */ + TransmitChannelMsg(_buffer, block_time + 10, MIDIST_CONTROLLER | ch, MIDICT_RPN_SELECT_LO, 0x00); + TransmitChannelMsg(_buffer, block_time + 10, MIDICT_RPN_SELECT_HI, 0x00); + TransmitChannelMsg(_buffer, block_time + 10, MIDICT_DATAENTRY, 0x02); + TransmitChannelMsg(_buffer, block_time + 10, MIDICT_DATAENTRY_LO, 0x00); + TransmitChannelMsg(_buffer, block_time + 10, MIDICT_RPN_SELECT_LO, 0x7F); + TransmitChannelMsg(_buffer, block_time + 10, MIDICT_RPN_SELECT_HI, 0x7F); + + _port->PlayBuffer(_buffer); + _buffer->Flush(); + } + + /* Wait until message time has passed. */ + Sleep(Clamp((block_time - cur_time) / MS_TO_REFTIME, 5, 1000)); +} + +static void MidiThreadProc(void *) +{ + DEBUG(driver, 2, "DMusic: Entering playback thread"); + + REFERENCE_TIME last_volume_time = 0; // timestamp of the last volume change + REFERENCE_TIME block_time = 0; // timestamp of the last block sent to the port + REFERENCE_TIME playback_start_time; // timestamp current file began playback + MidiFile current_file; // file currently being played from + PlaybackSegment current_segment; // segment info for current playback + size_t current_block = 0; // next block index to send + byte current_volume = 0; // current effective volume setting + byte channel_volumes[16]; // last seen volume controller values in raw data + + /* Get pointer to the reference clock of our output port. */ + IReferenceClock *clock; + _port->GetLatencyClock(&clock); + + REFERENCE_TIME cur_time; + clock->GetTime(&cur_time); + + /* Standard "Enable General MIDI" message */ + static byte gm_enable_sysex[] = { 0xF0, 0x7E, 0x00, 0x09, 0x01, 0xF7 }; + TransmitSysexConst(_buffer, cur_time, &gm_enable_sysex[0], sizeof(gm_enable_sysex)); + /* Roland-specific reverb room control, used by the original game */ + static byte roland_reverb_sysex[] = { 0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x01, 0x30, 0x02, 0x04, 0x00, 0x40, 0x40, 0x00, 0x00, 0x09, 0xF7 }; + TransmitSysexConst(_buffer, cur_time, &roland_reverb_sysex[0], sizeof(roland_reverb_sysex)); + + _port->PlayBuffer(_buffer); + _buffer->Flush(); + + DWORD next_timeout = 1000; + while (true) { + /* Wait for a signal from the GUI thread or until the time for the next event has come. */ + DWORD wfso = WaitForSingleObject(_thread_event, next_timeout); + + if (_playback.shutdown) { + _playback.playing = false; + break; + } + + if (_playback.do_stop) { + DEBUG(driver, 2, "DMusic thread: Stopping playback"); + + /* Turn all notes off and wait a bit to allow the messages to be handled. */ + clock->GetTime(&cur_time); + TransmitNotesOff(_buffer, block_time, cur_time); + + _playback.playing = false; + _playback.do_stop = false; + block_time = 0; + next_timeout = 1000; + continue; + } + + if (wfso == WAIT_OBJECT_0) { + if (_playback.do_start) { + DEBUG(driver, 2, "DMusic thread: Starting playback"); + { + /* New scope to limit the time the mutex is locked. */ + ThreadMutexLocker lock(_thread_mutex); + + current_file.MoveFrom(_playback.next_file); + std::swap(_playback.next_segment, current_segment); + current_segment.start_block = 0; + current_block = 0; + _playback.playing = true; + _playback.do_start = false; + } + + /* Turn all notes off in case we are seeking between music titles. */ + clock->GetTime(&cur_time); + TransmitNotesOff(_buffer, block_time, cur_time); + + MemSetT(channel_volumes, 127, lengthof(channel_volumes)); + + /* Take the current time plus the preload time as the music start time. */ + clock->GetTime(&playback_start_time); + playback_start_time += _playback.preload_time * MS_TO_REFTIME; + } + } + + if (_playback.playing) { + /* skip beginning of file? */ + if (current_segment.start > 0 && current_block == 0 && current_segment.start_block == 0) { + /* find first block after start time and pretend playback started earlier + * this is to allow all blocks prior to the actual start to still affect playback, + * as they may contain important controller and program changes */ + size_t preload_bytes = 0; + for (size_t bl = 0; bl < current_file.blocks.size(); bl++) { + MidiFile::DataBlock &block = current_file.blocks[bl]; + preload_bytes += block.data.Length(); + if (block.ticktime >= current_segment.start) { + if (current_segment.loop) { + DEBUG(driver, 2, "DMusic: timer: loop from block %d (ticktime %d, realtime %.3f, bytes %d)", (int)bl, (int)block.ticktime, ((int)block.realtime) / 1000.0, (int)preload_bytes); + current_segment.start_block = bl; + break; + } else { + /* Skip the transmission delay compensation performed in the Win32 MIDI driver. + * The DMusic driver will most likely be used with the MS softsynth, which is not subject to transmission delays. + */ + DEBUG(driver, 2, "DMusic: timer: start from block %d (ticktime %d, realtime %.3f, bytes %d)", (int)bl, (int)block.ticktime, ((int)block.realtime) / 1000.0, (int)preload_bytes); + playback_start_time -= block.realtime * MIDITIME_TO_REFTIME; + break; + } + } + } + } + + /* Get current playback timestamp. */ + REFERENCE_TIME current_time; + clock->GetTime(¤t_time); + + /* Check for volume change. */ + if (current_volume != _playback.new_volume) { + if (current_time - last_volume_time > 10 * MS_TO_REFTIME) { + DEBUG(driver, 2, "DMusic thread: volume change"); + current_volume = _playback.new_volume; + last_volume_time = current_time; + for (int ch = 0; ch < 16; ch++) { + int vol = ScaleVolume(channel_volumes[ch], current_volume); + TransmitChannelMsg(_buffer, block_time + 1, MIDIST_CONTROLLER | ch, MIDICT_CHANVOLUME, vol); + } + _port->PlayBuffer(_buffer); + _buffer->Flush(); + } + } + + while (current_block < current_file.blocks.size()) { + MidiFile::DataBlock &block = current_file.blocks[current_block]; + + /* check that block isn't at end-of-song override */ + if (current_segment.end > 0 && block.ticktime >= current_segment.end) { + if (current_segment.loop) { + DEBUG(driver, 2, "DMusic thread: Looping song"); + current_block = current_segment.start_block; + playback_start_time = current_time - current_file.blocks[current_block].realtime * MIDITIME_TO_REFTIME; + } else { + _playback.do_stop = true; + } + next_timeout = 0; + break; + } + /* check that block is not in the future */ + REFERENCE_TIME playback_time = current_time - playback_start_time; + if (block.realtime * MIDITIME_TO_REFTIME > playback_time + 3 *_playback.preload_time * MS_TO_REFTIME) { + /* Stop the thread loop until we are at the preload time of the next block. */ + next_timeout = Clamp(((int64)block.realtime * MIDITIME_TO_REFTIME - playback_time) / MS_TO_REFTIME - _playback.preload_time, 0, 1000); + DEBUG(driver, 9, "DMusic thread: Next event in %lu ms (music %u, ref " OTTD_PRINTF64 ")", next_timeout, block.realtime * MIDITIME_TO_REFTIME, playback_time); + break; + } + + /* Timestamp of the current block. */ + block_time = playback_start_time + block.realtime * MIDITIME_TO_REFTIME; + DEBUG(driver, 9, "DMusic thread: Streaming block " PRINTF_SIZE " (cur=" OTTD_PRINTF64 ", block=" OTTD_PRINTF64 ")", current_block, (long long)(current_time / MS_TO_REFTIME), (long long)(block_time / MS_TO_REFTIME)); + + byte *data = block.data.Begin(); + size_t remaining = block.data.Length(); + byte last_status = 0; + while (remaining > 0) { + /* MidiFile ought to have converted everything out of running status, + * but handle it anyway just to be safe */ + byte status = data[0]; + if (status & 0x80) { + last_status = status; + data++; + remaining--; + } else { + status = last_status; + } + switch (status & 0xF0) { + case MIDIST_PROGCHG: + case MIDIST_CHANPRESS: + /* 2 byte channel messages */ + TransmitChannelMsg(_buffer, block_time, status, data[0]); + data++; + remaining--; + break; + case MIDIST_NOTEOFF: + case MIDIST_NOTEON: + case MIDIST_POLYPRESS: + case MIDIST_PITCHBEND: + /* 3 byte channel messages */ + TransmitChannelMsg(_buffer, block_time, status, data[0], data[1]); + data += 2; + remaining -= 2; + break; + case MIDIST_CONTROLLER: + /* controller change */ + if (data[0] == MIDICT_CHANVOLUME) { + /* volume controller, adjust for user volume */ + channel_volumes[status & 0x0F] = data[1]; + int vol = ScaleVolume(data[1], current_volume); + TransmitChannelMsg(_buffer, block_time, status, data[0], vol); + } else { + /* handle other controllers normally */ + TransmitChannelMsg(_buffer, block_time, status, data[0], data[1]); + } + data += 2; + remaining -= 2; + break; + case 0xF0: + /* system messages */ + switch (status) { + case MIDIST_SYSEX: /* system exclusive */ + TransmitSysex(_buffer, block_time, data, remaining); + break; + case MIDIST_TC_QFRAME: /* time code quarter frame */ + case MIDIST_SONGSEL: /* song select */ + data++; + remaining--; + break; + case MIDIST_SONGPOSPTR: /* song position pointer */ + data += 2; + remaining -= 2; + break; + default: /* remaining have no data bytes */ + break; + } + break; + } + } + + current_block++; + } + + /* Anything in the playback buffer? Send it down the port. */ + DWORD used_buffer = 0; + _buffer->GetUsedBytes(&used_buffer); + if (used_buffer > 0) { + _port->PlayBuffer(_buffer); + _buffer->Flush(); + } + + /* end? */ + if (current_block == current_file.blocks.size()) { + if (current_segment.loop) { + current_block = current_segment.start_block; + playback_start_time = block_time - current_file.blocks[current_block].realtime * MIDITIME_TO_REFTIME; + } else { + _playback.do_stop = true; + } + next_timeout = 0; + } + } + } + + DEBUG(driver, 2, "DMusic: Exiting playback thread"); + + /* Turn all notes off and wait a bit to allow the messages to be handled by real hardware. */ + clock->GetTime(&cur_time); + TransmitNotesOff(_buffer, block_time, cur_time); + Sleep(_playback.preload_time * 4); + + clock->Release(); +} + +static void * DownloadArticulationData(int base_offset, void *data, const std::vector &artic) +{ + DMUS_ARTICULATION2 *art = (DMUS_ARTICULATION2 *)data; + art->ulArtIdx = base_offset + 1; + art->ulFirstExtCkIdx = 0; + art->ulNextArtIdx = 0; + + CONNECTIONLIST *con_list = (CONNECTIONLIST *)(art + 1); + con_list->cbSize = sizeof(CONNECTIONLIST); + con_list->cConnections = (ULONG)artic.size(); + MemCpyT((CONNECTION *)(con_list + 1), &artic.front(), artic.size()); + + return (CONNECTION *)(con_list + 1) + artic.size(); +} + +static const char *LoadDefaultDLSFile(const char *user_dls) +{ + DMUS_PORTCAPS caps; + MemSetT(&caps, 0); + caps.dwSize = sizeof(DMUS_PORTCAPS); + _port->GetCaps(&caps); + + /* Nothing to unless it is a synth with instrument download that doesn't come with GM voices by default. */ + if ((caps.dwFlags & (DMUS_PC_DLS | DMUS_PC_DLS2)) != 0 && (caps.dwFlags & DMUS_PC_GMINHARDWARE) == 0) { + DLSFile dls_file; + + if (user_dls == NULL) { + /* Try loading the default GM DLS file stored in the registry. */ + HKEY hkDM; + if (SUCCEEDED(RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\DirectMusic"), 0, KEY_READ, &hkDM))) { + TCHAR dls_path[MAX_PATH]; + DWORD buf_size = sizeof(dls_path); // Buffer size as to be given in bytes! + if (SUCCEEDED(RegQueryValueEx(hkDM, _T("GMFilePath"), NULL, NULL, (LPBYTE)dls_path, &buf_size))) { + TCHAR expand_path[MAX_PATH * 2]; + ExpandEnvironmentStrings(dls_path, expand_path, lengthof(expand_path)); + if (!dls_file.LoadFile(expand_path)) DEBUG(driver, 1, "Failed to load default GM DLS file from registry"); + } + RegCloseKey(hkDM); + } + + /* If we couldn't load the file from the registry, try again at the default install path of the GM DLS file. */ + if (dls_file.instruments.size() == 0) { + static const TCHAR *DLS_GM_FILE = _T("%windir%\\System32\\drivers\\gm.dls"); + TCHAR path[MAX_PATH]; + ExpandEnvironmentStrings(DLS_GM_FILE, path, lengthof(path)); + + if (!dls_file.LoadFile(path)) return "Can't load GM DLS collection"; + } + } else { + if (!dls_file.LoadFile(OTTD2FS(user_dls))) return "Can't load GM DLS collection"; + } + + /* Get download port and allocate download IDs. */ + IDirectMusicPortDownload *download_port = NULL; + if (FAILED(_port->QueryInterface(IID_IDirectMusicPortDownload, (LPVOID *)&download_port))) return "Can't get download port"; + + DWORD dlid_wave = 0, dlid_inst = 0; + if (FAILED(download_port->GetDLId(&dlid_wave, (DWORD)dls_file.waves.size())) || FAILED(download_port->GetDLId(&dlid_inst, (DWORD)dls_file.instruments.size()))) { + download_port->Release(); + return "Can't get enough DLS ids"; + } + + DWORD dwAppend = 0; + download_port->GetAppend(&dwAppend); + + /* Download wave data. */ + for (DWORD i = 0; i < dls_file.waves.size(); i++) { + IDirectMusicDownload *dl_wave = NULL; + if (FAILED(download_port->AllocateBuffer((DWORD)(sizeof(WAVE_DOWNLOAD) + dwAppend * dls_file.waves[i].fmt.wf.nBlockAlign + dls_file.waves[i].data.size()), &dl_wave))) { + download_port->Release(); + return "Can't allocate wave download buffer"; + } + + WAVE_DOWNLOAD *wave; + DWORD wave_size = 0; + if (FAILED(dl_wave->GetBuffer((LPVOID *)&wave, &wave_size))) { + dl_wave->Release(); + download_port->Release(); + return "Can't get wave download buffer"; + } + + /* Fill download data. */ + MemSetT(wave, 0); + wave->dlInfo.dwDLType = DMUS_DOWNLOADINFO_WAVE; + wave->dlInfo.cbSize = wave_size; + wave->dlInfo.dwDLId = dlid_wave + i; + wave->dlInfo.dwNumOffsetTableEntries = 2; + wave->ulOffsetTable[0] = offsetof(WAVE_DOWNLOAD, dmWave); + wave->ulOffsetTable[1] = offsetof(WAVE_DOWNLOAD, dmWaveData); + wave->dmWave.ulWaveDataIdx = 1; + MemCpyT((PCMWAVEFORMAT *)&wave->dmWave.WaveformatEx, &dls_file.waves[i].fmt, 1); + wave->dmWaveData.cbSize = (DWORD)dls_file.waves[i].data.size(); + MemCpyT(wave->dmWaveData.byData, &dls_file.waves[i].data[0], dls_file.waves[i].data.size()); + + _dls_downloads.push_back(dl_wave); + if (FAILED(download_port->Download(dl_wave))) { + download_port->Release(); + return "Downloading DLS wave failed"; + } + } + + /* Download instrument data. */ + for (DWORD i = 0; i < dls_file.instruments.size(); i++) { + DWORD offsets = 1 + (DWORD)dls_file.instruments[i].regions.size(); + + /* Calculate download size for the instrument. */ + size_t i_size = sizeof(DMUS_DOWNLOADINFO) + sizeof(DMUS_INSTRUMENT); + if (dls_file.instruments[i].articulators.size() > 0) { + /* Articulations are stored as two chunks, one containing meta data and one with the actual articulation data. */ + offsets += 2; + i_size += sizeof(DMUS_ARTICULATION2) + sizeof(CONNECTIONLIST) + sizeof(CONNECTION) * dls_file.instruments[i].articulators.size(); + } + + for (std::vector::iterator rgn = dls_file.instruments[i].regions.begin(); rgn != dls_file.instruments[i].regions.end(); rgn++) { + if (rgn->articulators.size() > 0) { + offsets += 2; + i_size += sizeof(DMUS_ARTICULATION2) + sizeof(CONNECTIONLIST) + sizeof(CONNECTION) * rgn->articulators.size(); + } + + /* Region size depends on the number of wave loops. The size of the + * declared structure already accounts for one loop. */ + if (rgn->wave_sample.cbSize != 0) { + i_size += sizeof(DMUS_REGION) - sizeof(DMUS_REGION::WLOOP) + sizeof(WLOOP) * rgn->wave_loops.size(); + } else { + i_size += sizeof(DMUS_REGION) - sizeof(DMUS_REGION::WLOOP) + sizeof(WLOOP) * dls_file.waves[dls_file.pool_cues[rgn->wave.ulTableIndex].ulOffset].wave_loops.size(); + } + } + + i_size += offsets * sizeof(ULONG); + + /* Allocate download buffer. */ + IDirectMusicDownload *dl_inst = NULL; + if (FAILED(download_port->AllocateBuffer((DWORD)i_size, &dl_inst))) { + download_port->Release(); + return "Can't allocate instrument download buffer"; + } + + void *instrument; + DWORD inst_size = 0; + if (FAILED(dl_inst->GetBuffer((LPVOID *)&instrument, &inst_size))) { + dl_inst->Release(); + download_port->Release(); + return "Can't get instrument download buffer"; + } + char *inst_base = (char *)instrument; + + /* Fill download header. */ + DMUS_DOWNLOADINFO *d_info = (DMUS_DOWNLOADINFO *)instrument; + d_info->dwDLType = DMUS_DOWNLOADINFO_INSTRUMENT2; + d_info->cbSize = inst_size; + d_info->dwDLId = dlid_inst + i; + d_info->dwNumOffsetTableEntries = offsets; + instrument = d_info + 1; + + /* Download offset table; contains the offsets of all chunks relative to the buffer start. */ + ULONG *offset_table = (ULONG *)instrument; + instrument = offset_table + offsets; + int last_offset = 0; + + /* Instrument header. */ + DMUS_INSTRUMENT *inst_data = (DMUS_INSTRUMENT *)instrument; + MemSetT(inst_data, 0); + offset_table[last_offset++] = (char *)inst_data - inst_base; + inst_data->ulPatch = (dls_file.instruments[i].hdr.Locale.ulBank & F_INSTRUMENT_DRUMS) | ((dls_file.instruments[i].hdr.Locale.ulBank & 0x7F7F) << 8) | (dls_file.instruments[i].hdr.Locale.ulInstrument & 0x7F); + instrument = inst_data + 1; + + /* Write global articulations. */ + if (dls_file.instruments[i].articulators.size() > 0) { + inst_data->ulGlobalArtIdx = last_offset; + offset_table[last_offset++] = (char *)instrument - inst_base; + offset_table[last_offset++] = (char *)instrument + sizeof(DMUS_ARTICULATION2) - inst_base; + + instrument = DownloadArticulationData(inst_data->ulGlobalArtIdx, instrument, dls_file.instruments[i].articulators); + assert((char *)instrument - inst_base <= (ptrdiff_t)inst_size); + } + + /* Write out regions. */ + inst_data->ulFirstRegionIdx = last_offset; + for (uint j = 0; j < dls_file.instruments[i].regions.size(); j++) { + DLSFile::DLSRegion &rgn = dls_file.instruments[i].regions[j]; + + DMUS_REGION *inst_region = (DMUS_REGION *)instrument; + offset_table[last_offset++] = (char *)inst_region - inst_base; + inst_region->RangeKey = rgn.hdr.RangeKey; + inst_region->RangeVelocity = rgn.hdr.RangeVelocity; + inst_region->fusOptions = rgn.hdr.fusOptions; + inst_region->usKeyGroup = rgn.hdr.usKeyGroup; + inst_region->ulFirstExtCkIdx = 0; + + ULONG wave_id = dls_file.pool_cues[rgn.wave.ulTableIndex].ulOffset; + inst_region->WaveLink = rgn.wave; + inst_region->WaveLink.ulTableIndex = wave_id + dlid_wave; + + /* The wave sample data will be taken from the region, if defined, otherwise from the wave itself. */ + if (rgn.wave_sample.cbSize != 0) { + inst_region->WSMP = rgn.wave_sample; + if (rgn.wave_loops.size() > 0) MemCpyT(inst_region->WLOOP, &rgn.wave_loops.front(), rgn.wave_loops.size()); + + instrument = (char *)(inst_region + 1) - sizeof(DMUS_REGION::WLOOP) + sizeof(WLOOP) * rgn.wave_loops.size(); + } else { + inst_region->WSMP = rgn.wave_sample; + if (dls_file.waves[wave_id].wave_loops.size() > 0) MemCpyT(inst_region->WLOOP, &dls_file.waves[wave_id].wave_loops.front(), dls_file.waves[wave_id].wave_loops.size()); + + instrument = (char *)(inst_region + 1) - sizeof(DMUS_REGION::WLOOP) + sizeof(WLOOP) * dls_file.waves[wave_id].wave_loops.size(); + } + + /* Write local articulator data. */ + if (rgn.articulators.size() > 0) { + inst_region->ulRegionArtIdx = last_offset; + offset_table[last_offset++] = (char *)instrument - inst_base; + offset_table[last_offset++] = (char *)instrument + sizeof(DMUS_ARTICULATION2) - inst_base; + + instrument = DownloadArticulationData(inst_region->ulRegionArtIdx, instrument, rgn.articulators); + } else { + inst_region->ulRegionArtIdx = 0; + } + assert((char *)instrument - inst_base <= (ptrdiff_t)inst_size); + + /* Link to the next region unless this was the last one.*/ + inst_region->ulNextRegionIdx = j < dls_file.instruments[i].regions.size() - 1 ? last_offset : 0; + } + + _dls_downloads.push_back(dl_inst); + if (FAILED(download_port->Download(dl_inst))) { + download_port->Release(); + return "Downloading DLS instrument failed"; + } + } + + download_port->Release(); + } + + return NULL; +} const char *MusicDriver_DMusic::Start(const char * const *parm) { - if (performance != NULL) return NULL; - - if (proc.CoCreateInstance == NULL) { - if (!LoadLibraryList((Function*)&proc, ole_files)) { - return "ole32.dll load failed"; - } - } - /* Initialize COM */ - if (FAILED(proc.CoInitialize(NULL))) { - return "COM initialization failed"; - } + if (FAILED(CoInitializeEx(NULL, COINITBASE_MULTITHREADED))) return "COM initialization failed"; - /* create the performance object */ - if (FAILED(proc.CoCreateInstance( - CLSID_DirectMusicPerformance, + /* Create the DirectMusic object */ + if (FAILED(CoCreateInstance( + CLSID_DirectMusic, NULL, CLSCTX_INPROC, - IID_IDirectMusicPerformance, - (LPVOID*)&performance + IID_IDirectMusic, + (LPVOID*)&_music ))) { - return "Failed to create the performance object"; + return "Failed to create the music object"; } - /* initialize it */ - if (FAILED(performance->Init(&music, NULL, NULL))) { - return "Failed to initialize performance object"; - } + /* Assign sound output device. */ + if (FAILED(_music->SetDirectSound(NULL, NULL))) return "Can't set DirectSound interface"; - int port = GetDriverParamInt(parm, "port", -1); + /* MIDI events need to be send to the synth in time before their playback time + * has come. By default, we try send any events at least 50 ms before playback. */ + _playback.preload_time = GetDriverParamInt(parm, "preload", 50); + int pIdx = GetDriverParamInt(parm, "port", -1); if (_debug_driver_level > 0) { /* Print all valid output ports. */ char desc[DMUS_MAX_DESCRIPTION]; @@ -108,69 +1121,56 @@ const char *MusicDriver_DMusic::Start(const char * const *parm) caps.dwSize = sizeof(DMUS_PORTCAPS); DEBUG(driver, 1, "Detected DirectMusic ports:"); - for (int i = 0; music->EnumPort(i, &caps) == S_OK; i++) { + for (int i = 0; _music->EnumPort(i, &caps) == S_OK; i++) { if (caps.dwClass == DMUS_PC_OUTPUTCLASS) { /* Description is UNICODE even for ANSI build. */ - DEBUG(driver, 1, " %d: %s%s", i, convert_from_fs(caps.wszDescription, desc, lengthof(desc)), i == port ? " (selected)" : ""); + DEBUG(driver, 1, " %d: %s%s", i, convert_from_fs(caps.wszDescription, desc, lengthof(desc)), i == pIdx ? " (selected)" : ""); } } } - IDirectMusicPort *music_port = NULL; // NULL means 'use default port'. - - if (port >= 0) { + GUID guidPort; + if (pIdx >= 0) { /* Check if the passed port is a valid port. */ DMUS_PORTCAPS caps; MemSetT(&caps, 0); caps.dwSize = sizeof(DMUS_PORTCAPS); - if (FAILED(music->EnumPort(port, &caps))) return "Supplied port parameter is not a valid port"; + if (FAILED(_music->EnumPort(pIdx, &caps))) return "Supplied port parameter is not a valid port"; if (caps.dwClass != DMUS_PC_OUTPUTCLASS) return "Supplied port parameter is not an output port"; - - /* Create new port. */ - DMUS_PORTPARAMS params; - MemSetT(¶ms, 0); - params.dwSize = sizeof(DMUS_PORTPARAMS); - params.dwValidParams = DMUS_PORTPARAMS_CHANNELGROUPS; - params.dwChannelGroups = 1; - - if (FAILED(music->CreatePort(caps.guidPort, ¶ms, &music_port, NULL))) { - return "Failed to create port"; - } - - /* Activate port. */ - if (FAILED(music_port->Activate(TRUE))) { - music_port->Release(); - return "Failed to activate port"; - } + guidPort = caps.guidPort; + } else { + if (FAILED(_music->GetDefaultPort(&guidPort))) return "Can't query default music port"; } - /* Add port to performance. */ - if (FAILED(performance->AddPort(music_port))) { - if (music_port != NULL) music_port->Release(); - return "AddPort failed"; - } + /* Create new port. */ + DMUS_PORTPARAMS params; + MemSetT(¶ms, 0); + params.dwSize = sizeof(DMUS_PORTPARAMS); + params.dwValidParams = DMUS_PORTPARAMS_CHANNELGROUPS; + params.dwChannelGroups = 1; + if (FAILED(_music->CreatePort(guidPort, ¶ms, &_port, NULL))) return "Failed to create port"; + /* Activate port. */ + if (FAILED(_port->Activate(TRUE))) return "Failed to activate port"; - /* Assign a performance channel block to the performance if we added - * a custom port to the performance. */ - if (music_port != NULL) { - if (FAILED(performance->AssignPChannelBlock(0, music_port, 1))) { - music_port->Release(); - return "Failed to assign PChannel block"; - } - /* We don't need the port anymore. */ - music_port->Release(); - } + /* Create playback buffer. */ + DMUS_BUFFERDESC desc; + MemSetT(&desc, 0); + desc.dwSize = sizeof(DMUS_BUFFERDESC); + desc.guidBufferFormat = KSDATAFORMAT_SUBTYPE_DIRECTMUSIC; + desc.cbBuffer = 1024; + if (FAILED(_music->CreateMusicBuffer(&desc, &_buffer, NULL))) return "Failed to create music buffer"; - /* create the loader object; this will be used to load the MIDI file */ - if (FAILED(proc.CoCreateInstance( - CLSID_DirectMusicLoader, - NULL, - CLSCTX_INPROC, - IID_IDirectMusicLoader, - (LPVOID*)&loader - ))) { - return "Failed to create loader object"; - } + /* On soft-synths (e.g. the default DirectMusic one), we might need to load a wavetable set to get music. */ + const char *dls = LoadDefaultDLSFile(GetDriverParam(parm, "dls")); + if (dls != NULL) return dls; + + /* Create playback thread and synchronization primitives. */ + _thread_event = CreateEvent(NULL, FALSE, FALSE, NULL); + if (_thread_event == NULL) return "Can't create thread shutdown event"; + _thread_mutex = ThreadMutex::New(); + if (_thread_mutex == NULL) return "Can't create thread mutex"; + + if (!ThreadObject::New(&MidiThreadProc, this, &_dmusic_thread, "ottd:dmusic")) return "Can't create MIDI output thread"; return NULL; } @@ -184,114 +1184,82 @@ MusicDriver_DMusic::~MusicDriver_DMusic() void MusicDriver_DMusic::Stop() { - seeking = false; - - if (performance != NULL) performance->Stop(NULL, NULL, 0, 0); - - if (segment != NULL) { - segment->SetParam(GUID_Unload, 0xFFFFFFFF, 0, 0, performance); - segment->Release(); - segment = NULL; + if (_dmusic_thread != NULL) { + _playback.shutdown = true; + SetEvent(_thread_event); + _dmusic_thread->Join(); } - if (music != NULL) { - music->Release(); - music = NULL; + /* Unloaded any instruments we loaded. */ + if (_dls_downloads.size() > 0) { + IDirectMusicPortDownload *download_port = NULL; + _port->QueryInterface(IID_IDirectMusicPortDownload, (LPVOID *)&download_port); + + /* Instruments refer to waves. As the waves are at the beginning of the download list, + * do the unload from the back so that references are cleared properly. */ + for (std::vector::reverse_iterator i = _dls_downloads.rbegin(); download_port != NULL && i != _dls_downloads.rend(); i++) { + download_port->Unload(*i); + (*i)->Release(); + } + _dls_downloads.clear(); + + if (download_port != NULL) download_port->Release(); } - if (performance != NULL) { - performance->CloseDown(); - performance->Release(); - performance = NULL; + if (_buffer != NULL) { + _buffer->Release(); + _buffer = NULL; } - if (loader != NULL) { - loader->Release(); - loader = NULL; + if (_port != NULL) { + _port->Activate(FALSE); + _port->Release(); + _port = NULL; } - proc.CoUninitialize(); + if (_music != NULL) { + _music->Release(); + _music = NULL; + } + + CloseHandle(_thread_event); + delete _thread_mutex; + + CoUninitialize(); } -void MusicDriver_DMusic::PlaySong(const char *filename) +void MusicDriver_DMusic::PlaySong(const MusicSongInfo &song) { - /* set up the loader object info */ - DMUS_OBJECTDESC obj_desc; - ZeroMemory(&obj_desc, sizeof(obj_desc)); - obj_desc.dwSize = sizeof(obj_desc); - obj_desc.guidClass = CLSID_DirectMusicSegment; - obj_desc.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_FILENAME | DMUS_OBJ_FULLPATH; - MultiByteToWideChar( - CP_ACP, MB_PRECOMPOSED, - filename, -1, - obj_desc.wszFileName, lengthof(obj_desc.wszFileName) - ); + ThreadMutexLocker lock(_thread_mutex); - /* release the existing segment if we have any */ - if (segment != NULL) { - segment->Release(); - segment = NULL; - } + if (!_playback.next_file.LoadSong(song)) return; - /* make a new segment */ - if (FAILED(loader->GetObject( - &obj_desc, IID_IDirectMusicSegment, (LPVOID*)&segment - ))) { - DEBUG(driver, 0, "DirectMusic: GetObject failed"); - return; - } + _playback.next_segment.start = song.override_start; + _playback.next_segment.end = song.override_end; + _playback.next_segment.loop = song.loop; - /* tell the segment what kind of data it contains */ - if (FAILED(segment->SetParam( - GUID_StandardMIDIFile, 0xFFFFFFFF, 0, 0, performance - ))) { - DEBUG(driver, 0, "DirectMusic: SetParam (MIDI file) failed"); - return; - } - - /* tell the segment to 'download' the instruments */ - if (FAILED(segment->SetParam(GUID_Download, 0xFFFFFFFF, 0, 0, performance))) { - DEBUG(driver, 0, "DirectMusic: failed to download instruments"); - return; - } - - /* start playing the MIDI file */ - if (FAILED(performance->PlaySegment(segment, 0, 0, NULL))) { - DEBUG(driver, 0, "DirectMusic: PlaySegment failed"); - return; - } - - seeking = true; + _playback.do_start = true; + SetEvent(_thread_event); } void MusicDriver_DMusic::StopSong() { - if (FAILED(performance->Stop(segment, NULL, 0, 0))) { - DEBUG(driver, 0, "DirectMusic: StopSegment failed"); - } - seeking = false; + _playback.do_stop = true; + SetEvent(_thread_event); } bool MusicDriver_DMusic::IsSongPlaying() { - /* Not the nicest code, but there is a short delay before playing actually - * starts. OpenTTD makes no provision for this. */ - if (performance->IsPlaying(segment, NULL) == S_OK) { - seeking = false; - return true; - } else { - return seeking; - } + return _playback.playing || _playback.do_start; } void MusicDriver_DMusic::SetVolume(byte vol) { - long db = vol * 2000 / 127 - 2000; ///< 0 - 127 -> -2000 - 0 - performance->SetGlobalParam(GUID_PerfMasterVolume, &db, sizeof(db)); + _playback.new_volume = vol; } diff --git a/src/music/dmusic.h b/src/music/dmusic.h index 7287623e48..527e064e49 100644 --- a/src/music/dmusic.h +++ b/src/music/dmusic.h @@ -23,7 +23,7 @@ public: /* virtual */ void Stop(); - /* virtual */ void PlaySong(const char *filename); + /* virtual */ void PlaySong(const MusicSongInfo &song); /* virtual */ void StopSong(); diff --git a/src/music/extmidi.cpp b/src/music/extmidi.cpp index d39a050f6c..9d07761b73 100644 --- a/src/music/extmidi.cpp +++ b/src/music/extmidi.cpp @@ -17,6 +17,8 @@ #include "../video/video_driver.hpp" #include "../gfx_func.h" #include "extmidi.h" +#include "../base_media_base.h" +#include "midifile.hpp" #include #include #include @@ -83,10 +85,13 @@ void MusicDriver_ExtMidi::Stop() this->DoStop(); } -void MusicDriver_ExtMidi::PlaySong(const char *filename) +void MusicDriver_ExtMidi::PlaySong(const MusicSongInfo &song) { - strecpy(this->song, filename, lastof(this->song)); - this->DoStop(); + std::string filename = MidiFile::GetSMFFile(song); + if (!filename.empty()) { + strecpy(this->song, filename.c_str(), lastof(this->song)); + this->DoStop(); + } } void MusicDriver_ExtMidi::StopSong() diff --git a/src/music/extmidi.h b/src/music/extmidi.h index cfbd894596..e174dc9b08 100644 --- a/src/music/extmidi.h +++ b/src/music/extmidi.h @@ -28,7 +28,7 @@ public: /* virtual */ void Stop(); - /* virtual */ void PlaySong(const char *filename); + /* virtual */ void PlaySong(const MusicSongInfo &song); /* virtual */ void StopSong(); diff --git a/src/music/fluidsynth.cpp b/src/music/fluidsynth.cpp new file mode 100644 index 0000000000..d1088f4bc4 --- /dev/null +++ b/src/music/fluidsynth.cpp @@ -0,0 +1,155 @@ +/* $Id$ */ + +/* + * 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 . + */ + +/** @file fluidsynth.cpp Playing music via the fluidsynth library. */ + +#include "../stdafx.h" +#include "../openttd.h" +#include "../sound_type.h" +#include "../debug.h" +#include "fluidsynth.h" +#include "midifile.hpp" +#include +#include "../mixer.h" + +static struct { + fluid_settings_t* settings; ///< FluidSynth settings handle + fluid_synth_t* synth; ///< FluidSynth synthesizer handle + fluid_player_t* player; ///< FluidSynth MIDI player handle +} _midi; ///< Metadata about the midi we're playing. + +/** Factory for the FluidSynth driver. */ +static FMusicDriver_FluidSynth iFMusicDriver_FluidSynth; + +/** List of sound fonts to try by default. */ +static const char *default_sf[] = { + /* Debian/Ubuntu/OpenSUSE preferred */ + "/usr/share/sounds/sf2/FluidR3_GM.sf2", + + /* RedHat/Fedora/Arch preferred */ + "/usr/share/soundfonts/FluidR3_GM.sf2", + + /* Debian/Ubuntu/OpenSUSE alternatives */ + "/usr/share/sounds/sf2/TimGM6mb.sf2", + "/usr/share/sounds/sf2/FluidR3_GS.sf2", + + NULL +}; + +static void RenderMusicStream(int16 *buffer, size_t samples) +{ + if (!_midi.synth || !_midi.player) return; + fluid_synth_write_s16(_midi.synth, samples, buffer, 0, 2, buffer, 1, 2); +} + +const char *MusicDriver_FluidSynth::Start(const char * const *param) +{ + const char *sfont_name = GetDriverParam(param, "soundfont"); + int sfont_id; + + DEBUG(driver, 1, "Fluidsynth: sf %s", sfont_name); + + /* Create the settings. */ + _midi.settings = new_fluid_settings(); + if (!_midi.settings) return "Could not create midi settings"; + + /* Create the synthesizer. */ + _midi.synth = new_fluid_synth(_midi.settings); + if (!_midi.synth) return "Could not open synth"; + + /* Load a SoundFont and reset presets (so that new instruments + * get used from the SoundFont) */ + if (!sfont_name) { + int i; + sfont_id = FLUID_FAILED; + for (i = 0; default_sf[i]; i++) { + if (!fluid_is_soundfont(default_sf[i])) continue; + sfont_id = fluid_synth_sfload(_midi.synth, default_sf[i], 1); + if (sfont_id != FLUID_FAILED) break; + } + if (sfont_id == FLUID_FAILED) return "Could not open any sound font"; + } else { + sfont_id = fluid_synth_sfload(_midi.synth, sfont_name, 1); + if (sfont_id == FLUID_FAILED) return "Could not open sound font"; + } + + _midi.player = NULL; + + uint32 samplerate = MxSetMusicSource(RenderMusicStream); + fluid_synth_set_sample_rate(_midi.synth, samplerate); + DEBUG(driver, 1, "Fluidsynth: samplerate %.0f", (float)samplerate); + + return NULL; +} + +void MusicDriver_FluidSynth::Stop() +{ + MxSetMusicSource(NULL); + this->StopSong(); + delete_fluid_synth(_midi.synth); + delete_fluid_settings(_midi.settings); +} + +void MusicDriver_FluidSynth::PlaySong(const MusicSongInfo &song) +{ + std::string filename = MidiFile::GetSMFFile(song); + + this->StopSong(); + + if (filename.empty()) { + return; + } + + _midi.player = new_fluid_player(_midi.synth); + if (!_midi.player) { + DEBUG(driver, 0, "Could not create midi player"); + return; + } + + if (fluid_player_add(_midi.player, filename.c_str()) != FLUID_OK) { + DEBUG(driver, 0, "Could not open music file"); + delete_fluid_player(_midi.player); + _midi.player = NULL; + return; + } + if (fluid_player_play(_midi.player) != FLUID_OK) { + DEBUG(driver, 0, "Could not start midi player"); + delete_fluid_player(_midi.player); + _midi.player = NULL; + return; + } +} + +void MusicDriver_FluidSynth::StopSong() +{ + if (!_midi.player) return; + + fluid_player_stop(_midi.player); + if (fluid_player_join(_midi.player) != FLUID_OK) { + DEBUG(driver, 0, "Could not join player"); + } + delete_fluid_player(_midi.player); + fluid_synth_system_reset(_midi.synth); + _midi.player = NULL; +} + +bool MusicDriver_FluidSynth::IsSongPlaying() +{ + if (!_midi.player) return false; + + return fluid_player_get_status(_midi.player) == FLUID_PLAYER_PLAYING; +} + +void MusicDriver_FluidSynth::SetVolume(byte vol) +{ + /* Allowed range of synth.gain is 0.0 to 10.0 */ + if (fluid_settings_setnum(_midi.settings, "synth.gain", 1.0 * vol / 128.0) != 1) { + DEBUG(driver, 0, "Could not set volume"); + } +} diff --git a/src/music/fluidsynth.h b/src/music/fluidsynth.h new file mode 100644 index 0000000000..171128a8e9 --- /dev/null +++ b/src/music/fluidsynth.h @@ -0,0 +1,41 @@ +/* $Id$ */ + +/* + * 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 . + */ + +/** @file fluidsynth.h Base for FluidSynth music playback. */ + +#ifndef MUSIC_FLUIDSYNTH_H +#define MUSIC_FLUIDSYNTH_H + +#include "music_driver.hpp" + +/** Music driver making use of FluidSynth. */ +class MusicDriver_FluidSynth : public MusicDriver { +public: + /* virtual */ const char *Start(const char * const *param); + + /* virtual */ void Stop(); + + /* virtual */ void PlaySong(const MusicSongInfo &song); + + /* virtual */ void StopSong(); + + /* virtual */ bool IsSongPlaying(); + + /* virtual */ void SetVolume(byte vol); + /* virtual */ const char *GetName() const { return "fluidsynth"; } +}; + +/** Factory for the fluidsynth driver. */ +class FMusicDriver_FluidSynth : public DriverFactoryBase { +public: + FMusicDriver_FluidSynth() : DriverFactoryBase(Driver::DT_MUSIC, 5, "fluidsynth", "FluidSynth MIDI Driver") {} + /* virtual */ Driver *CreateInstance() const { return new MusicDriver_FluidSynth(); } +}; + +#endif /* MUSIC_FLUIDSYNTH_H */ diff --git a/src/music/libtimidity.cpp b/src/music/libtimidity.cpp index 1cb2adc0f9..42c1e3c155 100644 --- a/src/music/libtimidity.cpp +++ b/src/music/libtimidity.cpp @@ -14,6 +14,8 @@ #include "../sound_type.h" #include "../debug.h" #include "libtimidity.h" +#include "midifile.hpp" +#include "../base_media_base.h" #include #include #include @@ -22,9 +24,6 @@ #include #include #include -#if defined(PSP) -#include -#endif /* PSP */ #include "../safeguards.h" @@ -44,16 +43,6 @@ static struct { uint32 song_position; } _midi; ///< Metadata about the midi we're playing. -#if defined(PSP) -static void AudioOutCallback(void *buf, unsigned int _reqn, void *userdata) -{ - memset(buf, 0, _reqn * PSP_NUM_AUDIO_CHANNELS); - if (_midi.status == MIDI_PLAYING) { - mid_song_read_wave(_midi.song, buf, _reqn * PSP_NUM_AUDIO_CHANNELS); - } -} -#endif /* PSP */ - /** Factory for the libtimidity driver. */ static FMusicDriver_LibTimidity iFMusicDriver_LibTimidity; @@ -75,17 +64,7 @@ const char *MusicDriver_LibTimidity::Start(const char * const *param) _midi.options.rate = 44100; _midi.options.format = MID_AUDIO_S16LSB; _midi.options.channels = 2; -#if defined(PSP) - _midi.options.buffer_size = PSP_NUM_AUDIO_SAMPLES; -#else _midi.options.buffer_size = _midi.options.rate; -#endif - -#if defined(PSP) - pspAudioInit(); - pspAudioSetChannelCallback(_midi.options.channels, &AudioOutCallback, NULL); - pspAudioSetVolume(_midi.options.channels, PSP_VOLUME_MAX, PSP_VOLUME_MAX); -#endif /* PSP */ return NULL; } @@ -96,11 +75,14 @@ void MusicDriver_LibTimidity::Stop() mid_exit(); } -void MusicDriver_LibTimidity::PlaySong(const char *filename) +void MusicDriver_LibTimidity::PlaySong(const MusicSongInfo &song) { - this->StopSong(); + std::string filename = MidiFile::GetSMFFile(song); - _midi.stream = mid_istream_open_file(filename); + this->StopSong(); + if (filename.empty()) return; + + _midi.stream = mid_istream_open_file(filename.c_str()); if (_midi.stream == NULL) { DEBUG(driver, 0, "Could not open music file"); return; diff --git a/src/music/libtimidity.h b/src/music/libtimidity.h index abe17e7703..badb05bab2 100644 --- a/src/music/libtimidity.h +++ b/src/music/libtimidity.h @@ -21,7 +21,7 @@ public: /* virtual */ void Stop(); - /* virtual */ void PlaySong(const char *filename); + /* virtual */ void PlaySong(const MusicSongInfo &song); /* virtual */ void StopSong(); diff --git a/src/music/midi.h b/src/music/midi.h new file mode 100644 index 0000000000..473f7f18bb --- /dev/null +++ b/src/music/midi.h @@ -0,0 +1,144 @@ +/* $Id$ */ + +/* +* 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 . +*/ + +/* @file midi.h Declarations for MIDI data */ + +#ifndef MUSIC_MIDI_H +#define MUSIC_MIDI_H + +#include "../stdafx.h" + +/** Header of a Stanard MIDI File */ +struct SMFHeader { + uint16 format; + uint16 tracks; + uint16 tickdiv; +}; + +/** MIDI status byte codes */ +enum MidiStatus { + /* Bytes with top bit unset are data bytes i.e. not status bytes */ + /* Channel status messages, require channel number in lower nibble */ + MIDIST_NOTEOFF = 0x80, + MIDIST_NOTEON = 0x90, + MIDIST_POLYPRESS = 0xA0, + MIDIST_CONTROLLER = 0xB0, + MIDIST_PROGCHG = 0xC0, + MIDIST_CHANPRESS = 0xD0, + MIDIST_PITCHBEND = 0xE0, + /* Full byte status messages */ + MIDIST_SYSEX = 0xF0, + MIDIST_TC_QFRAME = 0xF1, + MIDIST_SONGPOSPTR = 0xF2, + MIDIST_SONGSEL = 0xF3, + /* not defined: 0xF4, */ + /* not defined: 0xF5, */ + MIDIST_TUNEREQ = 0xF6, + MIDIST_ENDSYSEX = 0xF7, ///< only occurs in realtime data + MIDIST_SMF_ESCAPE = 0xF7, ///< only occurs in SMF data + MIDIST_RT_CLOCK = 0xF8, + /* not defined: 0xF9, */ + MIDIST_RT_START = 0xFA, + MIDIST_RT_CONTINUE = 0xFB, + MIDIST_RT_STOP = 0xFC, + /* not defined: 0xFD, */ + MIDIST_RT_ACTSENS = 0xFE, + MIDIST_SYSRESET = 0xFF, ///< only occurs in realtime data + MIDIST_SMF_META = 0xFF, ///< only occurs in SMF data +}; + +/** + * MIDI controller numbers. + * Complete list per General MIDI, missing values are not defined. + */ +enum MidiController { + /* Standard continuous controllers (MSB control) */ + MIDICT_BANKSELECT = 0, + MIDICT_MODWHEEL = 1, + MIDICT_BREATH = 2, + MIDICT_FOOT = 4, + MIDICT_PORTAMENTO = 5, + MIDICT_DATAENTRY = 6, + MIDICT_CHANVOLUME = 7, + MIDICT_BALANCE = 8, + MIDICT_PAN = 10, + MIDICT_EXPRESSION = 11, + MIDICT_EFFECT1 = 12, + MIDICT_EFFECT2 = 13, + MIDICT_GENERAL1 = 16, + MIDICT_GENERAL2 = 17, + MIDICT_GENERAL3 = 18, + MIDICT_GENERAL4 = 19, + /* Offset from MSB to LSB of continuous controllers */ + MIDICTOFS_HIGHRES = 32, + /* Stanard continuous controllers (LSB control) */ + MIDICT_BANKSELECT_LO = MIDICTOFS_HIGHRES + MIDICT_BANKSELECT, + MIDICT_MODWHEEL_LO = MIDICTOFS_HIGHRES + MIDICT_MODWHEEL, + MIDICT_BREATH_LO = MIDICTOFS_HIGHRES + MIDICT_BREATH, + MIDICT_FOOT_LO = MIDICTOFS_HIGHRES + MIDICT_FOOT, + MIDICT_PORTAMENTO_LO = MIDICTOFS_HIGHRES + MIDICT_PORTAMENTO, + MIDICT_DATAENTRY_LO = MIDICTOFS_HIGHRES + MIDICT_DATAENTRY, + MIDICT_CHANVOLUME_LO = MIDICTOFS_HIGHRES + MIDICT_CHANVOLUME, + MIDICT_BALANCE_LO = MIDICTOFS_HIGHRES + MIDICT_BALANCE, + MIDICT_PAN_LO = MIDICTOFS_HIGHRES + MIDICT_PAN, + MIDICT_EXPRESSION_LO = MIDICTOFS_HIGHRES + MIDICT_EXPRESSION, + MIDICT_EFFECT1_LO = MIDICTOFS_HIGHRES + MIDICT_EFFECT1, + MIDICT_EFFECT2_LO = MIDICTOFS_HIGHRES + MIDICT_EFFECT2, + MIDICT_GENERAL1_LO = MIDICTOFS_HIGHRES + MIDICT_GENERAL1, + MIDICT_GENERAL2_LO = MIDICTOFS_HIGHRES + MIDICT_GENERAL2, + MIDICT_GENERAL3_LO = MIDICTOFS_HIGHRES + MIDICT_GENERAL3, + MIDICT_GENERAL4_LO = MIDICTOFS_HIGHRES + MIDICT_GENERAL4, + /* Switch controllers */ + MIDICT_SUSTAINSW = 64, + MIDICT_PORTAMENTOSW = 65, + MIDICT_SOSTENUTOSW = 66, + MIDICT_SOFTPEDALSW = 67, + MIDICT_LEGATOSW = 68, + MIDICT_HOLD2SW = 69, + /* Standard low-resolution controllers */ + MIDICT_SOUND1 = 70, + MIDICT_SOUND2 = 71, + MIDICT_SOUND3 = 72, + MIDICT_SOUND4 = 73, + MIDICT_SOUND5 = 74, + MIDICT_SOUND6 = 75, + MIDICT_SOUND7 = 76, + MIDICT_SOUND8 = 77, + MIDICT_SOUND9 = 78, + MIDICT_SOUND10 = 79, + MIDICT_GENERAL5 = 80, + MIDICT_GENERAL6 = 81, + MIDICT_GENERAL7 = 82, + MIDICT_GENERAL8 = 83, + MIDICT_PORTAMENTOCTL = 84, + MIDICT_PRF_HIGHRESVEL = 88, + MIDICT_EFFECTS1 = 91, + MIDICT_EFFECTS2 = 92, + MIDICT_EFFECTS3 = 93, + MIDICT_EFFECTS4 = 94, + MIDICT_EFFECTS5 = 95, + /* Registered/unregistered parameters control */ + MIDICT_DATA_INCREMENT = 96, + MIDICT_DATA_DECREMENT = 97, + MIDICT_NRPN_SELECT_LO = 98, + MIDICT_NRPN_SELECT_HI = 99, + MIDICT_RPN_SELECT_LO = 100, + MIDICT_RPN_SELECT_HI = 101, + /* Channel mode messages */ + MIDICT_MODE_ALLSOUNDOFF = 120, + MIDICT_MODE_RESETALLCTRL = 121, + MIDICT_MODE_LOCALCTL = 122, + MIDICT_MODE_ALLNOTESOFF = 123, + MIDICT_MODE_OMNI_OFF = 124, + MIDICT_MODE_OMNI_ON = 125, + MIDICT_MODE_MONO = 126, + MIDICT_MODE_POLY = 127, +}; + +#endif /* MUSIC_MIDI_H */ diff --git a/src/music/midifile.cpp b/src/music/midifile.cpp new file mode 100644 index 0000000000..91f83c529d --- /dev/null +++ b/src/music/midifile.cpp @@ -0,0 +1,1127 @@ +/* $Id$ */ + +/* +* 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 . +*/ + +/* @file midifile.cpp Parser for standard MIDI files */ + +#include "midifile.hpp" +#include "../fileio_func.h" +#include "../fileio_type.h" +#include "../string_func.h" +#include "../core/endian_func.hpp" +#include "../base_media_base.h" +#include "midi.h" +#include + +#include "../console_func.h" +#include "../console_internal.h" + + +/* SMF reader based on description at: http://www.somascape.org/midi/tech/mfile.html */ + + +static MidiFile *_midifile_instance = NULL; + +/** + * Owning byte buffer readable as a stream. + * RAII-compliant to make teardown in error situations easier. + */ +class ByteBuffer { + byte *buf; + size_t buflen; + size_t pos; +public: + /** + * Construct buffer from data in a file. + * If file does not have sufficient bytes available, the object is constructed + * in an error state, that causes all further function calls to fail. + * @param file file to read from at current position + * @param len number of bytes to read + */ + ByteBuffer(FILE *file, size_t len) + { + this->buf = MallocT(len); + if (fread(this->buf, 1, len, file) == len) { + this->buflen = len; + this->pos = 0; + } else { + /* invalid state */ + this->buflen = 0; + } + } + + /** + * Destructor, frees the buffer. + */ + ~ByteBuffer() + { + free(this->buf); + } + + /** + * Return whether the buffer was constructed successfully. + * @return true is the buffer contains data + */ + bool IsValid() const + { + return this->buflen > 0; + } + + /** + * Return whether reading has reached the end of the buffer. + * @return true if there are no more bytes available to read + */ + bool IsEnd() const + { + return this->pos >= this->buflen; + } + + /** + * Read a single byte from the buffer. + * @param[out] b returns the read value + * @return true if a byte was available for reading + */ + bool ReadByte(byte &b) + { + if (this->IsEnd()) return false; + b = this->buf[this->pos++]; + return true; + } + + /** + * Read a MIDI file variable length value. + * Each byte encodes 7 bits of the value, most-significant bits are encoded first. + * If the most significant bit in a byte is set, there are further bytes encoding the value. + * @param[out] res returns the read value + * @return true if there was data available + */ + bool ReadVariableLength(uint32 &res) + { + res = 0; + byte b = 0; + do { + if (this->IsEnd()) return false; + b = this->buf[this->pos++]; + res = (res << 7) | (b & 0x7F); + } while (b & 0x80); + return true; + } + + /** + * Read bytes into a buffer. + * @param[out] dest buffer to copy info + * @param length number of bytes to read + * @return true if the requested number of bytes were available + */ + bool ReadBuffer(byte *dest, size_t length) + { + if (this->IsEnd()) return false; + if (this->buflen - this->pos < length) return false; + memcpy(dest, this->buf + this->pos, length); + this->pos += length; + return true; + } + + /** + * Skip over a number of bytes in the buffer. + * @param count number of bytes to skip over + * @return true if there were enough bytes available + */ + bool Skip(size_t count) + { + if (this->IsEnd()) return false; + if (this->buflen - this->pos < count) return false; + this->pos += count; + return true; + } + + /** + * Go a number of bytes back to re-read. + * @param count number of bytes to go back + * @return true if at least count bytes had been read previously + */ + bool Rewind(size_t count) + { + if (count > this->pos) return false; + this->pos -= count; + return true; + } +}; + +static bool ReadTrackChunk(FILE *file, MidiFile &target) +{ + byte buf[4]; + + const byte magic[] = { 'M', 'T', 'r', 'k' }; + if (fread(buf, sizeof(magic), 1, file) != 1) { + return false; + } + if (memcmp(magic, buf, sizeof(magic)) != 0) { + return false; + } + + /* Read chunk length and then the whole chunk */ + uint32 chunk_length; + if (fread(&chunk_length, 1, 4, file) != 4) { + return false; + } + chunk_length = FROM_BE32(chunk_length); + + ByteBuffer chunk(file, chunk_length); + if (!chunk.IsValid()) { + return false; + } + + target.blocks.push_back(MidiFile::DataBlock()); + MidiFile::DataBlock *block = &target.blocks.back(); + + byte last_status = 0; + bool running_sysex = false; + while (!chunk.IsEnd()) { + /* Read deltatime for event, start new block */ + uint32 deltatime = 0; + if (!chunk.ReadVariableLength(deltatime)) { + return false; + } + if (deltatime > 0) { + target.blocks.push_back(MidiFile::DataBlock(block->ticktime + deltatime)); + block = &target.blocks.back(); + } + + /* Read status byte */ + byte status; + if (!chunk.ReadByte(status)) { + return false; + } + + if ((status & 0x80) == 0) { + /* High bit not set means running status message, status is same as last + * convert to explicit status */ + chunk.Rewind(1); + status = last_status; + goto running_status; + } else if ((status & 0xF0) != 0xF0) { + /* Regular channel message */ + last_status = status; + running_status: + byte *data; + switch (status & 0xF0) { + case MIDIST_NOTEOFF: + case MIDIST_NOTEON: + case MIDIST_POLYPRESS: + case MIDIST_CONTROLLER: + case MIDIST_PITCHBEND: + /* 3 byte messages */ + data = block->data.Append(3); + data[0] = status; + if (!chunk.ReadBuffer(&data[1], 2)) { + return false; + } + break; + case MIDIST_PROGCHG: + case MIDIST_CHANPRESS: + /* 2 byte messages */ + data = block->data.Append(2); + data[0] = status; + if (!chunk.ReadByte(data[1])) { + return false; + } + break; + default: + NOT_REACHED(); + } + } else if (status == MIDIST_SMF_META) { + /* Meta event, read event type byte and data length */ + if (!chunk.ReadByte(buf[0])) { + return false; + } + uint32 length = 0; + if (!chunk.ReadVariableLength(length)) { + return false; + } + switch (buf[0]) { + case 0x2F: + /* end of track, no more data (length != 0 is illegal) */ + return (length == 0); + case 0x51: + /* tempo change */ + if (length != 3) return false; + if (!chunk.ReadBuffer(buf, 3)) return false; + target.tempos.push_back(MidiFile::TempoChange(block->ticktime, buf[0] << 16 | buf[1] << 8 | buf[2])); + break; + default: + /* unimportant meta event, skip over it */ + if (!chunk.Skip(length)) { + return false; + } + break; + } + } else if (status == MIDIST_SYSEX || (status == MIDIST_SMF_ESCAPE && running_sysex)) { + /* System exclusive message */ + uint32 length = 0; + if (!chunk.ReadVariableLength(length)) { + return false; + } + byte *data = block->data.Append(length + 1); + data[0] = 0xF0; + if (!chunk.ReadBuffer(data + 1, length)) { + return false; + } + if (data[length] != 0xF7) { + /* Engage Casio weirdo mode - convert to normal sysex */ + running_sysex = true; + *block->data.Append() = 0xF7; + } else { + running_sysex = false; + } + } else if (status == MIDIST_SMF_ESCAPE) { + /* Escape sequence */ + uint32 length = 0; + if (!chunk.ReadVariableLength(length)) { + return false; + } + byte *data = block->data.Append(length); + if (!chunk.ReadBuffer(data, length)) { + return false; + } + } else { + /* Messages undefined in standard midi files: + * 0xF1 - MIDI time code quarter frame + * 0xF2 - Song position pointer + * 0xF3 - Song select + * 0xF4 - undefined/reserved + * 0xF5 - undefined/reserved + * 0xF6 - Tune request for analog synths + * 0xF8..0xFE - System real-time messages + */ + return false; + } + } + + NOT_REACHED(); +} + +template +bool TicktimeAscending(const T &a, const T &b) +{ + return a.ticktime < b.ticktime; +} + +static bool FixupMidiData(MidiFile &target) +{ + /* Sort all tempo changes and events */ + std::sort(target.tempos.begin(), target.tempos.end(), TicktimeAscending); + std::sort(target.blocks.begin(), target.blocks.end(), TicktimeAscending); + + if (target.tempos.size() == 0) { + /* No tempo information, assume 120 bpm (500,000 microseconds per beat */ + target.tempos.push_back(MidiFile::TempoChange(0, 500000)); + } + /* Add sentinel tempo at end */ + target.tempos.push_back(MidiFile::TempoChange(UINT32_MAX, 0)); + + /* Merge blocks with identical tick times */ + std::vector merged_blocks; + uint32 last_ticktime = 0; + for (size_t i = 0; i < target.blocks.size(); i++) { + MidiFile::DataBlock &block = target.blocks[i]; + if (block.data.Length() == 0) { + continue; + } else if (block.ticktime > last_ticktime || merged_blocks.size() == 0) { + merged_blocks.push_back(block); + last_ticktime = block.ticktime; + } else { + byte *datadest = merged_blocks.back().data.Append(block.data.Length()); + memcpy(datadest, block.data.Begin(), block.data.Length()); + } + } + std::swap(merged_blocks, target.blocks); + + /* Annotate blocks with real time */ + last_ticktime = 0; + uint32 last_realtime = 0; + size_t cur_tempo = 0, cur_block = 0; + while (cur_block < target.blocks.size()) { + MidiFile::DataBlock &block = target.blocks[cur_block]; + MidiFile::TempoChange &tempo = target.tempos[cur_tempo]; + MidiFile::TempoChange &next_tempo = target.tempos[cur_tempo+1]; + if (block.ticktime <= next_tempo.ticktime) { + /* block is within the current tempo */ + int64 tickdiff = block.ticktime - last_ticktime; + last_ticktime = block.ticktime; + last_realtime += uint32(tickdiff * tempo.tempo / target.tickdiv); + block.realtime = last_realtime; + cur_block++; + } else { + /* tempo change occurs before this block */ + int64 tickdiff = next_tempo.ticktime - last_ticktime; + last_ticktime = next_tempo.ticktime; + last_realtime += uint32(tickdiff * tempo.tempo / target.tickdiv); // current tempo until the tempo change + cur_tempo++; + } + } + + return true; +} + +/** + * Read the header of a standard MIDI file. + * @param[in] filename name of file to read from + * @param[out] header filled with data read + * @return true if the file could be opened and contained a header with correct format + */ +bool MidiFile::ReadSMFHeader(const char *filename, SMFHeader &header) +{ + FILE *file = FioFOpenFile(filename, "rb", Subdirectory::BASESET_DIR); + if (!file) return false; + bool result = ReadSMFHeader(file, header); + FioFCloseFile(file); + return result; +} + +/** + * Read the header of a standard MIDI file. + * The function will consume 14 bytes from the current file pointer position. + * @param[in] file open file to read from (should be in binary mode) + * @param[out] header filled with data read + * @return true if a header in correct format could be read from the file + */ +bool MidiFile::ReadSMFHeader(FILE *file, SMFHeader &header) +{ + /* Try to read header, fixed size */ + byte buffer[14]; + if (fread(buffer, sizeof(buffer), 1, file) != 1) { + return false; + } + + /* Check magic, 'MThd' followed by 4 byte length indicator (always = 6 in SMF) */ + const byte magic[] = { 'M', 'T', 'h', 'd', 0x00, 0x00, 0x00, 0x06 }; + if (MemCmpT(buffer, magic, sizeof(magic)) != 0) { + return false; + } + + /* Read the parameters of the file */ + header.format = (buffer[8] << 8) | buffer[9]; + header.tracks = (buffer[10] << 8) | buffer[11]; + header.tickdiv = (buffer[12] << 8) | buffer[13]; + return true; +} + +/** + * Load a standard MIDI file. + * @param filename name of the file to load + * @returns true if loaded was successful + */ +bool MidiFile::LoadFile(const char *filename) +{ + _midifile_instance = this; + + this->blocks.clear(); + this->tempos.clear(); + this->tickdiv = 0; + + bool success = false; + FILE *file = FioFOpenFile(filename, "rb", Subdirectory::BASESET_DIR); + if (file == NULL) return false; + + SMFHeader header; + if (!ReadSMFHeader(file, header)) goto cleanup; + + /* Only format 0 (single-track) and format 1 (multi-track single-song) are accepted for now */ + if (header.format != 0 && header.format != 1) goto cleanup; + /* Doesn't support SMPTE timecode files */ + if ((header.tickdiv & 0x8000) != 0) goto cleanup; + + this->tickdiv = header.tickdiv; + + for (; header.tracks > 0; header.tracks--) { + if (!ReadTrackChunk(file, *this)) { + goto cleanup; + } + } + + success = FixupMidiData(*this); + +cleanup: + FioFCloseFile(file); + return success; +} + + +/** + * Decoder for "MPS MIDI" format data. + * This format for MIDI music is also used in a few other Microprose games contemporary with Transport Tycoon. + * + * The song data are usually packed inside a CAT file, with one CAT chunk per song. The song titles are used as names for the CAT chunks. + * + * Unlike the Standard MIDI File format, which is based on the IFF structure, the MPS MIDI format is best described as two linked lists of sub-tracks, + * the first list contains a number of reusable "segments", and the second list contains the "master tracks". Each list is prefixed with a byte + * giving the number of elements in the list, and the actual list is just a byte count (BE16 format) for the segment/track followed by the actual data, + * there is no index as such, so the entire data must be seeked through to build an index. + * + * The actual MIDI data inside each track is almost standard MIDI, prefixing every event with a delay, encoded using the same variable-length format + * used in SMF. A few status codes have changed meaning in MPS MIDI: 0xFE changes control from master track to a segment, 0xFD returns from a segment + * to the master track, and 0xFF is used to end the song. (In Standard MIDI all those values must only occur in real-time data.) + * + * As implemented in the original decoder, there is no support for recursively calling segments from segments, i.e. code 0xFE must only occur in + * a master track, and code 0xFD must only occur in a segment. There are no checks made for this, it's assumed that the only input data will ever + * be the original game music, not music from other games, or new productions. + * + * Additionally, some program change and controller events are given special meaning, see comments in the code. + */ +struct MpsMachine { + /** Starting parameter and playback status for one channel/track */ + struct Channel { + byte cur_program; ///< program selected, used for velocity scaling (lookup into programvelocities array) + byte running_status; ///< last midi status code seen + uint16 delay; ///< frames until next command + uint32 playpos; ///< next byte to play this channel from + uint32 startpos; ///< start position of master track + uint32 returnpos; ///< next return position after playing a segment + Channel() : cur_program(0xFF), running_status(0), delay(0), playpos(0), startpos(0), returnpos(0) { } + }; + Channel channels[16]; ///< playback status for each MIDI channel + std::vector segments; ///< pointers into songdata to repeatable data segments + int16 tempo_ticks; ///< ticker that increments when playing a frame, decrements before playing a frame + int16 current_tempo; ///< threshold for actually playing a frame + int16 initial_tempo; ///< starting tempo of song + bool shouldplayflag; ///< not-end-of-song flag + + static const int TEMPO_RATE; + static const byte programvelocities[128]; + + const byte *songdata; ///< raw data array + size_t songdatalen; ///< length of song data + MidiFile ⌖ ///< recipient of data + + /** Overridden MIDI status codes used in the data format */ + enum MpsMidiStatus { + MPSMIDIST_SEGMENT_RETURN = 0xFD, ///< resume playing master track from stored position + MPSMIDIST_SEGMENT_CALL = 0xFE, ///< store current position of master track playback, and begin playback of a segment + MPSMIDIST_ENDSONG = 0xFF, ///< immediately end the song + }; + + static void AddMidiData(MidiFile::DataBlock &block, byte b1, byte b2) + { + *block.data.Append() = b1; + *block.data.Append() = b2; + } + static void AddMidiData(MidiFile::DataBlock &block, byte b1, byte b2, byte b3) + { + *block.data.Append() = b1; + *block.data.Append() = b2; + *block.data.Append() = b3; + } + + /** + * Construct a TTD DOS music format decoder. + * @param data Buffer of song data from CAT file, ownership remains with caller + * @param length Length of the data buffer in bytes + * @param target MidiFile object to add decoded data to + */ + MpsMachine(const byte *data, size_t length, MidiFile &target) + : songdata(data), songdatalen(length), target(target) + { + uint32 pos = 0; + int loopmax; + int loopidx; + + /* First byte is the initial "tempo" */ + this->initial_tempo = this->songdata[pos++]; + + /* Next byte is a count of callable segments */ + loopmax = this->songdata[pos++]; + for (loopidx = 0; loopidx < loopmax; loopidx++) { + /* Segments form a linked list in the stream, + * first two bytes in each is an offset to the next. + * Two bytes between offset to next and start of data + * are unaccounted for. */ + this->segments.push_back(pos + 4); + pos += FROM_LE16(*(const int16 *)(this->songdata + pos)); + } + + /* After segments follows list of master tracks for each channel, + * also prefixed with a byte counting actual tracks. */ + loopmax = this->songdata[pos++]; + for (loopidx = 0; loopidx < loopmax; loopidx++) { + /* Similar structure to segments list, but also has + * the MIDI channel number as a byte before the offset + * to next track. */ + byte ch = this->songdata[pos++]; + this->channels[ch].startpos = pos + 4; + pos += FROM_LE16(*(const int16 *)(this->songdata + pos)); + } + } + + /** + * Read an SMF-style variable length value (note duration) from songdata. + * @param pos Position to read from, updated to point to next byte after the value read + * @return Value read from data stream + */ + uint16 ReadVariableLength(uint32 &pos) + { + byte b = 0; + uint16 res = 0; + do { + b = this->songdata[pos++]; + res = (res << 7) + (b & 0x7F); + } while (b & 0x80); + return res; + } + + /** + * Prepare for playback from the beginning. Resets the song pointer for every track to the beginning. + */ + void RestartSong() + { + for (int ch = 0; ch < 16; ch++) { + Channel &chandata = this->channels[ch]; + if (chandata.startpos != 0) { + /* Active track, set position to beginning */ + chandata.playpos = chandata.startpos; + chandata.delay = this->ReadVariableLength(chandata.playpos); + } else { + /* Inactive track, mark as such */ + chandata.playpos = 0; + chandata.delay = 0; + } + } + } + + /** + * Play one frame of data from one channel + */ + uint16 PlayChannelFrame(MidiFile::DataBlock &outblock, int channel) + { + uint16 newdelay = 0; + byte b1, b2; + Channel &chandata = this->channels[channel]; + + do { + /* Read command/status byte */ + b1 = this->songdata[chandata.playpos++]; + + /* Command 0xFE, call segment from master track */ + if (b1 == MPSMIDIST_SEGMENT_CALL) { + b1 = this->songdata[chandata.playpos++]; + chandata.returnpos = chandata.playpos; + chandata.playpos = this->segments[b1]; + newdelay = this->ReadVariableLength(chandata.playpos); + if (newdelay == 0) { + continue; + } + return newdelay; + } + + /* Command 0xFD, return from segment to master track */ + if (b1 == MPSMIDIST_SEGMENT_RETURN) { + chandata.playpos = chandata.returnpos; + chandata.returnpos = 0; + newdelay = this->ReadVariableLength(chandata.playpos); + if (newdelay == 0) { + continue; + } + return newdelay; + } + + /* Command 0xFF, end of song */ + if (b1 == MPSMIDIST_ENDSONG) { + this->shouldplayflag = false; + return 0; + } + + /* Regular MIDI channel message status byte */ + if (b1 >= 0x80) { + /* Save the status byte as running status for the channel + * and read another byte for first parameter to command */ + chandata.running_status = b1; + b1 = this->songdata[chandata.playpos++]; + } + + switch (chandata.running_status & 0xF0) { + case MIDIST_NOTEOFF: + case MIDIST_NOTEON: + b2 = this->songdata[chandata.playpos++]; + if (b2 != 0) { + /* Note on, read velocity and scale according to rules */ + int16 velocity; + if (channel == 9) { + /* Percussion channel, fixed velocity scaling not in the table */ + velocity = (int16)b2 * 0x50; + } else { + /* Regular channel, use scaling from table */ + velocity = b2 * programvelocities[chandata.cur_program]; + } + b2 = (velocity / 128) & 0x00FF; + AddMidiData(outblock, MIDIST_NOTEON + channel, b1, b2); + } else { + /* Note off */ + AddMidiData(outblock, MIDIST_NOTEON + channel, b1, 0); + } + break; + case MIDIST_CONTROLLER: + b2 = this->songdata[chandata.playpos++]; + if (b1 == MIDICT_MODE_MONO) { + /* Unknown what the purpose of this is. + * Occurs in "Can't get There from Here" and in "Aliens Ate my Railway" a few times each. + * Possibly intended to give hints to other (non-GM) music drivers decoding the song. + */ + break; + } else if (b1 == 0) { + /* Standard MIDI controller 0 is "bank select", override meaning to change tempo. + * This is not actually used in any of the original songs. */ + if (b2 != 0) { + this->current_tempo = ((int)b2) * 48 / 60; + } + break; + } else if (b1 == MIDICT_EFFECTS1) { + /* Override value of this controller, default mapping is Reverb Send Level according to MMA RP-023. + * Unknown what the purpose of this particular value is. */ + b2 = 30; + } + AddMidiData(outblock, MIDIST_CONTROLLER + channel, b1, b2); + break; + case MIDIST_PROGCHG: + if (b1 == 0x7E) { + /* Program change to "Applause" is originally used + * to cause the song to loop, but that gets handled + * separately in the output driver here. + * Just end the song. */ + this->shouldplayflag = false; + break; + } + /* Used for note velocity scaling lookup */ + chandata.cur_program = b1; + /* Two programs translated to a third, this is likely to + * provide three different velocity scalings of "brass". */ + if (b1 == 0x57 || b1 == 0x3F) { + b1 = 0x3E; + } + AddMidiData(outblock, MIDIST_PROGCHG + channel, b1); + break; + case MIDIST_PITCHBEND: + b2 = this->songdata[chandata.playpos++]; + AddMidiData(outblock, MIDIST_PITCHBEND + channel, b1, b2); + break; + default: + break; + } + + newdelay = this->ReadVariableLength(chandata.playpos); + } while (newdelay == 0); + + return newdelay; + } + + /** + * Play one frame of data into a block. + */ + bool PlayFrame(MidiFile::DataBlock &block) + { + /* Update tempo/ticks counter */ + this->tempo_ticks -= this->current_tempo; + if (this->tempo_ticks > 0) { + return true; + } + this->tempo_ticks += TEMPO_RATE; + + /* Look over all channels, play those active */ + for (int ch = 0; ch < 16; ch++) { + Channel &chandata = this->channels[ch]; + if (chandata.playpos != 0) { + if (chandata.delay == 0) { + chandata.delay = this->PlayChannelFrame(block, ch); + } + chandata.delay--; + } + } + + return this->shouldplayflag; + } + + /** + * Perform playback of whole song. + */ + bool PlayInto() + { + /* Tempo seems to be handled as TEMPO_RATE = 148 ticks per second. + * Use this as the tickdiv, and define the tempo to be one second (1M microseconds) per tickdiv. + * MIDI software loading exported files will show a bogus tempo, but playback will be correct. */ + this->target.tickdiv = TEMPO_RATE; + this->target.tempos.push_back(MidiFile::TempoChange(0, 1000000)); + + /* Initialize playback simulation */ + this->RestartSong(); + this->shouldplayflag = true; + this->current_tempo = (int32)this->initial_tempo * 24 / 60; + this->tempo_ticks = this->current_tempo; + + /* Always reset percussion channel to program 0 */ + this->target.blocks.push_back(MidiFile::DataBlock()); + AddMidiData(this->target.blocks.back(), MIDIST_PROGCHG+9, 0x00); + + /* Technically should be an endless loop, but having + * a maximum (about 10 minutes) avoids getting stuck, + * in case of corrupted data. */ + for (uint32 tick = 0; tick < 100000; tick+=1) { + this->target.blocks.push_back(MidiFile::DataBlock()); + auto &block = this->target.blocks.back(); + block.ticktime = tick; + if (!this->PlayFrame(block)) { + break; + } + } + return true; + } +}; +/** Frames/ticks per second for music playback */ +const int MpsMachine::TEMPO_RATE = 148; +/** Base note velocities for various GM programs */ +const byte MpsMachine::programvelocities[128] = { + 100, 100, 100, 100, 100, 90, 100, 100, 100, 100, 100, 90, 100, 100, 100, 100, + 100, 100, 85, 100, 100, 100, 100, 100, 100, 100, 100, 100, 90, 90, 110, 80, + 100, 100, 100, 90, 70, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 90, 100, 100, 100, 100, 100, 100, 120, 100, 100, 100, 120, 100, 127, + 100, 100, 90, 100, 100, 100, 100, 100, 100, 95, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 115, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, +}; + +/** + * Create MIDI data from song data for the original Microprose music drivers. + * @param data pointer to block of data + * @param length size of data in bytes + * @return true if the data could be loaded + */ +bool MidiFile::LoadMpsData(const byte *data, size_t length) +{ + _midifile_instance = this; + + MpsMachine machine(data, length, *this); + return machine.PlayInto() && FixupMidiData(*this); +} + +bool MidiFile::LoadSong(const MusicSongInfo &song) +{ + switch (song.filetype) { + case MTT_STANDARDMIDI: + return this->LoadFile(song.filename); + case MTT_MPSMIDI: + { + size_t songdatalen = 0; + byte *songdata = GetMusicCatEntryData(song.filename, song.cat_index, songdatalen); + if (songdata != NULL) { + bool result = this->LoadMpsData(songdata, songdatalen); + free(songdata); + return result; + } else { + return false; + } + } + default: + NOT_REACHED(); + } +} + +/** + * Move data from other to this, and clears other. + * @param other object containing loaded data to take over + */ +void MidiFile::MoveFrom(MidiFile &other) +{ + std::swap(this->blocks, other.blocks); + std::swap(this->tempos, other.tempos); + this->tickdiv = other.tickdiv; + + _midifile_instance = this; + + other.blocks.clear(); + other.tempos.clear(); + other.tickdiv = 0; +} + +static void WriteVariableLen(FILE *f, uint32 value) +{ + if (value < 0x7F) { + byte tb = value; + fwrite(&tb, 1, 1, f); + } else if (value < 0x3FFF) { + byte tb[2]; + tb[1] = value & 0x7F; value >>= 7; + tb[0] = (value & 0x7F) | 0x80; value >>= 7; + fwrite(tb, 1, sizeof(tb), f); + } else if (value < 0x1FFFFF) { + byte tb[3]; + tb[2] = value & 0x7F; value >>= 7; + tb[1] = (value & 0x7F) | 0x80; value >>= 7; + tb[0] = (value & 0x7F) | 0x80; value >>= 7; + fwrite(tb, 1, sizeof(tb), f); + } else if (value < 0x0FFFFFFF) { + byte tb[4]; + tb[3] = value & 0x7F; value >>= 7; + tb[2] = (value & 0x7F) | 0x80; value >>= 7; + tb[1] = (value & 0x7F) | 0x80; value >>= 7; + tb[0] = (value & 0x7F) | 0x80; value >>= 7; + fwrite(tb, 1, sizeof(tb), f); + } +} + +/** + * Write a Standard MIDI File containing the decoded music. + * @param filename Name of file to write to + * @return True if the file was written to completion + */ +bool MidiFile::WriteSMF(const char *filename) +{ + FILE *f = FioFOpenFile(filename, "wb", Subdirectory::NO_DIRECTORY); + if (!f) { + return false; + } + + /* SMF header */ + const byte fileheader[] = { + 'M', 'T', 'h', 'd', // block name + 0x00, 0x00, 0x00, 0x06, // BE32 block length, always 6 bytes + 0x00, 0x00, // writing format 0 (all in one track) + 0x00, 0x01, // containing 1 track (BE16) + (byte)(this->tickdiv >> 8), (byte)this->tickdiv, // tickdiv in BE16 + }; + fwrite(fileheader, sizeof(fileheader), 1, f); + + /* Track header */ + const byte trackheader[] = { + 'M', 'T', 'r', 'k', // block name + 0, 0, 0, 0, // BE32 block length, unknown at this time + }; + fwrite(trackheader, sizeof(trackheader), 1, f); + /* Determine position to write the actual track block length at */ + size_t tracksizepos = ftell(f) - 4; + + /* Write blocks in sequence */ + uint32 lasttime = 0; + size_t nexttempoindex = 0; + for (size_t bi = 0; bi < this->blocks.size(); bi++) { + DataBlock &block = this->blocks[bi]; + TempoChange &nexttempo = this->tempos[nexttempoindex]; + + uint32 timediff = block.ticktime - lasttime; + + /* Check if there is a tempo change before this block */ + if (nexttempo.ticktime < block.ticktime) { + timediff = nexttempo.ticktime - lasttime; + } + + /* Write delta time for block */ + lasttime += timediff; + bool needtime = false; + WriteVariableLen(f, timediff); + + /* Write tempo change if there is one */ + if (nexttempo.ticktime <= block.ticktime) { + byte tempobuf[6] = { MIDIST_SMF_META, 0x51, 0x03, 0, 0, 0 }; + tempobuf[3] = (nexttempo.tempo & 0x00FF0000) >> 16; + tempobuf[4] = (nexttempo.tempo & 0x0000FF00) >> 8; + tempobuf[5] = (nexttempo.tempo & 0x000000FF); + fwrite(tempobuf, sizeof(tempobuf), 1, f); + nexttempoindex++; + needtime = true; + } + /* If a tempo change occurred between two blocks, rather than + * at start of this one, start over with delta time for the block. */ + if (nexttempo.ticktime < block.ticktime) { + /* Start loop over at same index */ + bi--; + continue; + } + + /* Write each block data command */ + byte *dp = block.data.Begin(); + while (dp < block.data.End()) { + /* Always zero delta time inside blocks */ + if (needtime) { + fputc(0, f); + } + needtime = true; + + /* Check message type and write appropriate number of bytes */ + switch (*dp & 0xF0) { + case MIDIST_NOTEOFF: + case MIDIST_NOTEON: + case MIDIST_POLYPRESS: + case MIDIST_CONTROLLER: + case MIDIST_PITCHBEND: + fwrite(dp, 1, 3, f); + dp += 3; + continue; + case MIDIST_PROGCHG: + case MIDIST_CHANPRESS: + fwrite(dp, 1, 2, f); + dp += 2; + continue; + } + + /* Sysex needs to measure length and write that as well */ + if (*dp == MIDIST_SYSEX) { + fwrite(dp, 1, 1, f); + dp++; + byte *sysexend = dp; + while (*sysexend != MIDIST_ENDSYSEX) sysexend++; + ptrdiff_t sysexlen = sysexend - dp; + WriteVariableLen(f, sysexlen); + fwrite(dp, 1, sysexend - dp, f); + dp = sysexend; + continue; + } + + /* Fail for any other commands */ + fclose(f); + return false; + } + } + + /* End of track marker */ + static const byte track_end_marker[] = { 0x00, MIDIST_SMF_META, 0x2F, 0x00 }; + fwrite(&track_end_marker, sizeof(track_end_marker), 1, f); + + /* Fill out the RIFF block length */ + size_t trackendpos = ftell(f); + fseek(f, tracksizepos, SEEK_SET); + uint32 tracksize = (uint32)(trackendpos - tracksizepos - 4); // blindly assume we never produce files larger than 2 GB + tracksize = TO_BE32(tracksize); + fwrite(&tracksize, 4, 1, f); + + fclose(f); + return true; +} + +/** + * Get the name of a Standard MIDI File for a given song. + * For songs already in SMF format, just returns the original. + * Otherwise the song is converted, written to a temporary-ish file, and the written filename is returned. + * @param song Song definition to query + * @return Full filename string, empty string if failed + */ +std::string MidiFile::GetSMFFile(const MusicSongInfo &song) +{ + if (song.filetype == MTT_STANDARDMIDI) { + char filename[MAX_PATH]; + if (FioFindFullPath(filename, lastof(filename), Subdirectory::BASESET_DIR, song.filename)) { + return std::string(filename); + } else if (FioFindFullPath(filename, lastof(filename), Subdirectory::OLD_GM_DIR, song.filename)) { + return std::string(filename); + } else { + return std::string(); + } + } + + if (song.filetype != MTT_MPSMIDI) return std::string(); + + char basename[MAX_PATH]; + { + const char *fnstart = strrchr(song.filename, PATHSEPCHAR); + if (fnstart == NULL) { + fnstart = song.filename; + } else { + fnstart++; + } + + /* Remove all '.' characters from filename */ + char *wp = basename; + for (const char *rp = fnstart; *rp != '\0'; rp++) { + if (*rp != '.') *wp++ = *rp; + } + *wp++ = '\0'; + } + + char tempdirname[MAX_PATH]; + FioGetFullPath(tempdirname, lastof(tempdirname), Searchpath::SP_AUTODOWNLOAD_DIR, Subdirectory::BASESET_DIR, basename); + if (!AppendPathSeparator(tempdirname, lastof(tempdirname))) return std::string(); + FioCreateDirectory(tempdirname); + + char output_filename[MAX_PATH]; + seprintf(output_filename, lastof(output_filename), "%s%d.mid", tempdirname, song.cat_index); + + if (FileExists(output_filename)) { + /* If the file already exists, assume it's the correct decoded data */ + return std::string(output_filename); + } + + byte *data; + size_t datalen; + data = GetMusicCatEntryData(song.filename, song.cat_index, datalen); + if (data == NULL) return std::string(); + + MidiFile midifile; + if (!midifile.LoadMpsData(data, datalen)) { + free(data); + return std::string(); + } + free(data); + + if (midifile.WriteSMF(output_filename)) { + return std::string(output_filename); + } else { + return std::string(); + } +} + + +static bool CmdDumpSMF(byte argc, char *argv[]) +{ + if (argc == 0) { + IConsolePrint(CC_WARNING, "Write the current song to a Standard MIDI File. Usage: 'dumpsmf '"); + return true; + } + if (argc != 2) { + IConsolePrint(CC_WARNING, "You must specify a filename to write MIDI data to."); + return false; + } + + if (_midifile_instance == NULL) { + IConsolePrint(CC_ERROR, "There is no MIDI file loaded currently, make sure music is playing, and you're using a driver that works with raw MIDI."); + return false; + } + + char fnbuf[MAX_PATH] = { 0 }; + if (seprintf(fnbuf, lastof(fnbuf), "%s%s", FiosGetScreenshotDir(), argv[1]) >= (int)lengthof(fnbuf)) { + IConsolePrint(CC_ERROR, "Filename too long."); + return false; + } + IConsolePrintF(CC_INFO, "Dumping MIDI to: %s", fnbuf); + + if (_midifile_instance->WriteSMF(fnbuf)) { + IConsolePrint(CC_INFO, "File written successfully."); + return true; + } else { + IConsolePrint(CC_ERROR, "An error occurred writing MIDI file."); + return false; + } +} + +static void RegisterConsoleMidiCommands() +{ + static bool registered = false; + if (!registered) { + IConsoleCmdRegister("dumpsmf", CmdDumpSMF); + registered = true; + } +} + +MidiFile::MidiFile() +{ + RegisterConsoleMidiCommands(); +} + +MidiFile::~MidiFile() +{ + if (_midifile_instance == this) { + _midifile_instance = NULL; + } +} + diff --git a/src/music/midifile.hpp b/src/music/midifile.hpp new file mode 100644 index 0000000000..0016be86ca --- /dev/null +++ b/src/music/midifile.hpp @@ -0,0 +1,55 @@ +/* $Id$ */ + +/* +* 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 . +*/ + +/* @file midifile.hpp Parser for standard MIDI files */ + +#ifndef MUSIC_MIDIFILE_HPP +#define MUSIC_MIDIFILE_HPP + +#include "../stdafx.h" +#include "../core/smallvec_type.hpp" +#include "midi.h" +#include +#include + +struct MusicSongInfo; + +struct MidiFile { + struct DataBlock { + uint32 ticktime; ///< tick number since start of file this block should be triggered at + uint32 realtime; ///< real-time (microseconds) since start of file this block should be triggered at + SmallVector data; ///< raw midi data contained in block + DataBlock(uint32 _ticktime = 0) : ticktime(_ticktime) { } + }; + struct TempoChange { + uint32 ticktime; ///< tick number since start of file this tempo change occurs at + uint32 tempo; ///< new tempo in microseconds per tick + TempoChange(uint32 _ticktime, uint32 _tempo) : ticktime(_ticktime), tempo(_tempo) { } + }; + + std::vector blocks; ///< sequential time-annotated data of file, merged to a single track + std::vector tempos; ///< list of tempo changes in file + uint16 tickdiv; ///< ticks per quarter note + + MidiFile(); + ~MidiFile(); + + bool LoadFile(const char *filename); + bool LoadMpsData(const byte *data, size_t length); + bool LoadSong(const MusicSongInfo &song); + void MoveFrom(MidiFile &other); + + bool WriteSMF(const char *filename); + + static std::string GetSMFFile(const MusicSongInfo &song); + static bool ReadSMFHeader(const char *filename, SMFHeader &header); + static bool ReadSMFHeader(FILE *file, SMFHeader &header); +}; + +#endif /* MUSIC_MIDIFILE_HPP */ diff --git a/src/music/music_driver.hpp b/src/music/music_driver.hpp index be09d3ea2b..f4d3d7dd36 100644 --- a/src/music/music_driver.hpp +++ b/src/music/music_driver.hpp @@ -14,14 +14,16 @@ #include "../driver.h" +struct MusicSongInfo; + /** Driver for all music playback. */ class MusicDriver : public Driver { public: /** * Play a particular song. - * @param filename The name of file with the song to play. + * @param song The information for the song to play. */ - virtual void PlaySong(const char *filename) = 0; + virtual void PlaySong(const MusicSongInfo &song) = 0; /** * Stop playing the current song. diff --git a/src/music/null_m.h b/src/music/null_m.h index df9f7d80d5..51e1a06656 100644 --- a/src/music/null_m.h +++ b/src/music/null_m.h @@ -21,7 +21,7 @@ public: /* virtual */ void Stop() { } - /* virtual */ void PlaySong(const char *filename) { } + /* virtual */ void PlaySong(const MusicSongInfo &song) { } /* virtual */ void StopSong() { } diff --git a/src/music/os2_m.cpp b/src/music/os2_m.cpp index d7fb97d2d3..1689f00a64 100644 --- a/src/music/os2_m.cpp +++ b/src/music/os2_m.cpp @@ -12,6 +12,8 @@ #include "../stdafx.h" #include "../openttd.h" #include "os2_m.h" +#include "midifile.hpp" +#include "../base_media_base.h" #define INCL_DOS #define INCL_OS2MM @@ -49,11 +51,14 @@ static long CDECL MidiSendCommand(const char *cmd, ...) /** OS/2's music player's factory. */ static FMusicDriver_OS2 iFMusicDriver_OS2; -void MusicDriver_OS2::PlaySong(const char *filename) +void MusicDriver_OS2::PlaySong(const MusicSongInfo &song) { - MidiSendCommand("close all"); + std::string filename = MidiFile::GetSMFFile(song); - if (MidiSendCommand("open %s type sequencer alias song", filename) != 0) { + MidiSendCommand("close all"); + if (filename.empty()) return; + + if (MidiSendCommand("open %s type sequencer alias song", filename.c_str()) != 0) { return; } diff --git a/src/music/os2_m.h b/src/music/os2_m.h index f35e2fdcf6..ac7cd03197 100644 --- a/src/music/os2_m.h +++ b/src/music/os2_m.h @@ -21,7 +21,7 @@ public: /* virtual */ void Stop(); - /* virtual */ void PlaySong(const char *filename); + /* virtual */ void PlaySong(const MusicSongInfo &song); /* virtual */ void StopSong(); diff --git a/src/music/qtmidi.cpp b/src/music/qtmidi.cpp index 9bc6a61740..f8ab150e79 100644 --- a/src/music/qtmidi.cpp +++ b/src/music/qtmidi.cpp @@ -30,7 +30,9 @@ #include "../stdafx.h" #include "qtmidi.h" +#include "midifile.hpp" #include "../debug.h" +#include "../base_media_base.h" #define Rect OTTDRect #define Point OTTDPoint @@ -258,11 +260,14 @@ void MusicDriver_QtMidi::Stop() * * @param filename Path to a MIDI file. */ -void MusicDriver_QtMidi::PlaySong(const char *filename) +void MusicDriver_QtMidi::PlaySong(const MusicSongInfo &song) { if (!_quicktime_started) return; - DEBUG(driver, 2, "qtmidi: trying to play '%s'", filename); + std::string filename = MidiFile::GetSMFFile(song); + if (filename.empty()) return; + + DEBUG(driver, 2, "qtmidi: trying to play '%s'", filename.c_str()); switch (_quicktime_state) { case QT_STATE_PLAY: StopSong(); @@ -276,12 +281,12 @@ void MusicDriver_QtMidi::PlaySong(const char *filename) FALLTHROUGH; case QT_STATE_IDLE: - LoadMovieForMIDIFile(filename, &_quicktime_movie); + LoadMovieForMIDIFile(filename.c_str(), &_quicktime_movie); SetMovieVolume(_quicktime_movie, VOLUME); StartMovie(_quicktime_movie); _quicktime_state = QT_STATE_PLAY; } - DEBUG(driver, 3, "qtmidi: playing '%s'", filename); + DEBUG(driver, 3, "qtmidi: playing '%s'", filename.c_str()); } diff --git a/src/music/qtmidi.h b/src/music/qtmidi.h index f0e17086e4..32163db939 100644 --- a/src/music/qtmidi.h +++ b/src/music/qtmidi.h @@ -20,7 +20,7 @@ public: /* virtual */ void Stop(); - /* virtual */ void PlaySong(const char *filename); + /* virtual */ void PlaySong(const MusicSongInfo &song); /* virtual */ void StopSong(); diff --git a/src/music/win32_m.cpp b/src/music/win32_m.cpp index fff0376a09..a32318db12 100644 --- a/src/music/win32_m.cpp +++ b/src/music/win32_m.cpp @@ -15,170 +15,407 @@ #include #include #include "../os/windows/win32.h" +#include "../debug.h" +#include "midifile.hpp" +#include "midi.h" +#include "../base_media_base.h" #include "../safeguards.h" +struct PlaybackSegment { + uint32 start, end; + size_t start_block; + bool loop; +}; + static struct { - bool stop_song; - bool terminate; - bool playing; - int new_vol; - HANDLE wait_obj; - HANDLE thread; - UINT_PTR devid; - char start_song[MAX_PATH]; + UINT time_period; ///< obtained timer precision value + HMIDIOUT midi_out; ///< handle to open midiOut + UINT timer_id; ///< ID of active multimedia timer + CRITICAL_SECTION lock; ///< synchronization for playback status fields + + bool playing; ///< flag indicating that playback is active + bool do_start; ///< flag for starting playback of next_file at next opportunity + bool do_stop; ///< flag for stopping playback at next opportunity + byte current_volume; ///< current effective volume setting + byte new_volume; ///< volume setting to change to + + MidiFile current_file; ///< file currently being played from + PlaybackSegment current_segment; ///< segment info for current playback + DWORD playback_start_time; ///< timestamp current file began playback + size_t current_block; ///< next block index to send + MidiFile next_file; ///< upcoming file to play + PlaybackSegment next_segment; ///< segment info for upcoming file + + byte channel_volumes[16]; ///< last seen volume controller values in raw data } _midi; static FMusicDriver_Win32 iFMusicDriver_Win32; -void MusicDriver_Win32::PlaySong(const char *filename) + +static byte ScaleVolume(byte original, byte scale) { - assert(filename != NULL); - strecpy(_midi.start_song, filename, lastof(_midi.start_song)); - _midi.playing = true; - _midi.stop_song = false; - SetEvent(_midi.wait_obj); + return original * scale / 127; +} + + +void CALLBACK MidiOutProc(HMIDIOUT hmo, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) +{ + if (wMsg == MOM_DONE) { + MIDIHDR *hdr = (LPMIDIHDR)dwParam1; + midiOutUnprepareHeader(hmo, hdr, sizeof(*hdr)); + free(hdr); + } +} + +static void TransmitChannelMsg(byte status, byte p1, byte p2 = 0) +{ + midiOutShortMsg(_midi.midi_out, status | (p1 << 8) | (p2 << 16)); +} + +static void TransmitSysex(byte *&msg_start, size_t &remaining) +{ + /* find end of message */ + byte *msg_end = msg_start; + while (*msg_end != MIDIST_ENDSYSEX) msg_end++; + msg_end++; /* also include sysex end byte */ + + /* prepare header */ + MIDIHDR *hdr = CallocT(1); + hdr->lpData = (LPSTR)msg_start; + hdr->dwBufferLength = msg_end - msg_start; + if (midiOutPrepareHeader(_midi.midi_out, hdr, sizeof(*hdr)) == MMSYSERR_NOERROR) { + /* transmit - just point directly into the data buffer */ + hdr->dwBytesRecorded = hdr->dwBufferLength; + midiOutLongMsg(_midi.midi_out, hdr, sizeof(*hdr)); + } else { + free(hdr); + } + + /* update position in buffer */ + remaining -= msg_end - msg_start; + msg_start = msg_end; +} + +static void TransmitSysexConst(byte *msg_start, size_t length) +{ + TransmitSysex(msg_start, length); +} + +/** + * Realtime MIDI playback service routine. + * This is called by the multimedia timer. + */ +void CALLBACK TimerCallback(UINT uTimerID, UINT, DWORD_PTR dwUser, DWORD_PTR, DWORD_PTR) +{ + /* Try to check playback status changes. + * If _midi is already locked, skip checking for this cycle and try again + * next cycle, instead of waiting for locks in the realtime callback. */ + if (TryEnterCriticalSection(&_midi.lock)) { + /* check for stop */ + if (_midi.do_stop) { + DEBUG(driver, 2, "Win32-MIDI: timer: do_stop is set"); + midiOutReset(_midi.midi_out); + _midi.playing = false; + _midi.do_stop = false; + LeaveCriticalSection(&_midi.lock); + return; + } + + /* check for start/restart/change song */ + if (_midi.do_start) { + DEBUG(driver, 2, "Win32-MIDI: timer: do_start is set"); + if (_midi.playing) { + midiOutReset(_midi.midi_out); + /* Some songs change the "Pitch bend range" registered + * parameter. If this doesn't get reset, everything else + * will start sounding wrong. */ + for (int ch = 0; ch < 16; ch++) { + /* Running status, only need status for first message */ + /* Select RPN 00.00, set value to 02.00, and unselect again */ + TransmitChannelMsg(MIDIST_CONTROLLER | ch, MIDICT_RPN_SELECT_LO, 0x00); + TransmitChannelMsg(MIDICT_RPN_SELECT_HI, 0x00); + TransmitChannelMsg(MIDICT_DATAENTRY, 0x02); + TransmitChannelMsg(MIDICT_DATAENTRY_LO, 0x00); + TransmitChannelMsg(MIDICT_RPN_SELECT_LO, 0x7F); + TransmitChannelMsg(MIDICT_RPN_SELECT_HI, 0x7F); + } + } + _midi.current_file.MoveFrom(_midi.next_file); + std::swap(_midi.next_segment, _midi.current_segment); + _midi.current_segment.start_block = 0; + _midi.playback_start_time = timeGetTime(); + _midi.playing = true; + _midi.do_start = false; + _midi.current_block = 0; + + MemSetT(_midi.channel_volumes, 127, lengthof(_midi.channel_volumes)); + } else if (!_midi.playing) { + /* not playing, stop the timer */ + DEBUG(driver, 2, "Win32-MIDI: timer: not playing, stopping timer"); + timeKillEvent(uTimerID); + _midi.timer_id = 0; + LeaveCriticalSection(&_midi.lock); + return; + } + + /* check for volume change */ + static int volume_throttle = 0; + if (_midi.current_volume != _midi.new_volume) { + if (volume_throttle == 0) { + DEBUG(driver, 2, "Win32-MIDI: timer: volume change"); + _midi.current_volume = _midi.new_volume; + volume_throttle = 20 / _midi.time_period; + for (int ch = 0; ch < 16; ch++) { + int vol = ScaleVolume(_midi.channel_volumes[ch], _midi.current_volume); + TransmitChannelMsg(MIDIST_CONTROLLER | ch, MIDICT_CHANVOLUME, vol); + } + } + else { + volume_throttle--; + } + } + + LeaveCriticalSection(&_midi.lock); + } + + /* skip beginning of file? */ + if (_midi.current_segment.start > 0 && _midi.current_block == 0 && _midi.current_segment.start_block == 0) { + /* find first block after start time and pretend playback started earlier + * this is to allow all blocks prior to the actual start to still affect playback, + * as they may contain important controller and program changes */ + uint preload_bytes = 0; + for (size_t bl = 0; bl < _midi.current_file.blocks.size(); bl++) { + MidiFile::DataBlock &block = _midi.current_file.blocks[bl]; + preload_bytes += block.data.Length(); + if (block.ticktime >= _midi.current_segment.start) { + if (_midi.current_segment.loop) { + DEBUG(driver, 2, "Win32-MIDI: timer: loop from block %d (ticktime %d, realtime %.3f, bytes %d)", (int)bl, (int)block.ticktime, ((int)block.realtime)/1000.0, (int)preload_bytes); + _midi.current_segment.start_block = bl; + break; + } else { + /* Calculate offset start time for playback. + * The preload_bytes are used to compensate for delay in transmission over traditional serial MIDI interfaces, + * which have a bitrate of 31,250 bits/sec, and transmit 1+8+1 start/data/stop bits per byte. + * The delay compensation is needed to avoid time-compression of following messages. + */ + DEBUG(driver, 2, "Win32-MIDI: timer: start from block %d (ticktime %d, realtime %.3f, bytes %d)", (int)bl, (int)block.ticktime, ((int)block.realtime) / 1000.0, (int)preload_bytes); + _midi.playback_start_time -= block.realtime / 1000 - preload_bytes * 1000 / 3125; + break; + } + } + } + } + + + /* play pending blocks */ + DWORD current_time = timeGetTime(); + DWORD playback_time = current_time - _midi.playback_start_time; + while (_midi.current_block < _midi.current_file.blocks.size()) { + MidiFile::DataBlock &block = _midi.current_file.blocks[_midi.current_block]; + + /* check that block isn't at end-of-song override */ + if (_midi.current_segment.end > 0 && block.ticktime >= _midi.current_segment.end) { + if (_midi.current_segment.loop) { + _midi.current_block = _midi.current_segment.start_block; + _midi.playback_start_time = timeGetTime() - _midi.current_file.blocks[_midi.current_block].realtime / 1000; + } else { + _midi.do_stop = true; + } + break; + } + /* check that block is not in the future */ + if (block.realtime / 1000 > playback_time) { + break; + } + + byte *data = block.data.Begin(); + size_t remaining = block.data.Length(); + byte last_status = 0; + while (remaining > 0) { + /* MidiFile ought to have converted everything out of running status, + * but handle it anyway just to be safe */ + byte status = data[0]; + if (status & 0x80) { + last_status = status; + data++; + remaining--; + } else { + status = last_status; + } + switch (status & 0xF0) { + case MIDIST_PROGCHG: + case MIDIST_CHANPRESS: + /* 2 byte channel messages */ + TransmitChannelMsg(status, data[0]); + data++; + remaining--; + break; + case MIDIST_NOTEOFF: + case MIDIST_NOTEON: + case MIDIST_POLYPRESS: + case MIDIST_PITCHBEND: + /* 3 byte channel messages */ + TransmitChannelMsg(status, data[0], data[1]); + data += 2; + remaining -= 2; + break; + case MIDIST_CONTROLLER: + /* controller change */ + if (data[0] == MIDICT_CHANVOLUME) { + /* volume controller, adjust for user volume */ + _midi.channel_volumes[status & 0x0F] = data[1]; + int vol = ScaleVolume(data[1], _midi.current_volume); + TransmitChannelMsg(status, data[0], vol); + } else { + /* handle other controllers normally */ + TransmitChannelMsg(status, data[0], data[1]); + } + data += 2; + remaining -= 2; + break; + case 0xF0: + /* system messages */ + switch (status) { + case MIDIST_SYSEX: /* system exclusive */ + TransmitSysex(data, remaining); + break; + case MIDIST_TC_QFRAME: /* time code quarter frame */ + case MIDIST_SONGSEL: /* song select */ + data++; + remaining--; + break; + case MIDIST_SONGPOSPTR: /* song position pointer */ + data += 2; + remaining -= 2; + break; + default: /* remaining have no data bytes */ + break; + } + break; + } + } + + _midi.current_block++; + } + + /* end? */ + if (_midi.current_block == _midi.current_file.blocks.size()) { + if (_midi.current_segment.loop) { + _midi.current_block = _midi.current_segment.start_block; + _midi.playback_start_time = timeGetTime() - _midi.current_file.blocks[_midi.current_block].realtime / 1000; + } else { + _midi.do_stop = true; + } + } +} + +void MusicDriver_Win32::PlaySong(const MusicSongInfo &song) +{ + DEBUG(driver, 2, "Win32-MIDI: PlaySong: entry"); + EnterCriticalSection(&_midi.lock); + + if (!_midi.next_file.LoadSong(song)) { + LeaveCriticalSection(&_midi.lock); + return; + } + + _midi.next_segment.start = song.override_start; + _midi.next_segment.end = song.override_end; + _midi.next_segment.loop = song.loop; + + DEBUG(driver, 2, "Win32-MIDI: PlaySong: setting flag"); + _midi.do_stop = _midi.playing; + _midi.do_start = true; + + if (_midi.timer_id == 0) { + DEBUG(driver, 2, "Win32-MIDI: PlaySong: starting timer"); + _midi.timer_id = timeSetEvent(_midi.time_period, _midi.time_period, TimerCallback, (DWORD_PTR)this, TIME_PERIODIC | TIME_CALLBACK_FUNCTION); + } + + LeaveCriticalSection(&_midi.lock); } void MusicDriver_Win32::StopSong() { - if (_midi.playing) { - _midi.stop_song = true; - _midi.start_song[0] = '\0'; - SetEvent(_midi.wait_obj); - } + DEBUG(driver, 2, "Win32-MIDI: StopSong: entry"); + EnterCriticalSection(&_midi.lock); + DEBUG(driver, 2, "Win32-MIDI: StopSong: setting flag"); + _midi.do_stop = true; + LeaveCriticalSection(&_midi.lock); } bool MusicDriver_Win32::IsSongPlaying() { - return _midi.playing; + return _midi.playing || _midi.do_start; } void MusicDriver_Win32::SetVolume(byte vol) { - _midi.new_vol = vol; - SetEvent(_midi.wait_obj); -} - -static MCIERROR CDECL MidiSendCommand(const TCHAR *cmd, ...) -{ - va_list va; - TCHAR buf[512]; - - va_start(va, cmd); - _vsntprintf(buf, lengthof(buf), cmd, va); - va_end(va); - return mciSendString(buf, NULL, 0, 0); -} - -static bool MidiIntPlaySong(const char *filename) -{ - MidiSendCommand(_T("close all")); - - if (MidiSendCommand(_T("open \"%s\" type sequencer alias song"), OTTD2FS(filename)) != 0) { - /* Let's try the "short name" */ - TCHAR buf[MAX_PATH]; - if (GetShortPathName(OTTD2FS(filename), buf, MAX_PATH) == 0) return false; - if (MidiSendCommand(_T("open \"%s\" type sequencer alias song"), buf) != 0) return false; - } - - MidiSendCommand(_T("seek song to start wait")); - return MidiSendCommand(_T("play song")) == 0; -} - -static void MidiIntStopSong() -{ - MidiSendCommand(_T("close all")); -} - -static void MidiIntSetVolume(int vol) -{ - DWORD v = (vol * 65535 / 127); - midiOutSetVolume((HMIDIOUT)_midi.devid, v + (v << 16)); -} - -static bool MidiIntIsSongPlaying() -{ - char buf[16]; - mciSendStringA("status song mode", buf, sizeof(buf), 0); - return strcmp(buf, "playing") == 0 || strcmp(buf, "seeking") == 0; -} - -static DWORD WINAPI MidiThread(LPVOID arg) -{ - SetWin32ThreadName(-1, "ottd:win-midi"); - - do { - char *s; - int vol; - - vol = _midi.new_vol; - if (vol != -1) { - _midi.new_vol = -1; - MidiIntSetVolume(vol); - } - - s = _midi.start_song; - if (s[0] != '\0') { - _midi.playing = MidiIntPlaySong(s); - s[0] = '\0'; - - /* Delay somewhat in case we don't manage to play. */ - if (!_midi.playing) WaitForMultipleObjects(1, &_midi.wait_obj, FALSE, 5000); - } - - if (_midi.stop_song && _midi.playing) { - _midi.stop_song = false; - _midi.playing = false; - MidiIntStopSong(); - } - - if (_midi.playing && !MidiIntIsSongPlaying()) _midi.playing = false; - - WaitForMultipleObjects(1, &_midi.wait_obj, FALSE, 1000); - } while (!_midi.terminate); - - MidiIntStopSong(); - return 0; + EnterCriticalSection(&_midi.lock); + _midi.new_volume = vol; + LeaveCriticalSection(&_midi.lock); } const char *MusicDriver_Win32::Start(const char * const *parm) { - MIDIOUTCAPS midicaps; - UINT nbdev; - UINT_PTR dev; - char buf[16]; + DEBUG(driver, 2, "Win32-MIDI: Start: initializing"); - mciSendStringA("capability sequencer has audio", buf, lengthof(buf), 0); - if (strcmp(buf, "true") != 0) return "MCI sequencer can't play audio"; + InitializeCriticalSection(&_midi.lock); - memset(&_midi, 0, sizeof(_midi)); - _midi.new_vol = -1; + int resolution = GetDriverParamInt(parm, "resolution", 5); + int port = GetDriverParamInt(parm, "port", -1); - /* Get midi device */ - _midi.devid = MIDI_MAPPER; - for (dev = 0, nbdev = midiOutGetNumDevs(); dev < nbdev; dev++) { - if (midiOutGetDevCaps(dev, &midicaps, sizeof(midicaps)) == 0 && (midicaps.dwSupport & MIDICAPS_VOLUME)) { - _midi.devid = dev; - break; - } + UINT devid; + if (port < 0) { + devid = MIDI_MAPPER; + } else { + devid = (UINT)port; } - if (NULL == (_midi.wait_obj = CreateEvent(NULL, FALSE, FALSE, NULL))) return "Failed to create event"; + resolution = Clamp(resolution, 1, 20); - /* The lpThreadId parameter of CreateThread (the last parameter) - * may NOT be NULL on Windows 95, 98 and ME. */ - DWORD threadId; - if (NULL == (_midi.thread = CreateThread(NULL, 8192, MidiThread, 0, 0, &threadId))) return "Failed to create thread"; + if (midiOutOpen(&_midi.midi_out, devid, (DWORD_PTR)&MidiOutProc, (DWORD_PTR)this, CALLBACK_FUNCTION) != MMSYSERR_NOERROR) { + return "could not open midi device"; + } - return NULL; + midiOutReset(_midi.midi_out); + + /* Standard "Enable General MIDI" message */ + static byte gm_enable_sysex[] = { 0xF0, 0x7E, 0x00, 0x09, 0x01, 0xF7 }; + TransmitSysexConst(&gm_enable_sysex[0], sizeof(gm_enable_sysex)); + + /* Roland-specific reverb room control, used by the original game */ + static byte roland_reverb_sysex[] = { 0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x01, 0x30, 0x02, 0x04, 0x00, 0x40, 0x40, 0x00, 0x00, 0x09, 0xF7 }; + TransmitSysexConst(&roland_reverb_sysex[0], sizeof(roland_reverb_sysex)); + + /* prepare multimedia timer */ + TIMECAPS timecaps; + if (timeGetDevCaps(&timecaps, sizeof(timecaps)) == MMSYSERR_NOERROR) { + _midi.time_period = min(max((UINT)resolution, timecaps.wPeriodMin), timecaps.wPeriodMax); + if (timeBeginPeriod(_midi.time_period) == MMSYSERR_NOERROR) { + /* success */ + DEBUG(driver, 2, "Win32-MIDI: Start: timer resolution is %d", (int)_midi.time_period); + return NULL; + } + } + midiOutClose(_midi.midi_out); + return "could not set timer resolution"; } void MusicDriver_Win32::Stop() { - _midi.terminate = true; - SetEvent(_midi.wait_obj); - WaitForMultipleObjects(1, &_midi.thread, true, INFINITE); - CloseHandle(_midi.wait_obj); - CloseHandle(_midi.thread); + EnterCriticalSection(&_midi.lock); + + if (_midi.timer_id) { + timeKillEvent(_midi.timer_id); + _midi.timer_id = 0; + } + + timeEndPeriod(_midi.time_period); + midiOutReset(_midi.midi_out); + midiOutClose(_midi.midi_out); + + LeaveCriticalSection(&_midi.lock); + DeleteCriticalSection(&_midi.lock); } diff --git a/src/music/win32_m.h b/src/music/win32_m.h index 3efee3243a..1ac8ae69e4 100644 --- a/src/music/win32_m.h +++ b/src/music/win32_m.h @@ -21,7 +21,7 @@ public: /* virtual */ void Stop(); - /* virtual */ void PlaySong(const char *filename); + /* virtual */ void PlaySong(const MusicSongInfo &song); /* virtual */ void StopSong(); diff --git a/src/music_gui.cpp b/src/music_gui.cpp index 279f376525..87a073b0a7 100644 --- a/src/music_gui.cpp +++ b/src/music_gui.cpp @@ -10,6 +10,7 @@ /** @file music_gui.cpp GUI for the music playback. */ #include "stdafx.h" +#include #include "openttd.h" #include "base_media_base.h" #include "music/music_driver.hpp" @@ -18,11 +19,15 @@ #include "window_func.h" #include "sound_func.h" #include "gfx_func.h" +#include "zoom_func.h" #include "core/random_func.hpp" #include "error.h" #include "core/geometry_func.hpp" #include "string_func.h" #include "settings_type.h" +#include "settings_gui.h" +#include "widgets/dropdown_func.h" +#include "widgets/dropdown_type.h" #include "widgets/music_widget.h" @@ -31,271 +36,419 @@ #include "safeguards.h" -/** - * Get the name of the song. - * @param index of the song. - * @return the name of the song. - */ -static const char *GetSongName(int index) -{ - return BaseMusic::GetUsedSet()->song_name[index]; -} -/** - * Get the track number of the song. - * @param index of the song. - * @return the track number of the song. - */ -static int GetTrackNumber(int index) -{ - return BaseMusic::GetUsedSet()->track_nr[index]; -} +struct MusicSystem { + struct PlaylistEntry : MusicSongInfo { + const MusicSet *set; ///< music set the song comes from + uint set_index; ///< index of song in set -/** The currently played song */ -static byte _music_wnd_cursong = 1; -/** Whether a song is currently played */ -static bool _song_is_active = false; + PlaylistEntry(const MusicSet *set, uint set_index) : MusicSongInfo(set->songinfo[set_index]), set(set), set_index(set_index) { } + bool IsValid() const { return !StrEmpty(this->songname); } + }; + typedef std::vector Playlist; -/** Indices of the songs in the current playlist */ -static byte _cur_playlist[NUM_SONGS_PLAYLIST + 1]; + enum PlaylistChoices { + PLCH_ALLMUSIC, + PLCH_OLDSTYLE, + PLCH_NEWSTYLE, + PLCH_EZYSTREET, + PLCH_CUSTOM1, + PLCH_CUSTOM2, + PLCH_THEMEONLY, + PLCH_MAX, + }; -/** Indices of all songs */ -static byte _playlist_all[NUM_SONGS_AVAILABLE + 1]; -/** Indices of all old style songs */ -static byte _playlist_old_style[NUM_SONGS_CLASS + 1]; -/** Indices of all new style songs */ -static byte _playlist_new_style[NUM_SONGS_CLASS + 1]; -/** Indices of all ezy street songs */ -static byte _playlist_ezy_street[NUM_SONGS_CLASS + 1]; + Playlist active_playlist; ///< current play order of songs, including any shuffle + Playlist displayed_playlist; ///< current playlist as displayed in GUI, never in shuffled order + Playlist music_set; ///< all songs in current music set, in set order -assert_compile(lengthof(_settings_client.music.custom_1) == NUM_SONGS_PLAYLIST + 1); -assert_compile(lengthof(_settings_client.music.custom_2) == NUM_SONGS_PLAYLIST + 1); + PlaylistChoices selected_playlist; -/** The different playlists that can be played. */ -static byte * const _playlists[] = { - _playlist_all, - _playlist_old_style, - _playlist_new_style, - _playlist_ezy_street, - _settings_client.music.custom_1, - _settings_client.music.custom_2, + void BuildPlaylists(); + + void ChangePlaylist(PlaylistChoices pl); + void ChangeMusicSet(const char *set_name); + void Shuffle(); + void Unshuffle(); + + void Play(); + void Stop(); + void Next(); + void Prev(); + void CheckStatus(); + + bool IsPlaying() const; + bool IsShuffle() const; + PlaylistEntry GetCurrentSong() const; + + bool IsCustomPlaylist() const; + void PlaylistAdd(size_t song_index); + void PlaylistRemove(size_t song_index); + void PlaylistClear(); + +private: + void ChangePlaylistPosition(int ofs); + int playlist_position; + + void SaveCustomPlaylist(PlaylistChoices pl); + + Playlist standard_playlists[PLCH_MAX]; }; -/** - * Validate a playlist. - * @param playlist The playlist to validate. - * @param last The last location in the list. - */ -void ValidatePlaylist(byte *playlist, byte *last) -{ - while (*playlist != 0 && playlist <= last) { - /* Song indices are saved off-by-one so 0 is "nothing". */ - if (*playlist <= NUM_SONGS_AVAILABLE && !StrEmpty(GetSongName(*playlist - 1))) { - playlist++; - continue; - } - for (byte *p = playlist; *p != 0 && p <= last; p++) { - p[0] = p[1]; - } - } +MusicSystem _music; - /* Make sure the list is null terminated. */ - *last = 0; -} -/** Initialize the playlists */ -void InitializeMusic() +/** Rebuild all playlists for the current music set */ +void MusicSystem::BuildPlaylists() { - uint j = 0; + const MusicSet *set = BaseMusic::GetUsedSet(); + + /* Clear current playlists */ + for (size_t i = 0; i < lengthof(this->standard_playlists); ++i) this->standard_playlists[i].clear(); + this->music_set.clear(); + + /* Build standard playlists, and a list of available music */ for (uint i = 0; i < NUM_SONGS_AVAILABLE; i++) { - if (StrEmpty(GetSongName(i))) continue; - _playlist_all[j++] = i + 1; - } - /* Terminate the list */ - _playlist_all[j] = 0; + PlaylistEntry entry(set, i); + if (!entry.IsValid()) continue; - /* Now make the 'styled' playlists */ - for (uint k = 0; k < NUM_SONG_CLASSES; k++) { - j = 0; - for (uint i = 0; i < NUM_SONGS_CLASS; i++) { - int id = k * NUM_SONGS_CLASS + i + 1; - if (StrEmpty(GetSongName(id))) continue; - _playlists[k + 1][j++] = id + 1; - } - /* Terminate the list */ - _playlists[k + 1][j] = 0; - } + this->music_set.push_back(entry); - ValidatePlaylist(_settings_client.music.custom_1, lastof(_settings_client.music.custom_1)); - ValidatePlaylist(_settings_client.music.custom_2, lastof(_settings_client.music.custom_2)); + /* Add theme song to theme-only playlist */ + if (i == 0) this->standard_playlists[PLCH_THEMEONLY].push_back(entry); - if (BaseMusic::GetUsedSet()->num_available < _music_wnd_cursong) { - /* If there are less songs than the currently played song, - * just pause and reset to no song. */ - _music_wnd_cursong = 0; - _song_is_active = false; - } -} - -static void SkipToPrevSong() -{ - byte *b = _cur_playlist; - byte *p = b; - byte t; - - if (b[0] == 0) return; // empty playlist - - do p++; while (p[0] != 0); // find the end - - t = *--p; // and copy the bytes - while (p != b) { - p--; - p[1] = p[0]; - } - *b = t; - - _song_is_active = false; -} - -static void SkipToNextSong() -{ - byte *b = _cur_playlist; - byte t; - - t = b[0]; - if (t != 0) { - while (b[1] != 0) { - b[0] = b[1]; - b++; - } - b[0] = t; - } - - _song_is_active = false; -} - -static void MusicVolumeChanged(byte new_vol) -{ - MusicDriver::GetInstance()->SetVolume(new_vol); -} - -static void DoPlaySong() -{ - char filename[MAX_PATH]; - if (FioFindFullPath(filename, lastof(filename), BASESET_DIR, BaseMusic::GetUsedSet()->files[_music_wnd_cursong - 1].filename) == NULL) { - FioFindFullPath(filename, lastof(filename), OLD_GM_DIR, BaseMusic::GetUsedSet()->files[_music_wnd_cursong - 1].filename); - } - MusicDriver::GetInstance()->PlaySong(filename); - SetWindowDirty(WC_MUSIC_WINDOW, 0); -} - -static void DoStopMusic() -{ - MusicDriver::GetInstance()->StopSong(); - SetWindowDirty(WC_MUSIC_WINDOW, 0); -} - -static void SelectSongToPlay() -{ - uint i = 0; - uint j = 0; - - memset(_cur_playlist, 0, sizeof(_cur_playlist)); - do { - /* File is the index into the file table of the music set. The play list uses 0 as 'no entry', - * so we need to subtract 1. In case of 'no entry' (file = -1), just skip adding it outright. */ - int file = _playlists[_settings_client.music.playlist][i] - 1; - if (file >= 0) { - const char *filename = BaseMusic::GetUsedSet()->files[file].filename; - /* We are now checking for the existence of that file prior - * to add it to the list of available songs */ - if (!StrEmpty(filename) && FioCheckFileExists(filename, BASESET_DIR)) { - _cur_playlist[j] = _playlists[_settings_client.music.playlist][i]; - j++; - } - } - } while (_playlists[_settings_client.music.playlist][++i] != 0 && j < lengthof(_cur_playlist) - 1); - - /* Do not shuffle when on the intro-start window, as the song to play has to be the original TTD Theme*/ - if (_settings_client.music.shuffle && _game_mode != GM_MENU) { - i = 500; - do { - uint32 r = InteractiveRandom(); - byte *a = &_cur_playlist[GB(r, 0, 5)]; - byte *b = &_cur_playlist[GB(r, 8, 5)]; - - if (*a != 0 && *b != 0) { - byte t = *a; - *a = *b; - *b = t; - } - } while (--i); - } -} - -static void StopMusic() -{ - _music_wnd_cursong = 0; - DoStopMusic(); - _song_is_active = false; - SetWindowWidgetDirty(WC_MUSIC_WINDOW, 0, 9); -} - -static void PlayPlaylistSong() -{ - if (_cur_playlist[0] == 0) { - SelectSongToPlay(); - /* if there is not songs in the playlist, it may indicate - * no file on the gm folder, or even no gm folder. - * Stop the playback, then */ - if (_cur_playlist[0] == 0) { - _song_is_active = false; - _music_wnd_cursong = 0; - _settings_client.music.playing = false; - return; + /* Don't add the theme song to standard playlists */ + if (i > 0) { + this->standard_playlists[PLCH_ALLMUSIC].push_back(entry); + uint theme = (i - 1) / NUM_SONGS_CLASS; + this->standard_playlists[PLCH_OLDSTYLE + theme].push_back(entry); } } - _music_wnd_cursong = _cur_playlist[0]; - DoPlaySong(); - _song_is_active = true; - SetWindowWidgetDirty(WC_MUSIC_WINDOW, 0, 9); -} - -void ResetMusic() -{ - _music_wnd_cursong = 1; - DoPlaySong(); -} - -void MusicLoop() -{ - if (!_settings_client.music.playing && _song_is_active) { - StopMusic(); - } else if (_settings_client.music.playing && !_song_is_active) { - PlayPlaylistSong(); - } - - if (!_song_is_active) return; - - if (!MusicDriver::GetInstance()->IsSongPlaying()) { - if (_game_mode != GM_MENU) { - StopMusic(); - SkipToNextSong(); - PlayPlaylistSong(); - } else { - ResetMusic(); + /* Load custom playlists + * Song index offsets are 1-based, zero indicates invalid/end-of-list value */ + for (uint i = 0; i < NUM_SONGS_PLAYLIST; i++) { + if (_settings_client.music.custom_1[i] > 0) { + PlaylistEntry entry(set, _settings_client.music.custom_1[i] - 1); + if (entry.IsValid()) this->standard_playlists[PLCH_CUSTOM1].push_back(entry); + } + if (_settings_client.music.custom_2[i] > 0) { + PlaylistEntry entry(set, _settings_client.music.custom_2[i] - 1); + if (entry.IsValid()) this->standard_playlists[PLCH_CUSTOM2].push_back(entry); } } } -static void SelectPlaylist(byte list) +/** + * Switch to another playlist, or reload the current one. + * @param pl Playlist to select + */ +void MusicSystem::ChangePlaylist(PlaylistChoices pl) { - _settings_client.music.playlist = list; + assert(pl < PLCH_MAX && pl >= PLCH_ALLMUSIC); + + this->displayed_playlist = this->standard_playlists[pl]; + this->active_playlist = this->displayed_playlist; + this->selected_playlist = pl; + this->playlist_position = 0; + + if (this->selected_playlist != PLCH_THEMEONLY) _settings_client.music.playlist = this->selected_playlist; + + if (_settings_client.music.shuffle) { + this->Shuffle(); + /* Shuffle() will also Play() if necessary, only start once */ + } else if (_settings_client.music.playing) { + this->Play(); + } + InvalidateWindowData(WC_MUSIC_TRACK_SELECTION, 0); InvalidateWindowData(WC_MUSIC_WINDOW, 0); } +/** + * Change to named music set, and reset playback. + * @param set_name Name of music set to select + */ +void MusicSystem::ChangeMusicSet(const char *set_name) +{ + BaseMusic::SetSet(set_name); + + free(BaseMusic::ini_set); + BaseMusic::ini_set = stredup(set_name); + + this->BuildPlaylists(); + this->ChangePlaylist(this->selected_playlist); + + InvalidateWindowData(WC_GAME_OPTIONS, WN_GAME_OPTIONS_GAME_OPTIONS, 0, true); +} + +/** Enable shuffle mode and restart playback */ +void MusicSystem::Shuffle() +{ + _settings_client.music.shuffle = true; + + this->active_playlist = this->displayed_playlist; + for (size_t i = 0; i < this->active_playlist.size(); i++) { + size_t shuffle_index = InteractiveRandom() % (this->active_playlist.size() - i); + std::swap(this->active_playlist[i], this->active_playlist[i + shuffle_index]); + } + + if (_settings_client.music.playing) this->Play(); + + InvalidateWindowData(WC_MUSIC_WINDOW, 0); +} + +/** Disable shuffle and restart playback */ +void MusicSystem::Unshuffle() +{ + _settings_client.music.shuffle = false; + this->active_playlist = this->displayed_playlist; + + if (_settings_client.music.playing) this->Play(); + + InvalidateWindowData(WC_MUSIC_WINDOW, 0); +} + +/** Start/restart playback at current song */ +void MusicSystem::Play() +{ + /* Always set the playing flag, even if there is no music */ + _settings_client.music.playing = true; + MusicDriver::GetInstance()->StopSong(); + /* Make sure playlist_position is a valid index, if playlist has changed etc. */ + this->ChangePlaylistPosition(0); + + /* If there is no music, don't try to play it */ + if (this->active_playlist.empty()) return; + + MusicSongInfo song = this->active_playlist[this->playlist_position]; + if (_game_mode == GM_MENU && this->selected_playlist == PLCH_THEMEONLY) song.loop = true; + MusicDriver::GetInstance()->PlaySong(song); + + InvalidateWindowData(WC_MUSIC_WINDOW, 0); +} + +/** Stop playback and set flag that we don't intend to play music */ +void MusicSystem::Stop() +{ + MusicDriver::GetInstance()->StopSong(); + _settings_client.music.playing = false; + + InvalidateWindowData(WC_MUSIC_WINDOW, 0); +} + +/** Skip to next track */ +void MusicSystem::Next() +{ + this->ChangePlaylistPosition(+1); + if (_settings_client.music.playing) this->Play(); + + InvalidateWindowData(WC_MUSIC_WINDOW, 0); +} + +/** Skip to previous track */ +void MusicSystem::Prev() +{ + this->ChangePlaylistPosition(-1); + if (_settings_client.music.playing) this->Play(); + + InvalidateWindowData(WC_MUSIC_WINDOW, 0); +} + +/** Check that music is playing if it should, and that appropriate playlist is active for game/main menu */ +void MusicSystem::CheckStatus() +{ + if ((_game_mode == GM_MENU) != (this->selected_playlist == PLCH_THEMEONLY)) { + /* Make sure the theme-only playlist is active when on the title screen, and not during gameplay */ + this->ChangePlaylist((_game_mode == GM_MENU) ? PLCH_THEMEONLY : (PlaylistChoices)_settings_client.music.playlist); + } + if (this->active_playlist.empty()) return; + /* If we were supposed to be playing, but music has stopped, move to next song */ + if (this->IsPlaying() && !MusicDriver::GetInstance()->IsSongPlaying()) this->Next(); +} + +/** Is the player getting music right now? */ +bool MusicSystem::IsPlaying() const +{ + return _settings_client.music.playing && !this->active_playlist.empty(); +} + +/** Is shuffle mode enabled? */ +bool MusicSystem::IsShuffle() const +{ + return _settings_client.music.shuffle; +} + +/** Return the current song, or a dummy if none */ +MusicSystem::PlaylistEntry MusicSystem::GetCurrentSong() const +{ + if (!this->IsPlaying()) return PlaylistEntry(BaseMusic::GetUsedSet(), 0); + return this->active_playlist[this->playlist_position]; +} + +/** Is one of the custom playlists selected? */ +bool MusicSystem::IsCustomPlaylist() const +{ + return (this->selected_playlist == PLCH_CUSTOM1) || (this->selected_playlist == PLCH_CUSTOM2); +} + +/** + * Append a song to a custom playlist. + * Always adds to the currently active playlist. + * @param song_index Index of song in the current music set to add + */ +void MusicSystem::PlaylistAdd(size_t song_index) +{ + if (!this->IsCustomPlaylist()) return; + + /* Pick out song from the music set */ + if (song_index >= this->music_set.size()) return; + PlaylistEntry entry = this->music_set[song_index]; + + /* Check for maximum length */ + if (this->standard_playlists[this->selected_playlist].size() >= NUM_SONGS_PLAYLIST) return; + + /* Add it to the appropriate playlist, and the display */ + this->standard_playlists[this->selected_playlist].push_back(entry); + this->displayed_playlist.push_back(entry); + + /* Add it to the active playlist, if playback is shuffled select a random position to add at */ + if (this->active_playlist.empty()) { + this->active_playlist.push_back(entry); + if (this->IsPlaying()) this->Play(); + } else if (this->IsShuffle()) { + /* Generate a random position between 0 and n (inclusive, new length) to insert at */ + size_t maxpos = this->displayed_playlist.size(); + size_t newpos = InteractiveRandom() % maxpos; + this->active_playlist.insert(this->active_playlist.begin() + newpos, entry); + /* Make sure to shift up the current playback position if the song was inserted before it */ + if ((int)newpos <= this->playlist_position) this->playlist_position++; + } else { + this->active_playlist.push_back(entry); + } + + this->SaveCustomPlaylist(this->selected_playlist); + + InvalidateWindowData(WC_MUSIC_TRACK_SELECTION, 0); +} + +/** + * Remove a song from a custom playlist. + * @param song_index Index in the custom playlist to remove. + */ +void MusicSystem::PlaylistRemove(size_t song_index) +{ + if (!this->IsCustomPlaylist()) return; + + Playlist &pl = this->standard_playlists[this->selected_playlist]; + if (song_index >= pl.size()) return; + + /* Remove from "simple" playlists */ + PlaylistEntry song = pl[song_index]; + pl.erase(pl.begin() + song_index); + this->displayed_playlist.erase(this->displayed_playlist.begin() + song_index); + + /* Find in actual active playlist (may be shuffled) and remove, + * if it's the current song restart playback */ + for (size_t i = 0; i < this->active_playlist.size(); i++) { + Playlist::iterator s2 = this->active_playlist.begin() + i; + if (s2->filename == song.filename && s2->cat_index == song.cat_index) { + this->active_playlist.erase(s2); + if ((int)i == this->playlist_position && this->IsPlaying()) this->Play(); + break; + } + } + + this->SaveCustomPlaylist(this->selected_playlist); + + InvalidateWindowData(WC_MUSIC_TRACK_SELECTION, 0); +} + +/** + * Remove all songs from the current custom playlist. + * Effectively stops playback too. + */ +void MusicSystem::PlaylistClear() +{ + if (!this->IsCustomPlaylist()) return; + + this->standard_playlists[this->selected_playlist].clear(); + this->ChangePlaylist(this->selected_playlist); + + this->SaveCustomPlaylist(this->selected_playlist); +} + +/** + * Change playlist position pointer by the given offset, making sure to keep it within valid range. + * If the playlist is empty, position is always set to 0. + * @param ofs Amount to move playlist position by. + */ +void MusicSystem::ChangePlaylistPosition(int ofs) +{ + if (this->active_playlist.empty()) { + this->playlist_position = 0; + } else { + this->playlist_position += ofs; + while (this->playlist_position >= (int)this->active_playlist.size()) this->playlist_position -= (int)this->active_playlist.size(); + while (this->playlist_position < 0) this->playlist_position += (int)this->active_playlist.size(); + } +} + +/** + * Save a custom playlist to settings after modification. + * @param pl Playlist to store back + */ +void MusicSystem::SaveCustomPlaylist(PlaylistChoices pl) +{ + byte *settings_pl; + if (pl == PLCH_CUSTOM1) { + settings_pl = _settings_client.music.custom_1; + } else if (pl == PLCH_CUSTOM2) { + settings_pl = _settings_client.music.custom_2; + } else { + return; + } + + size_t num = 0; + MemSetT(settings_pl, 0, NUM_SONGS_PLAYLIST); + + for (Playlist::const_iterator song = this->standard_playlists[pl].begin(); song != this->standard_playlists[pl].end(); ++song) { + /* Music set indices in the settings playlist are 1-based, 0 means unused slot */ + settings_pl[num++] = (byte)song->set_index + 1; + } +} + + +/** + * Check music playback status and start/stop/song-finished. + * Called from main loop. + */ +void MusicLoop() +{ + _music.CheckStatus(); +} + +/** + * Change the configured music set and reset playback + * @param index Index of music set to switch to + */ +void ChangeMusicSet(int index) +{ + if (BaseMusic::GetIndexOfUsedSet() == index) return; + const char *name = BaseMusic::GetSet(index)->name; + _music.ChangeMusicSet(name); +} + +/** + * Prepare the music system for use. + * Called from \c InitializeGame + */ +void InitializeMusic() +{ + _music.BuildPlaylists(); +} + + struct MusicTrackSelectionWindow : public Window { MusicTrackSelectionWindow(WindowDesc *desc, WindowNumber number) : Window(desc) { @@ -312,6 +465,9 @@ struct MusicTrackSelectionWindow : public Window { case WID_MTS_PLAYLIST: SetDParam(0, STR_MUSIC_PLAYLIST_ALL + _settings_client.music.playlist); break; + case WID_MTS_CAPTION: + SetDParamStr(0, BaseMusic::GetUsedSet()->name); + break; } } @@ -349,13 +505,10 @@ struct MusicTrackSelectionWindow : public Window { case WID_MTS_LIST_LEFT: case WID_MTS_LIST_RIGHT: { Dimension d = {0, 0}; - for (uint i = 0; i < NUM_SONGS_AVAILABLE; i++) { - const char *song_name = GetSongName(i); - if (StrEmpty(song_name)) continue; - - SetDParam(0, GetTrackNumber(i)); + for (MusicSystem::Playlist::const_iterator song = _music.music_set.begin(); song != _music.music_set.end(); ++song) { + SetDParam(0, song->tracknr); SetDParam(1, 2); - SetDParamStr(2, GetSongName(i)); + SetDParamStr(2, song->songname); Dimension d2 = GetStringBoundingBox(STR_PLAYLIST_TRACK_NAME); d.width = max(d.width, d2.width); d.height += d2.height; @@ -375,13 +528,10 @@ struct MusicTrackSelectionWindow : public Window { GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK); int y = r.top + WD_FRAMERECT_TOP; - for (uint i = 0; i < NUM_SONGS_AVAILABLE; i++) { - const char *song_name = GetSongName(i); - if (StrEmpty(song_name)) continue; - - SetDParam(0, GetTrackNumber(i)); + for (MusicSystem::Playlist::const_iterator song = _music.music_set.begin(); song != _music.music_set.end(); ++song) { + SetDParam(0, song->tracknr); SetDParam(1, 2); - SetDParamStr(2, song_name); + SetDParamStr(2, song->songname); DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_PLAYLIST_TRACK_NAME); y += FONT_HEIGHT_SMALL; } @@ -392,11 +542,10 @@ struct MusicTrackSelectionWindow : public Window { GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK); int y = r.top + WD_FRAMERECT_TOP; - for (const byte *p = _playlists[_settings_client.music.playlist]; *p != 0; p++) { - uint i = *p - 1; - SetDParam(0, GetTrackNumber(i)); + for (MusicSystem::Playlist::const_iterator song = _music.active_playlist.begin(); song != _music.active_playlist.end(); ++song) { + SetDParam(0, song->tracknr); SetDParam(1, 2); - SetDParamStr(2, GetSongName(i)); + SetDParamStr(2, song->songname); DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_PLAYLIST_TRACK_NAME); y += FONT_HEIGHT_SMALL; } @@ -410,66 +559,51 @@ struct MusicTrackSelectionWindow : public Window { switch (widget) { case WID_MTS_LIST_LEFT: { // add to playlist int y = this->GetRowFromWidget(pt.y, widget, 0, FONT_HEIGHT_SMALL); - - if (_settings_client.music.playlist < 4) return; - if (!IsInsideMM(y, 0, BaseMusic::GetUsedSet()->num_available)) return; - - byte *p = _playlists[_settings_client.music.playlist]; - for (uint i = 0; i != NUM_SONGS_PLAYLIST - 1; i++) { - if (p[i] == 0) { - /* Find the actual song number */ - for (uint j = 0; j < NUM_SONGS_AVAILABLE; j++) { - if (GetTrackNumber(j) == y + 1) { - p[i] = j + 1; - break; - } - } - p[i + 1] = 0; - this->SetDirty(); - SelectSongToPlay(); - break; - } - } + _music.PlaylistAdd(y); break; } case WID_MTS_LIST_RIGHT: { // remove from playlist int y = this->GetRowFromWidget(pt.y, widget, 0, FONT_HEIGHT_SMALL); + _music.PlaylistRemove(y); + break; + } - if (_settings_client.music.playlist < 4) return; - if (!IsInsideMM(y, 0, NUM_SONGS_PLAYLIST)) return; - - byte *p = _playlists[_settings_client.music.playlist]; - for (uint i = y; i != NUM_SONGS_PLAYLIST - 1; i++) { - p[i] = p[i + 1]; - } - - this->SetDirty(); - SelectSongToPlay(); + case WID_MTS_MUSICSET: { + int selected = 0; + DropDownList *dropdown = BuildMusicSetDropDownList(&selected); + ShowDropDownList(this, dropdown, selected, widget, 0, true, false); break; } case WID_MTS_CLEAR: // clear - for (uint i = 0; _playlists[_settings_client.music.playlist][i] != 0; i++) _playlists[_settings_client.music.playlist][i] = 0; - this->SetDirty(); - StopMusic(); - SelectSongToPlay(); + _music.PlaylistClear(); break; case WID_MTS_ALL: case WID_MTS_OLD: case WID_MTS_NEW: case WID_MTS_EZY: case WID_MTS_CUSTOM1: case WID_MTS_CUSTOM2: // set playlist - SelectPlaylist(widget - WID_MTS_ALL); - StopMusic(); - SelectSongToPlay(); + _music.ChangePlaylist((MusicSystem::PlaylistChoices)(widget - WID_MTS_ALL)); break; } } + + virtual void OnDropdownSelect(int widget, int index) + { + switch (widget) { + case WID_MTS_MUSICSET: + ChangeMusicSet(index); + break; + default: + NOT_REACHED(); + } + } }; static const NWidgetPart _nested_music_track_selection_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), - NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_PLAYLIST_MUSIC_PROGRAM_SELECTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_CAPTION, COLOUR_GREY, WID_MTS_CAPTION), SetDataTip(STR_PLAYLIST_MUSIC_SELECTION_SETNAME, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_MTS_MUSICSET), SetDataTip(STR_PLAYLIST_CHANGE_SET, STR_PLAYLIST_TOOLTIP_CHANGE_SET), EndContainer(), NWidget(WWT_PANEL, COLOUR_GREY), NWidget(NWID_HORIZONTAL), SetPIP(2, 4, 2), @@ -522,6 +656,20 @@ struct MusicWindow : public Window { this->InitNested(number); this->LowerWidget(_settings_client.music.playlist + WID_M_ALL); this->SetWidgetLoweredState(WID_M_SHUFFLE, _settings_client.music.shuffle); + + UpdateDisabledButtons(); + } + + void UpdateDisabledButtons() + { + /* Disable music control widgets if there is no music + * -- except Programme button! So you can still select a music set. */ + this->SetWidgetsDisabledState( + BaseMusic::GetUsedSet()->num_available == 0, + WID_M_PREV, WID_M_NEXT, WID_M_STOP, WID_M_PLAY, WID_M_SHUFFLE, + WID_M_ALL, WID_M_OLD, WID_M_NEW, WID_M_EZY, WID_M_CUSTOM1, WID_M_CUSTOM2, + WIDGET_LIST_END + ); } virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) @@ -548,8 +696,8 @@ struct MusicWindow : public Window { case WID_M_TRACK_NAME: { Dimension d = GetStringBoundingBox(STR_MUSIC_TITLE_NONE); - for (uint i = 0; i < NUM_SONGS_AVAILABLE; i++) { - SetDParamStr(0, GetSongName(i)); + for (MusicSystem::Playlist::const_iterator song = _music.music_set.begin(); song != _music.music_set.end(); ++song) { + SetDParamStr(0, song->songname); d = maxdim(d, GetStringBoundingBox(STR_MUSIC_TITLE_NAME)); } d.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; @@ -571,9 +719,12 @@ struct MusicWindow : public Window { switch (widget) { case WID_M_TRACK_NR: { GfxFillRect(r.left + 1, r.top + 1, r.right, r.bottom, PC_BLACK); + if (BaseMusic::GetUsedSet()->num_available == 0) { + break; + } StringID str = STR_MUSIC_TRACK_NONE; - if (_song_is_active != 0 && _music_wnd_cursong != 0) { - SetDParam(0, GetTrackNumber(_music_wnd_cursong - 1)); + if (_music.IsPlaying()) { + SetDParam(0, _music.GetCurrentSong().tracknr); SetDParam(1, 2); str = STR_MUSIC_TRACK_DIGIT; } @@ -584,24 +735,24 @@ struct MusicWindow : public Window { case WID_M_TRACK_NAME: { GfxFillRect(r.left, r.top + 1, r.right - 1, r.bottom, PC_BLACK); StringID str = STR_MUSIC_TITLE_NONE; - if (_song_is_active != 0 && _music_wnd_cursong != 0) { + if (BaseMusic::GetUsedSet()->num_available == 0) { + str = STR_MUSIC_TITLE_NOMUSIC; + } else if (_music.IsPlaying()) { str = STR_MUSIC_TITLE_NAME; - SetDParamStr(0, GetSongName(_music_wnd_cursong - 1)); + SetDParamStr(0, _music.GetCurrentSong().songname); } DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str, TC_FROMSTRING, SA_HOR_CENTER); break; } case WID_M_MUSIC_VOL: case WID_M_EFFECT_VOL: { - DrawFrameRect(r.left, r.top + 2, r.right, r.bottom - 2, COLOUR_GREY, FR_LOWERED); + int sw = ScaleGUITrad(slider_width); + int hsw = sw / 2; + DrawFrameRect(r.left + hsw, r.top + 2, r.right - hsw, r.bottom - 2, COLOUR_GREY, FR_LOWERED); byte volume = (widget == WID_M_MUSIC_VOL) ? _settings_client.music.music_vol : _settings_client.music.effect_vol; - int x = (volume * (r.right - r.left) / 127); - if (_current_text_dir == TD_RTL) { - x = r.right - x; - } else { - x += r.left; - } - DrawFrameRect(x, r.top, x + slider_width, r.bottom, COLOUR_GREY, FR_NONE); + if (_current_text_dir == TD_RTL) volume = 127 - volume; + int x = r.left + (volume * (r.right - r.left - sw) / 127); + DrawFrameRect(x, r.top, x + sw, r.bottom, COLOUR_GREY, FR_NONE); break; } } @@ -618,6 +769,9 @@ struct MusicWindow : public Window { for (int i = 0; i < 6; i++) { this->SetWidgetLoweredState(WID_M_ALL + i, i == _settings_client.music.playlist); } + + UpdateDisabledButtons(); + this->SetDirty(); } @@ -625,23 +779,19 @@ struct MusicWindow : public Window { { switch (widget) { case WID_M_PREV: // skip to prev - if (!_song_is_active) return; - SkipToPrevSong(); - this->SetDirty(); + _music.Prev(); break; case WID_M_NEXT: // skip to next - if (!_song_is_active) return; - SkipToNextSong(); - this->SetDirty(); + _music.Next(); break; case WID_M_STOP: // stop playing - _settings_client.music.playing = false; + _music.Stop(); break; case WID_M_PLAY: // start playing - _settings_client.music.playing = true; + _music.Play(); break; case WID_M_MUSIC_VOL: case WID_M_EFFECT_VOL: { // volume sliders @@ -651,9 +801,12 @@ struct MusicWindow : public Window { byte new_vol = x * 127 / this->GetWidget(widget)->current_x; if (_current_text_dir == TD_RTL) new_vol = 127 - new_vol; + /* Clamp to make sure min and max are properly settable */ + if (new_vol > 124) new_vol = 127; + if (new_vol < 3) new_vol = 0; if (new_vol != *vol) { *vol = new_vol; - if (widget == WID_M_MUSIC_VOL) MusicVolumeChanged(new_vol); + if (widget == WID_M_MUSIC_VOL) MusicDriver::GetInstance()->SetVolume(new_vol); this->SetDirty(); } @@ -662,12 +815,13 @@ struct MusicWindow : public Window { } case WID_M_SHUFFLE: // toggle shuffle - _settings_client.music.shuffle ^= 1; - this->SetWidgetLoweredState(WID_M_SHUFFLE, _settings_client.music.shuffle); + if (_music.IsShuffle()) { + _music.Unshuffle(); + } else { + _music.Shuffle(); + } + this->SetWidgetLoweredState(WID_M_SHUFFLE, _music.IsShuffle()); this->SetWidgetDirty(WID_M_SHUFFLE); - StopMusic(); - SelectSongToPlay(); - this->SetDirty(); break; case WID_M_PROGRAMME: // show track selection @@ -676,10 +830,7 @@ struct MusicWindow : public Window { case WID_M_ALL: case WID_M_OLD: case WID_M_NEW: case WID_M_EZY: case WID_M_CUSTOM1: case WID_M_CUSTOM2: // playlist - SelectPlaylist(widget - WID_M_ALL); - StopMusic(); - SelectSongToPlay(); - this->SetDirty(); + _music.ChangePlaylist((MusicSystem::PlaylistChoices)(widget - WID_M_ALL)); break; } } @@ -776,6 +927,5 @@ static WindowDesc _music_window_desc( void ShowMusicWindow() { - if (BaseMusic::GetUsedSet()->num_available == 0) ShowErrorMessage(STR_ERROR_NO_SONGS, INVALID_STRING_ID, WL_WARNING); AllocateWindowDescFront(&_music_window_desc, 0); } diff --git a/src/network/core/core.cpp b/src/network/core/core.cpp index 7a2ad92a29..c8db860dd5 100644 --- a/src/network/core/core.cpp +++ b/src/network/core/core.cpp @@ -64,7 +64,7 @@ bool NetworkCoreInitialize() #endif /* __MORPHOS__ / __AMIGA__ */ /* Let's load the network in windows */ -#ifdef WIN32 +#ifdef _WIN32 { WSADATA wsa; DEBUG(net, 3, "[core] loading windows socket library"); @@ -73,7 +73,7 @@ bool NetworkCoreInitialize() return false; } } -#endif /* WIN32 */ +#endif /* _WIN32 */ return true; } @@ -94,7 +94,7 @@ void NetworkCoreShutdown() if (SocketBase != NULL) CloseLibrary(SocketBase); #endif -#if defined(WIN32) +#if defined(_WIN32) WSACleanup(); #endif } diff --git a/src/network/core/host.cpp b/src/network/core/host.cpp index cf98239f86..216839032b 100644 --- a/src/network/core/host.cpp +++ b/src/network/core/host.cpp @@ -24,12 +24,7 @@ */ static void NetworkFindBroadcastIPsInternal(NetworkAddressList *broadcast); -#if defined(PSP) -static void NetworkFindBroadcastIPsInternal(NetworkAddressList *broadcast) // PSP implementation -{ -} - -#elif defined(BEOS_NET_SERVER) || defined(__HAIKU__) /* doesn't have neither getifaddrs or net/if.h */ +#if defined(BEOS_NET_SERVER) || defined(__HAIKU__) /* doesn't have neither getifaddrs or net/if.h */ /* Based on Andrew Bachmann's netstat+.c. Big thanks to him! */ extern "C" int _netstat(int fd, char **output, int verbose); @@ -112,7 +107,7 @@ static void NetworkFindBroadcastIPsInternal(NetworkAddressList *broadcast) // GE freeifaddrs(ifap); } -#elif defined(WIN32) +#elif defined(_WIN32) static void NetworkFindBroadcastIPsInternal(NetworkAddressList *broadcast) // Win32 implementation { SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0); diff --git a/src/network/core/os_abstraction.h b/src/network/core/os_abstraction.h index 9608f08fa7..c320cd9102 100644 --- a/src/network/core/os_abstraction.h +++ b/src/network/core/os_abstraction.h @@ -21,7 +21,7 @@ #ifdef ENABLE_NETWORK /* Windows stuff */ -#if defined(WIN32) || defined(WIN64) +#if defined(_WIN32) #include #include #include @@ -125,7 +125,7 @@ static inline void OTTDfreeaddrinfo(struct addrinfo *ai) } #define freeaddrinfo OTTDfreeaddrinfo #endif /* __MINGW32__ && __CYGWIN__ */ -#endif /* WIN32 */ +#endif /* _WIN32 */ /* UNIX stuff */ #if defined(UNIX) && !defined(__OS2__) @@ -194,29 +194,6 @@ static inline void OTTDfreeaddrinfo(struct addrinfo *ai) #define IPV6_V6ONLY 27 #endif -#if defined(PSP) -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -# define TCP_NODELAY 1 -# define SO_NONBLOCK 0x1009 -# define SOCKET int -# define INVALID_SOCKET -1 -# define INADDR_NONE 0xffffffff -# define closesocket close -# define GET_LAST_ERROR() sceNetInetGetErrno() -#endif /* PSP */ - /* OS/2 stuff */ #if defined(__OS2__) # define SOCKET int @@ -313,12 +290,12 @@ typedef unsigned long in_addr_t; */ static inline bool SetNonBlocking(SOCKET d) { -#ifdef WIN32 +#ifdef _WIN32 u_long nonblocking = 1; #else int nonblocking = 1; #endif -#if (defined(__BEOS__) && defined(BEOS_NET_SERVER)) || defined(PSP) +#if (defined(__BEOS__) && defined(BEOS_NET_SERVER)) return setsockopt(d, SOL_SOCKET, SO_NONBLOCK, &nonblocking, sizeof(nonblocking)) == 0; #else return ioctlsocket(d, FIONBIO, &nonblocking) == 0; diff --git a/src/network/core/tcp_game.cpp b/src/network/core/tcp_game.cpp index 9b3f7b5ef3..caa378fc4c 100644 --- a/src/network/core/tcp_game.cpp +++ b/src/network/core/tcp_game.cpp @@ -45,6 +45,8 @@ NetworkRecvStatus NetworkGameSocketHandler::CloseConnection(bool error) { /* Clients drop back to the main menu */ if (!_network_server && _networking) { + extern void ClientNetworkEmergencySave(); // from network_client.cpp + ClientNetworkEmergencySave(); _switch_mode = SM_MENU; _networking = false; ShowErrorMessage(STR_NETWORK_ERROR_LOSTCONNECTION, INVALID_STRING_ID, WL_CRITICAL); diff --git a/src/network/core/udp.cpp b/src/network/core/udp.cpp index 20b1ce1196..d2dc15d427 100644 --- a/src/network/core/udp.cpp +++ b/src/network/core/udp.cpp @@ -252,8 +252,8 @@ void NetworkUDPSocketHandler::ReceiveNetworkGameInfo(Packet *p, NetworkGameInfo *dst = c; dst = &c->next; } + FALLTHROUGH; } - FALLTHROUGH; case 3: info->game_date = Clamp(p->Recv_uint32(), 0, MAX_DATE); diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index e3bcbb2d87..4b066681d7 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -119,6 +119,19 @@ struct PacketReader : LoadFilter { }; +/** + * Create an emergency savegame when the network connection is lost. + */ +void ClientNetworkEmergencySave() +{ + if (!_settings_client.gui.autosave_on_network_disconnect) return; + + const char *filename = "netsave.sav"; + DEBUG(net, 0, "Client: Performing emergency save (%s)", filename); + SaveOrLoad(filename, SLO_SAVE, DFT_GAME_FILE, AUTOSAVE_DIR, false); +} + + /** * Create a new socket for the client side of the game connection. * @param s The socket to connect with. @@ -670,6 +683,9 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_ERROR(Packet *p ShowErrorMessage(err, INVALID_STRING_ID, WL_CRITICAL); + /* Perform an emergency save if we had already entered the game */ + if (this->status == STATUS_ACTIVE) ClientNetworkEmergencySave(); + DeleteWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN); return NETWORK_RECV_STATUS_SERVER_ERROR; @@ -1051,6 +1067,8 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_SHUTDOWN(Packet ShowErrorMessage(STR_NETWORK_MESSAGE_SERVER_SHUTDOWN, INVALID_STRING_ID, WL_CRITICAL); } + if (this->status == STATUS_ACTIVE) ClientNetworkEmergencySave(); + return NETWORK_RECV_STATUS_SERVER_ERROR; } @@ -1066,6 +1084,8 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_NEWGAME(Packet ShowErrorMessage(STR_NETWORK_MESSAGE_SERVER_REBOOT, INVALID_STRING_ID, WL_CRITICAL); } + if (this->status == STATUS_ACTIVE) ClientNetworkEmergencySave(); + return NETWORK_RECV_STATUS_SERVER_ERROR; } @@ -1153,6 +1173,7 @@ void ClientNetworkGameSocketHandler::CheckConnection() if (lag > 20) { this->NetworkGameSocketHandler::CloseConnection(); ShowErrorMessage(STR_NETWORK_ERROR_LOSTCONNECTION, INVALID_STRING_ID, WL_CRITICAL); + ClientNetworkEmergencySave(); return; } diff --git a/src/network/network_content_gui.cpp b/src/network/network_content_gui.cpp index 4b1332c589..1df2fc82c4 100644 --- a/src/network/network_content_gui.cpp +++ b/src/network/network_content_gui.cpp @@ -519,7 +519,7 @@ public: * Create the content list window. * @param desc the window description to pass to Window's constructor. * @param select_all Whether the select all button is allowed or not. - * @param type the main type of content to display or #CONTENT_TYPE_END. + * @param types the main type of content to display or #CONTENT_TYPE_END. * When a type other than #CONTENT_TYPE_END is given, dependencies of * other types are only shown when content that depend on them are * selected. diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index bcee408528..275b6200eb 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -1115,7 +1115,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMMAND(Packet } if ((GetCommandFlags(cp.cmd) & CMD_SPECTATOR) == 0 && !Company::IsValidID(cp.company) && ci->client_id != CLIENT_ID_SERVER) { - IConsolePrintF(CC_ERROR, "WARNING: spectator issueing command from client %d (IP: %s), kicking...", ci->client_id, this->GetClientIP()); + IConsolePrintF(CC_ERROR, "WARNING: spectator issuing command from client %d (IP: %s), kicking...", ci->client_id, this->GetClientIP()); return this->SendError(NETWORK_ERROR_KICKED); } @@ -2137,7 +2137,7 @@ bool NetworkCompanyHasClients(CompanyID company) /** - * Get the name of the client, if the user did not send it yet, Client # is used. + * Get the name of the client, if the user did not send it yet, Client ID is used. * @param client_name The variable to write the name to. * @param last The pointer to the last element of the destination buffer */ diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 5b1713709d..57dcb41ca5 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -194,7 +194,7 @@ static GrfProcessingState _cur; /** * Helper to check whether an image index is valid for a particular NewGRF vehicle. - * @param The type of vehicle. + * @tparam T The type of vehicle. * @param image_index The image index to check. * @return True iff the image index is valid, or 0xFD (use new graphics). */ @@ -313,8 +313,8 @@ struct GRFTempEngineData { Refittability refittability; ///< Did the newgrf set any refittability property? If not, default refittability will be applied. bool prop27_set; ///< Did the NewGRF set property 27 (misc flags)? uint8 rv_max_speed; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8 - uint32 ctt_include_mask; ///< Cargo types always included in the refit mask. - uint32 ctt_exclude_mask; ///< Cargo types always excluded from the refit mask. + CargoTypes ctt_include_mask; ///< Cargo types always included in the refit mask. + CargoTypes ctt_exclude_mask; ///< Cargo types always excluded from the refit mask. /** * Update the summary refittability on setting a refittability property. @@ -734,9 +734,9 @@ static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite) * @param invert_action1_flag Set to true, if palette bit 15 means 'not from action 1'. * @param use_cur_spritesets Whether to use currently referenceable action 1 sets. * @param feature GrfSpecFeature to use spritesets from. - * @param [out] grf_sprite Read sprite and palette. - * @param [out] max_sprite_offset Optionally returns the number of sprites in the spriteset of the sprite. (0 if no spritset) - * @param [out] max_palette_offset Optionally returns the number of sprites in the spriteset of the palette. (0 if no spritset) + * @param[out] grf_sprite Read sprite and palette. + * @param[out] max_sprite_offset Optionally returns the number of sprites in the spriteset of the sprite. (0 if no spritset) + * @param[out] max_palette_offset Optionally returns the number of sprites in the spriteset of the palette. (0 if no spritset) * @return Read TileLayoutFlags. */ static TileLayoutFlags ReadSpriteLayoutSprite(ByteReader *buf, bool read_flags, bool invert_action1_flag, bool use_cur_spritesets, int feature, PalSpriteID *grf_sprite, uint16 *max_sprite_offset = NULL, uint16 *max_palette_offset = NULL) @@ -943,11 +943,11 @@ static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool us } /** - * Translate the refit mask. + * Translate the refit mask. refit_mask is uint32 as it has not been mapped to CargoTypes. */ -static uint32 TranslateRefitMask(uint32 refit_mask) +static CargoTypes TranslateRefitMask(uint32 refit_mask) { - uint32 result = 0; + CargoTypes result = 0; uint8 bit; FOR_EACH_SET_BIT(bit, refit_mask) { CargoID cargo = GetCargoTranslation(bit, _cur.grffile, true); @@ -1310,7 +1310,7 @@ static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop uint8 count = buf->ReadByte(); _gted[e->index].UpdateRefittability(prop == 0x2C && count != 0); if (prop == 0x2C) _gted[e->index].defaultcargo_grf = _cur.grffile; - uint32 &ctt = prop == 0x2C ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask; + CargoTypes &ctt = prop == 0x2C ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask; ctt = 0; while (count--) { CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile); @@ -1498,7 +1498,7 @@ static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop uint8 count = buf->ReadByte(); _gted[e->index].UpdateRefittability(prop == 0x24 && count != 0); if (prop == 0x24) _gted[e->index].defaultcargo_grf = _cur.grffile; - uint32 &ctt = prop == 0x24 ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask; + CargoTypes &ctt = prop == 0x24 ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask; ctt = 0; while (count--) { CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile); @@ -1670,7 +1670,7 @@ static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop uint8 count = buf->ReadByte(); _gted[e->index].UpdateRefittability(prop == 0x1E && count != 0); if (prop == 0x1E) _gted[e->index].defaultcargo_grf = _cur.grffile; - uint32 &ctt = prop == 0x1E ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask; + CargoTypes &ctt = prop == 0x1E ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask; ctt = 0; while (count--) { CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile); @@ -1820,7 +1820,7 @@ static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int uint8 count = buf->ReadByte(); _gted[e->index].UpdateRefittability(prop == 0x1D && count != 0); if (prop == 0x1D) _gted[e->index].defaultcargo_grf = _cur.grffile; - uint32 &ctt = prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask; + CargoTypes &ctt = prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask; ctt = 0; while (count--) { CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile); @@ -1845,7 +1845,7 @@ static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int /** * Define properties for stations - * @param stdid StationID of the first station tile. + * @param stid StationID of the first station tile. * @param numinfo Number of subsequent station tiles to change the property for. * @param prop The property to change. * @param buf The property value. @@ -2036,9 +2036,10 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte break; case 0x12: // Cargo types for random triggers - statspec->cargo_triggers = buf->ReadDWord(); if (_cur.grffile->grf_version >= 7) { - statspec->cargo_triggers = TranslateRefitMask(statspec->cargo_triggers); + statspec->cargo_triggers = TranslateRefitMask(buf->ReadDWord()); + } else { + statspec->cargo_triggers = (CargoTypes)buf->ReadDWord(); } break; @@ -2552,7 +2553,7 @@ static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, Byt * @param gvid ID of the global variable. This is basically only checked for zerones. * @param numinfo Number of subsequent IDs to change the property for. * @param buf The property value. - * @param [in,out] translation_table Storage location for the translation table. + * @param[in,out] translation_table Storage location for the translation table. * @param name Name of the table for debug output. * @return ChangeInfoResult. */ @@ -3082,6 +3083,10 @@ static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf) buf->ReadWord(); break; + case 0x13: + buf->Skip(buf->ReadByte() * 2); + break; + default: ret = CIR_UNKNOWN; break; @@ -3171,7 +3176,7 @@ static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int pr case 0x0C: { uint16 acctp = buf->ReadWord(); tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur.grffile); - tsp->acceptance[prop - 0x0A] = GB(acctp, 8, 8); + tsp->acceptance[prop - 0x0A] = Clamp(GB(acctp, 8, 8), 0, 16); break; } @@ -3200,6 +3205,26 @@ static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int pr tsp->special_flags = (IndustryTileSpecialFlags)buf->ReadByte(); break; + case 0x13: { // variable length cargo acceptance + byte num_cargoes = buf->ReadByte(); + if (num_cargoes > lengthof(tsp->acceptance)) { + GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG); + error->param_value[1] = prop; + return CIR_DISABLED; + } + for (uint i = 0; i < lengthof(tsp->acceptance); i++) { + if (i < num_cargoes) { + tsp->accepts_cargo[i] = GetCargoTranslation(buf->ReadByte(), _cur.grffile); + /* Tile acceptance can be negative to counteract the INDTILE_SPECIAL_ACCEPTS_ALL_CARGO flag */ + tsp->acceptance[i] = (int8)buf->ReadByte(); + } else { + tsp->accepts_cargo[i] = CT_INVALID; + tsp->acceptance[i] = 0; + } + } + break; + } + default: ret = CIR_UNKNOWN; break; @@ -3279,11 +3304,17 @@ static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf) for (byte j = 0; j < 3; j++) buf->ReadByte(); break; - case 0x15: { - byte number_of_sounds = buf->ReadByte(); - for (uint8 j = 0; j < number_of_sounds; j++) { - buf->ReadByte(); - } + case 0x15: + case 0x25: + case 0x26: + case 0x27: + buf->Skip(buf->ReadByte()); + break; + + case 0x28: { + int num_inputs = buf->ReadByte(); + int num_outputs = buf->ReadByte(); + buf->Skip(num_inputs * num_outputs * 2); break; } @@ -3471,8 +3502,6 @@ static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, } else { /* Declared as been valid, can be used */ itt[k].gfx = tempid; - size = k + 1; - copy_from = itt; } } else if (itt[k].gfx == 0xFF) { itt[k].ti.x = (int8)GB(itt[k].ti.x, 0, 8); @@ -3643,6 +3672,77 @@ static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, break; } + case 0x25: { // variable length produced cargoes + byte num_cargoes = buf->ReadByte(); + if (num_cargoes > lengthof(indsp->produced_cargo)) { + GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG); + error->param_value[1] = prop; + return CIR_DISABLED; + } + for (uint i = 0; i < lengthof(indsp->produced_cargo); i++) { + if (i < num_cargoes) { + CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile); + indsp->produced_cargo[i] = cargo; + } else { + indsp->produced_cargo[i] = CT_INVALID; + } + } + break; + } + + case 0x26: { // variable length accepted cargoes + byte num_cargoes = buf->ReadByte(); + if (num_cargoes > lengthof(indsp->accepts_cargo)) { + GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG); + error->param_value[1] = prop; + return CIR_DISABLED; + } + for (uint i = 0; i < lengthof(indsp->accepts_cargo); i++) { + if (i < num_cargoes) { + CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile); + indsp->accepts_cargo[i] = cargo; + } else { + indsp->accepts_cargo[i] = CT_INVALID; + } + } + break; + } + + case 0x27: { // variable length production rates + byte num_cargoes = buf->ReadByte(); + if (num_cargoes > lengthof(indsp->production_rate)) { + GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG); + error->param_value[1] = prop; + return CIR_DISABLED; + } + for (uint i = 0; i < lengthof(indsp->production_rate); i++) { + if (i < num_cargoes) { + indsp->production_rate[i] = buf->ReadByte(); + } else { + indsp->production_rate[i] = 0; + } + } + break; + } + + case 0x28: { // variable size input/output production multiplier table + byte num_inputs = buf->ReadByte(); + byte num_outputs = buf->ReadByte(); + if (num_inputs > lengthof(indsp->accepts_cargo) || num_outputs > lengthof(indsp->produced_cargo)) { + GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG); + error->param_value[1] = prop; + return CIR_DISABLED; + } + for (uint i = 0; i < lengthof(indsp->accepts_cargo); i++) { + for (uint j = 0; j < lengthof(indsp->produced_cargo); j++) { + uint16 mult = 0; + if (i < num_inputs && j < num_outputs) mult = buf->ReadWord(); + indsp->input_cargo_multiplier[i][j] = mult; + } + } + break; + } + default: ret = CIR_UNKNOWN; break; @@ -3786,8 +3886,6 @@ static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, B } else { /* Declared as been valid, can be used */ att[k].gfx = tempid; - size = k + 1; - copy_from = att; } } else if (att[k].gfx == 0xFF) { att[k].ti.x = (int8)GB(att[k].ti.x, 0, 8); @@ -4740,7 +4838,7 @@ static void NewSpriteGroup(ByteReader *buf) } } - group->num_ranges = optimised.size(); + group->num_ranges = (uint)optimised.size(); // cast is safe, there should never be 2**31 elements here if (group->num_ranges > 0) { group->ranges = MallocT(group->num_ranges); MemCpyT(group->ranges, &optimised.front(), group->num_ranges); @@ -4842,7 +4940,7 @@ static void NewSpriteGroup(ByteReader *buf) } case GSF_INDUSTRIES: { - if (type > 1) { + if (type > 2) { grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type); break; } @@ -4852,21 +4950,63 @@ static void NewSpriteGroup(ByteReader *buf) act_group = group; group->version = type; if (type == 0) { + group->num_input = 3; for (uint i = 0; i < 3; i++) { group->subtract_input[i] = (int16)buf->ReadWord(); // signed } + group->num_output = 2; for (uint i = 0; i < 2; i++) { group->add_output[i] = buf->ReadWord(); // unsigned } group->again = buf->ReadByte(); - } else { + } else if (type == 1) { + group->num_input = 3; for (uint i = 0; i < 3; i++) { group->subtract_input[i] = buf->ReadByte(); } + group->num_output = 2; for (uint i = 0; i < 2; i++) { group->add_output[i] = buf->ReadByte(); } group->again = buf->ReadByte(); + } else if (type == 2) { + group->num_input = buf->ReadByte(); + if (group->num_input > lengthof(group->subtract_input)) { + GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK); + error->data = stredup("too many inputs (max 16)"); + return; + } + for (uint i = 0; i < group->num_input; i++) { + byte rawcargo = buf->ReadByte(); + CargoID cargo = GetCargoTranslation(rawcargo, _cur.grffile); + if (std::find(group->cargo_input, group->cargo_input + i, cargo) != group->cargo_input + i) { + GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK); + error->data = stredup("duplicate input cargo"); + return; + } + group->cargo_input[i] = cargo; + group->subtract_input[i] = buf->ReadByte(); + } + group->num_output = buf->ReadByte(); + if (group->num_output > lengthof(group->add_output)) { + GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK); + error->data = stredup("too many outputs (max 16)"); + return; + } + for (uint i = 0; i < group->num_output; i++) { + byte rawcargo = buf->ReadByte(); + CargoID cargo = GetCargoTranslation(rawcargo, _cur.grffile); + if (std::find(group->cargo_output, group->cargo_output + i, cargo) != group->cargo_output + i) { + GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK); + error->data = stredup("duplicate output cargo"); + return; + } + group->cargo_output[i] = cargo; + group->add_output[i] = buf->ReadByte(); + } + group->again = buf->ReadByte(); + } else { + NOT_REACHED(); } break; } @@ -5906,7 +6046,8 @@ static uint32 GetParamVal(byte param, uint32 *cond_val) /* Supported in Action 0x07 and 0x09, not 0x0D */ return 0; } else { - uint32 param_val = _ttdpatch_flags[*cond_val / 0x20]; + uint32 index = *cond_val / 0x20; + uint32 param_val = index < lengthof(_ttdpatch_flags) ? _ttdpatch_flags[index] : 0; *cond_val %= 0x20; return param_val; } @@ -7896,6 +8037,8 @@ static void InitializeGRFSpecial() | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18) // dynamic engines | (1 << 0x1E) // variablerunningcosts | (1 << 0x1F); // any switch is on + + _ttdpatch_flags[4] = (1 << 0x00); // larger persistent storage } /** Reset and clear all NewGRF stations */ @@ -8305,9 +8448,9 @@ static void CalculateRefitMasks() /* Did the newgrf specify any refitting? If not, use defaults. */ if (_gted[engine].refittability != GRFTempEngineData::UNSET) { - uint32 mask = 0; - uint32 not_mask = 0; - uint32 xor_mask = ei->refit_mask; + CargoTypes mask = 0; + CargoTypes not_mask = 0; + CargoTypes xor_mask = ei->refit_mask; /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo. * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */ @@ -8328,7 +8471,7 @@ static void CalculateRefitMasks() ei->refit_mask |= _gted[engine].ctt_include_mask; ei->refit_mask &= ~_gted[engine].ctt_exclude_mask; } else { - uint32 xor_mask = 0; + CargoTypes xor_mask = 0; /* Don't apply default refit mask to wagons nor engines with no capacity */ if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) { diff --git a/src/newgrf_airport.cpp b/src/newgrf_airport.cpp index 0863d09861..6213097bd0 100644 --- a/src/newgrf_airport.cpp +++ b/src/newgrf_airport.cpp @@ -216,7 +216,6 @@ void AirportOverrideManager::SetEntitySpec(AirportSpec *as) /** * Store a value into the object's persistent storage. - * @param object Object that we want to query. * @param pos Position in the persistent storage to use. * @param value Value to store. */ diff --git a/src/newgrf_animation_base.h b/src/newgrf_animation_base.h index 7b94031fbd..791f3d691a 100644 --- a/src/newgrf_animation_base.h +++ b/src/newgrf_animation_base.h @@ -31,7 +31,6 @@ template active_sel == NULL || !this->editable) break; @@ -1089,8 +1089,8 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { break; } /* With double click, continue */ + FALLTHROUGH; } - FALLTHROUGH; case WID_NS_ADD: if (this->avail_sel == NULL || !this->editable || HasBit(this->avail_sel->flags, GCF_INVALID)) break; @@ -1584,8 +1584,8 @@ NewGRFWindow::GUIGRFConfigList::FilterFunction * const NewGRFWindow::filter_func /** * Custom nested widget container for the NewGRF gui. * Depending on the space in the gui, it uses either - * - two column mode, put the #acs and the #avs underneath each other and the #info next to it, or - * - three column mode, put the #avs, #acs, and #info each in its own column. + * - two column mode, put the #acs and the #avs underneath each other and the #inf next to it, or + * - three column mode, put the #avs, #acs, and #inf each in its own column. */ class NWidgetNewGRFDisplay : public NWidgetContainer { public: diff --git a/src/newgrf_house.cpp b/src/newgrf_house.cpp index ebdd858a4d..314f02b3dc 100644 --- a/src/newgrf_house.cpp +++ b/src/newgrf_house.cpp @@ -56,7 +56,7 @@ static const GRFFile *GetHouseSpecGrf(HouseID house_id) */ HouseResolverObject::HouseResolverObject(HouseID house_id, TileIndex tile, Town *town, CallbackID callback, uint32 param1, uint32 param2, - bool not_yet_constructed, uint8 initial_random_bits, uint32 watched_cargo_triggers) + bool not_yet_constructed, uint8 initial_random_bits, CargoTypes watched_cargo_triggers) : ResolverObject(GetHouseSpecGrf(house_id), callback, param1, param2), house_scope(*this, house_id, tile, town, not_yet_constructed, initial_random_bits, watched_cargo_triggers), town_scope(*this, town, not_yet_constructed) // Don't access StorePSA if house is not yet constructed. @@ -409,7 +409,7 @@ static uint32 GetDistanceFromNearbyHouse(uint8 parameter, TileIndex tile, HouseI } uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile, - bool not_yet_constructed, uint8 initial_random_bits, uint32 watched_cargo_triggers) + bool not_yet_constructed, uint8 initial_random_bits, CargoTypes watched_cargo_triggers) { assert(IsValidTile(tile) && (not_yet_constructed || IsTileType(tile, MP_HOUSE))); @@ -472,13 +472,13 @@ void DrawNewHouseTile(TileInfo *ti, HouseID house_id) } /* Simple wrapper for GetHouseCallback to keep the animation unified. */ -uint16 GetSimpleHouseCallback(CallbackID callback, uint32 param1, uint32 param2, const HouseSpec *spec, Town *town, TileIndex tile, uint32 extra_data) +uint16 GetSimpleHouseCallback(CallbackID callback, uint32 param1, uint32 param2, const HouseSpec *spec, Town *town, TileIndex tile, CargoTypes extra_data) { return GetHouseCallback(callback, param1, param2, spec - HouseSpec::Get(0), town, tile, false, 0, extra_data); } /** Helper class for animation control. */ -struct HouseAnimationBase : public AnimationBase { +struct HouseAnimationBase : public AnimationBase { static const CallbackID cb_animation_speed = CBID_HOUSE_ANIMATION_SPEED; static const CallbackID cb_animation_next_frame = CBID_HOUSE_ANIMATION_NEXT_FRAME; @@ -633,7 +633,7 @@ void TriggerHouse(TileIndex t, HouseTrigger trigger) * @param trigger_cargoes Cargo types that triggered the callback. * @param random Random bits. */ -void DoWatchedCargoCallback(TileIndex tile, TileIndex origin, uint32 trigger_cargoes, uint16 random) +void DoWatchedCargoCallback(TileIndex tile, TileIndex origin, CargoTypes trigger_cargoes, uint16 random) { TileIndexDiffC diff = TileIndexToTileIndexDiffC(origin, tile); uint32 cb_info = random << 16 | (uint8)diff.y << 8 | (uint8)diff.x; @@ -646,7 +646,7 @@ void DoWatchedCargoCallback(TileIndex tile, TileIndex origin, uint32 trigger_car * @param trigger_cargoes Triggering cargo types. * @pre IsTileType(t, MP_HOUSE) */ -void WatchedCargoCallback(TileIndex tile, uint32 trigger_cargoes) +void WatchedCargoCallback(TileIndex tile, CargoTypes trigger_cargoes) { assert(IsTileType(tile, MP_HOUSE)); HouseID id = GetHouseType(tile); diff --git a/src/newgrf_house.h b/src/newgrf_house.h index 0ac868d1e7..bb364f6fc6 100644 --- a/src/newgrf_house.h +++ b/src/newgrf_house.h @@ -25,7 +25,7 @@ struct HouseScopeResolver : public ScopeResolver { Town *town; ///< Town of this house. bool not_yet_constructed; ///< True for construction check. uint16 initial_random_bits; ///< Random bits during construction checks. - uint32 watched_cargo_triggers; ///< Cargo types that triggered the watched cargo callback. + CargoTypes watched_cargo_triggers; ///< Cargo types that triggered the watched cargo callback. /** * Constructor of a house scope resolver. @@ -38,7 +38,7 @@ struct HouseScopeResolver : public ScopeResolver { * @param watched_cargo_triggers Cargo types that triggered the watched cargo callback. */ HouseScopeResolver(ResolverObject &ro, HouseID house_id, TileIndex tile, Town *town, - bool not_yet_constructed, uint8 initial_random_bits, uint32 watched_cargo_triggers) + bool not_yet_constructed, uint8 initial_random_bits, CargoTypes watched_cargo_triggers) : ScopeResolver(ro), house_id(house_id), tile(tile), town(town), not_yet_constructed(not_yet_constructed), initial_random_bits(initial_random_bits), watched_cargo_triggers(watched_cargo_triggers) { @@ -56,7 +56,7 @@ struct HouseResolverObject : public ResolverObject { HouseResolverObject(HouseID house_id, TileIndex tile, Town *town, CallbackID callback = CBID_NO_CALLBACK, uint32 param1 = 0, uint32 param2 = 0, - bool not_yet_constructed = false, uint8 initial_random_bits = 0, uint32 watched_cargo_triggers = 0); + bool not_yet_constructed = false, uint8 initial_random_bits = 0, CargoTypes watched_cargo_triggers = 0); /* virtual */ ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) { @@ -97,8 +97,8 @@ void AnimateNewHouseTile(TileIndex tile); void AnimateNewHouseConstruction(TileIndex tile); uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile, - bool not_yet_constructed = false, uint8 initial_random_bits = 0, uint32 watched_cargo_triggers = 0); -void WatchedCargoCallback(TileIndex tile, uint32 trigger_cargoes); + bool not_yet_constructed = false, uint8 initial_random_bits = 0, CargoTypes watched_cargo_triggers = 0); +void WatchedCargoCallback(TileIndex tile, CargoTypes trigger_cargoes); bool CanDeleteHouse(TileIndex tile); diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp index 7815ba36af..de388c0234 100644 --- a/src/newgrf_industries.cpp +++ b/src/newgrf_industries.cpp @@ -304,6 +304,33 @@ static uint32 GetCountAndDistanceOfClosestInstance(byte param_setID, byte layout return GetCountAndDistanceOfClosestInstance(parameter, layout_filter, town_filter, this->industry); } + case 0x69: + case 0x6A: + case 0x6B: + case 0x6C: + case 0x6D: { + CargoID cargo = GetCargoTranslation(parameter, this->ro.grffile); + int index = this->industry->GetCargoProducedIndex(cargo); + if (index < 0) return 0; // invalid cargo + if (variable == 0x69) return this->industry->produced_cargo_waiting[index]; + if (variable == 0x6A) return this->industry->this_month_production[index]; + if (variable == 0x6B) return this->industry->this_month_transported[index]; + if (variable == 0x6C) return this->industry->last_month_production[index]; + if (variable == 0x6D) return this->industry->last_month_transported[index]; + NOT_REACHED(); + } + + + case 0x6E: + case 0x6F: { + CargoID cargo = GetCargoTranslation(parameter, this->ro.grffile); + int index = this->industry->GetCargoAcceptedIndex(cargo); + if (index < 0) return 0; // invalid cargo + if (variable == 0x6E) return this->industry->last_cargo_accepted_at[index]; + if (variable == 0x6F) return this->industry->incoming_cargo_waiting[index]; + NOT_REACHED(); + } + /* Get a variable from the persistent storage */ case 0x7C: return (this->industry->psa != NULL) ? this->industry->psa->GetValue(parameter) : 0; @@ -364,7 +391,10 @@ static uint32 GetCountAndDistanceOfClosestInstance(byte param_setID, byte layout case 0xB0: return Clamp(this->industry->construction_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535); // Date when built since 1920 (in days) case 0xB3: return this->industry->construction_type; // Construction type - case 0xB4: return Clamp(this->industry->last_cargo_accepted_at - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535); // Date last cargo accepted since 1920 (in days) + case 0xB4: { + Date *latest = std::max_element(this->industry->last_cargo_accepted_at, endof(this->industry->last_cargo_accepted_at)); + return Clamp((*latest) - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535); // Date last cargo accepted since 1920 (in days) + } } DEBUG(grf, 1, "Unhandled industry variable 0x%X", variable); @@ -415,7 +445,7 @@ static const GRFFile *GetGrffile(IndustryType type) /** * Constructor of the industries resolver. * @param tile %Tile owned by the industry. - * @param industry %Industry being resolved. + * @param indus %Industry being resolved. * @param type Type of the industry. * @param random_bits Random bits of the new industry. * @param callback Callback ID. @@ -575,13 +605,28 @@ void IndustryProductionCallback(Industry *ind, int reason) if (tgroup == NULL || tgroup->type != SGT_INDUSTRY_PRODUCTION) break; const IndustryProductionSpriteGroup *group = (const IndustryProductionSpriteGroup *)tgroup; - bool deref = (group->version == 1); + bool deref = (group->version >= 1); - for (uint i = 0; i < 3; i++) { - ind->incoming_cargo_waiting[i] = Clamp(ind->incoming_cargo_waiting[i] - DerefIndProd(group->subtract_input[i], deref) * multiplier, 0, 0xFFFF); - } - for (uint i = 0; i < 2; i++) { - ind->produced_cargo_waiting[i] = Clamp(ind->produced_cargo_waiting[i] + max(DerefIndProd(group->add_output[i], deref), 0) * multiplier, 0, 0xFFFF); + if (group->version < 2) { + /* Callback parameters map directly to industry cargo slot indices */ + for (uint i = 0; i < group->num_input; i++) { + ind->incoming_cargo_waiting[i] = Clamp(ind->incoming_cargo_waiting[i] - DerefIndProd(group->subtract_input[i], deref) * multiplier, 0, 0xFFFF); + } + for (uint i = 0; i < group->num_output; i++) { + ind->produced_cargo_waiting[i] = Clamp(ind->produced_cargo_waiting[i] + max(DerefIndProd(group->add_output[i], deref), 0) * multiplier, 0, 0xFFFF); + } + } else { + /* Callback receives list of cargos to apply for, which need to have their cargo slots in industry looked up */ + for (uint i = 0; i < group->num_input; i++) { + int cargo_index = ind->GetCargoAcceptedIndex(group->cargo_input[i]); + if (cargo_index < 0) continue; + ind->incoming_cargo_waiting[cargo_index] = Clamp(ind->incoming_cargo_waiting[cargo_index] - DerefIndProd(group->subtract_input[i], deref) * multiplier, 0, 0xFFFF); + } + for (uint i = 0; i < group->num_output; i++) { + int cargo_index = ind->GetCargoProducedIndex(group->cargo_output[i]); + if (cargo_index < 0) continue; + ind->produced_cargo_waiting[cargo_index] = Clamp(ind->produced_cargo_waiting[cargo_index] + max(DerefIndProd(group->add_output[i], deref), 0) * multiplier, 0, 0xFFFF); + } } int32 again = DerefIndProd(group->again, deref); @@ -602,7 +647,7 @@ void IndustryProductionCallback(Industry *ind, int reason) */ bool IndustryTemporarilyRefusesCargo(Industry *ind, CargoID cargo_type) { - assert(cargo_type == ind->accepts_cargo[0] || cargo_type == ind->accepts_cargo[1] || cargo_type == ind->accepts_cargo[2]); + assert(std::find(ind->accepts_cargo, endof(ind->accepts_cargo), cargo_type) != endof(ind->accepts_cargo)); const IndustrySpec *indspec = GetIndustrySpec(ind->type); if (HasBit(indspec->callback_mask, CBM_IND_REFUSE_CARGO)) { diff --git a/src/newgrf_industrytiles.cpp b/src/newgrf_industrytiles.cpp index 69c4b1d07d..0b2a55000e 100644 --- a/src/newgrf_industrytiles.cpp +++ b/src/newgrf_industrytiles.cpp @@ -296,7 +296,7 @@ bool StartStopIndustryTileAnimation(const Industry *ind, IndustryAnimationTrigge * @param tile Industry tile to trigger. * @param trigger Trigger to trigger. * @param ind Industry of the tile. - * @param [in,out] reseed_industry Collects bits to reseed for the industry. + * @param[in,out] reseed_industry Collects bits to reseed for the industry. */ static void DoTriggerIndustryTile(TileIndex tile, IndustryTileTrigger trigger, Industry *ind, uint32 &reseed_industry) { diff --git a/src/newgrf_object.cpp b/src/newgrf_object.cpp index 78bbc52443..1501cb9b8a 100644 --- a/src/newgrf_object.cpp +++ b/src/newgrf_object.cpp @@ -96,7 +96,9 @@ uint ObjectSpec::Index() const void ResetObjects() { /* Clean the pool. */ - MemSetT(_object_specs, 0, lengthof(_object_specs)); + for (uint16 i = 0; i < NUM_OBJECTS; i++) { + _object_specs[i] = {}; + } /* And add our originals. */ MemCpyT(_object_specs, _original_objects, lengthof(_original_objects)); @@ -348,8 +350,8 @@ unhandled: * @param tile %Tile of the object. * @param view View of the object. * @param callback Callback ID. - * @param callback_param1 First parameter (var 10) of the callback. - * @param callback_param2 Second parameter (var 18) of the callback. + * @param param1 First parameter (var 10) of the callback. + * @param param2 Second parameter (var 18) of the callback. */ ObjectResolverObject::ObjectResolverObject(const ObjectSpec *spec, Object *obj, TileIndex tile, uint8 view, CallbackID callback, uint32 param1, uint32 param2) diff --git a/src/newgrf_object.h b/src/newgrf_object.h index 69e1a3299c..43c8de031c 100644 --- a/src/newgrf_object.h +++ b/src/newgrf_object.h @@ -138,8 +138,8 @@ struct ObjectResolverObject : public ResolverObject { case VSG_SCOPE_PARENT: { TownScopeResolver *tsr = this->GetTown(); if (tsr != NULL) return tsr; + FALLTHROUGH; } - FALLTHROUGH; default: return ResolverObject::GetScope(scope, relative); diff --git a/src/newgrf_railtype.cpp b/src/newgrf_railtype.cpp index 624b0eca84..8421844717 100644 --- a/src/newgrf_railtype.cpp +++ b/src/newgrf_railtype.cpp @@ -87,8 +87,8 @@ RailTypeResolverObject::RailTypeResolverObject(const RailtypeInfo *rti, TileInde * @param rti The rail type data (spec). * @param tile The tile to get the sprite for. * @param rtsg The type of sprite to draw. - * @param content Where are we drawing the tile? - * @param [out] num_results If not NULL, return the number of sprites in the spriteset. + * @param context Where are we drawing the tile? + * @param[out] num_results If not NULL, return the number of sprites in the spriteset. * @return The sprite to draw. */ SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg, TileContext context, uint *num_results) diff --git a/src/newgrf_spritegroup.cpp b/src/newgrf_spritegroup.cpp index a5d689bbf9..1bcb4a0359 100644 --- a/src/newgrf_spritegroup.cpp +++ b/src/newgrf_spritegroup.cpp @@ -118,7 +118,7 @@ static inline uint32 GetVariable(const ResolverObject &object, ScopeResolver *sc /** * Store a value into the persistent storage area (PSA). Default implementation does nothing (for newgrf classes without storage). - * @param pos Position to store into. + * @param reg Position to store into. * @param value Value to store. */ /* virtual */ void ScopeResolver::StorePSA(uint reg, int32 value) {} @@ -144,21 +144,6 @@ static inline uint32 GetVariable(const ResolverObject &object, ScopeResolver *sc return &this->default_scope; } -/** - * Rotate val rot times to the right - * @param val the value to rotate - * @param rot the amount of times to rotate - * @return the rotated value - */ -static uint32 RotateRight(uint32 val, uint32 rot) -{ - /* Do not rotate more than necessary */ - rot %= 32; - - return (val >> rot) | (val << (32 - rot)); -} - - /* Evaluate an adjustment for a variable of the given size. * U is the unsigned type and S is the signed type to use. */ template @@ -191,7 +176,7 @@ static U EvalAdjustT(const DeterministicSpriteGroupAdjust *adjust, ScopeResolver case DSGA_OP_STO: _temp_store.StoreValue((U)value, (S)last_value); return last_value; case DSGA_OP_RST: return value; case DSGA_OP_STOP: scope->StorePSA((U)value, (S)last_value); return last_value; - case DSGA_OP_ROR: return RotateRight(last_value, value); + case DSGA_OP_ROR: return ROR((U)last_value, (U)value & 0x1F); // mask 'value' to 5 bits, which should behave the same on all architectures. case DSGA_OP_SCMP: return ((S)last_value == (S)value) ? 1 : ((S)last_value < (S)value ? 0 : 2); case DSGA_OP_UCMP: return ((U)last_value == (U)value) ? 1 : ((U)last_value < (U)value ? 0 : 2); case DSGA_OP_SHL: return (uint32)(U)last_value << ((U)value & 0x1F); // Same behaviour as in ParamSet, mask 'value' to 5 bits, which should behave the same on all architectures. @@ -308,7 +293,7 @@ const SpriteGroup *RealSpriteGroup::Resolve(ResolverObject &object) const * Process registers and the construction stage into the sprite layout. * The passed construction stage might get reset to zero, if it gets incorporated into the layout * during the preprocessing. - * @param [in, out] stage Construction stage (0-3), or NULL if not applicable. + * @param[in,out] stage Construction stage (0-3), or NULL if not applicable. * @return sprite layout to draw. */ const DrawTileSprites *TileLayoutSpriteGroup::ProcessRegisters(uint8 *stage) const diff --git a/src/newgrf_spritegroup.h b/src/newgrf_spritegroup.h index 6adf7c2ac8..6f038fd138 100644 --- a/src/newgrf_spritegroup.h +++ b/src/newgrf_spritegroup.h @@ -15,6 +15,7 @@ #include "town_type.h" #include "engine_type.h" #include "house_type.h" +#include "industry_type.h" #include "newgrf_callbacks.h" #include "newgrf_generic.h" @@ -277,9 +278,14 @@ struct IndustryProductionSpriteGroup : SpriteGroup { IndustryProductionSpriteGroup() : SpriteGroup(SGT_INDUSTRY_PRODUCTION) {} uint8 version; - int16 subtract_input[3]; // signed - uint16 add_output[2]; // unsigned + uint8 num_input; ///< How many subtract_input values are valid + int16 subtract_input[INDUSTRY_NUM_INPUTS]; ///< Take this much of the input cargo (can be negative, is indirect in cb version 1+) + CargoID cargo_input[INDUSTRY_NUM_INPUTS]; ///< Which input cargoes to take from (only cb version 2) + uint8 num_output; ///< How many add_output values are valid + uint16 add_output[INDUSTRY_NUM_OUTPUTS]; ///< Add this much output cargo when successful (unsigned, is indirect in cb version 1+) + CargoID cargo_output[INDUSTRY_NUM_OUTPUTS]; ///< Which output cargoes to add to (only cb version 2) uint8 again; + }; /** diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index 41ef7af75c..d9b79c55a1 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -881,7 +881,7 @@ bool CanStationTileHaveWires(TileIndex tile) return statspec == NULL || !HasBit(statspec->wires, GetStationGfx(tile)); } -/** Wrapper for animation control, see #GetStationCallback. */ +/** Wrapper for animation control, see GetStationCallback. */ uint16 GetAnimStationCallback(CallbackID callback, uint32 param1, uint32 param2, const StationSpec *statspec, BaseStation *st, TileIndex tile, int extra_data) { return GetStationCallback(callback, param1, param2, statspec, st, tile); @@ -963,7 +963,7 @@ void TriggerStationRandomisation(Station *st, TileIndex tile, StationRandomTrigg uint32 whole_reseed = 0; ETileArea area = ETileArea(st, tile, tas[trigger]); - uint32 empty_mask = 0; + CargoTypes empty_mask = 0; if (trigger == SRT_CARGO_TAKEN) { /* Create a bitmask of completely empty cargo types to be matched */ for (CargoID i = 0; i < NUM_CARGO; i++) { diff --git a/src/newgrf_station.h b/src/newgrf_station.h index 5413a4c08f..123330d0ad 100644 --- a/src/newgrf_station.h +++ b/src/newgrf_station.h @@ -68,8 +68,8 @@ struct StationResolverObject : public ResolverObject { case VSG_SCOPE_PARENT: { TownScopeResolver *tsr = this->GetTown(); if (tsr != NULL) return tsr; + FALLTHROUGH; } - FALLTHROUGH; default: return ResolverObject::GetScope(scope, relative); @@ -153,7 +153,7 @@ struct StationSpec { */ uint16 cargo_threshold; - uint32 cargo_triggers; ///< Bitmask of cargo types which cause trigger re-randomizing + CargoTypes cargo_triggers; ///< Bitmask of cargo types which cause trigger re-randomizing byte callback_mask; ///< Bitmask of station callbacks that have to be called diff --git a/src/newgrf_storage.h b/src/newgrf_storage.h index ae9782d88c..a0c1558f8e 100644 --- a/src/newgrf_storage.h +++ b/src/newgrf_storage.h @@ -220,7 +220,7 @@ extern PersistentStoragePool _persistent_storage_pool; /** * Class for pooled persistent storage of data. */ -struct PersistentStorage : PersistentStorageArray, PersistentStoragePool::PoolItem<&_persistent_storage_pool> { +struct PersistentStorage : PersistentStorageArray, PersistentStoragePool::PoolItem<&_persistent_storage_pool> { /** We don't want GCC to zero our struct! It already is zeroed and has an index! */ PersistentStorage(const uint32 new_grfid, byte feature, TileIndex tile) { @@ -230,7 +230,7 @@ struct PersistentStorage : PersistentStorageArray, PersistentStorageP } }; -assert_compile(cpp_lengthof(OldPersistentStorage, storage) == cpp_lengthof(PersistentStorage, storage)); +assert_compile(cpp_lengthof(OldPersistentStorage, storage) <= cpp_lengthof(PersistentStorage, storage)); #define FOR_ALL_STORAGES_FROM(var, start) FOR_ALL_ITEMS_FROM(PersistentStorage, storage_index, var, start) #define FOR_ALL_STORAGES(var) FOR_ALL_STORAGES_FROM(var, 0) diff --git a/src/newgrf_text.cpp b/src/newgrf_text.cpp index eb4b11c5e0..b92b84355a 100644 --- a/src/newgrf_text.cpp +++ b/src/newgrf_text.cpp @@ -329,7 +329,7 @@ struct UnmappedChoiceList : ZeroedMemoryAllocator { * @param language_id The (NewGRF) language ID associated with this string. * @param allow_newlines Whether newlines are allowed in the string or not. * @param str The string to translate. - * @param [out] olen The length of the final string. + * @param[out] olen The length of the final string. * @param byte80 The control code to use as replacement for the 0x80-value. * @return The translated string. */ diff --git a/src/newgrf_town.cpp b/src/newgrf_town.cpp index 820e2be689..00fcf76b63 100644 --- a/src/newgrf_town.cpp +++ b/src/newgrf_town.cpp @@ -50,7 +50,7 @@ case 0x81: return GB(this->t->xy, 8, 8); case 0x82: return ClampToU16(this->t->cache.population); case 0x83: return GB(ClampToU16(this->t->cache.population), 8, 8); - case 0x8A: return this->t->grow_counter; + case 0x8A: return this->t->grow_counter / TOWN_GROWTH_TICKS; case 0x92: return this->t->flags; // In original game, 0x92 and 0x93 are really one word. Since flags is a byte, this is to adjust case 0x93: return 0; case 0x94: return ClampToU16(this->t->cache.squared_town_zone_radius[0]); @@ -82,7 +82,7 @@ case 0xAE: return this->t->have_ratings; case 0xB2: return this->t->statues; case 0xB6: return ClampToU16(this->t->cache.num_houses); - case 0xB9: return this->t->growth_rate & (~TOWN_GROW_RATE_CUSTOM); + case 0xB9: return this->t->growth_rate / TOWN_GROWTH_TICKS; case 0xBA: return ClampToU16(this->t->supplied[CT_PASSENGERS].new_max); case 0xBB: return GB(ClampToU16(this->t->supplied[CT_PASSENGERS].new_max), 8, 8); case 0xBC: return ClampToU16(this->t->supplied[CT_MAIL].new_max); diff --git a/src/news_gui.cpp b/src/news_gui.cpp index 94cfaccf93..71a39eb3a9 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -494,7 +494,7 @@ struct NewsWindow : Window { private: /** - * Moves the window so #newtop is new 'top' coordinate. Makes screen dirty where needed. + * Moves the window to a new #top coordinate. Makes screen dirty where needed. * @param newtop new top coordinate */ void SetWindowTop(int newtop) @@ -962,7 +962,6 @@ void ShowLastNewsMessage() * @param y position of the string * @param colour the colour the string will be shown in * @param *ni NewsItem being printed - * @param maxw maximum width of string in pixels */ static void DrawNewsString(uint left, uint right, int y, TextColour colour, const NewsItem *ni) { diff --git a/src/news_type.h b/src/news_type.h index fee7ae38e3..cad15ecbef 100644 --- a/src/news_type.h +++ b/src/news_type.h @@ -17,19 +17,6 @@ #include "strings_type.h" #include "sound_type.h" -/** Constants in the message options window. */ -enum MessageOptionsSpace { - MOS_WIDG_PER_SETTING = 4, ///< Number of widgets needed for each news category, starting at widget #WID_MO_START_OPTION. - - MOS_LEFT_EDGE = 6, ///< Number of pixels between left edge of the window and the options buttons column. - MOS_COLUMN_SPACING = 4, ///< Number of pixels between the buttons and the description columns. - MOS_RIGHT_EDGE = 6, ///< Number of pixels between right edge of the window and the options descriptions column. - MOS_BUTTON_SPACE = 10, ///< Additional space in the button with the option value (for better looks). - - MOS_ABOVE_GLOBAL_SETTINGS = 6, ///< Number of vertical pixels between the categories and the global options. - MOS_BOTTOM_EDGE = 6, ///< Number of pixels between bottom edge of the window and bottom of the global options. -}; - /** * Type of news. */ diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index f7ba0d995b..9f03813dfb 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -540,7 +540,7 @@ static CommandCost ClearTile_Object(TileIndex tile, DoCommandFlag flags) return cost; } -static void AddAcceptedCargo_Object(TileIndex tile, CargoArray &acceptance, uint32 *always_accepted) +static void AddAcceptedCargo_Object(TileIndex tile, CargoArray &acceptance, CargoTypes *always_accepted) { if (!IsObjectType(tile, OBJECT_HQ)) return; diff --git a/src/object_gui.cpp b/src/object_gui.cpp index 57c45d09c9..8aabcfdc46 100644 --- a/src/object_gui.cpp +++ b/src/object_gui.cpp @@ -520,10 +520,7 @@ static WindowDesc _build_object_desc( _nested_build_object_widgets, lengthof(_nested_build_object_widgets) ); -/** - * Show our object picker. - * @param w The toolbar window we're associated with. - */ +/** Show our object picker. */ void ShowBuildObjectPicker() { /* Don't show the place object button when there are no objects to place. */ diff --git a/src/openttd.cpp b/src/openttd.cpp index 6c85bc72d4..0ea484a104 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -63,6 +63,7 @@ #include "subsidy_func.h" #include "gfx_layout.h" #include "viewport_sprite_sorter.h" +#include "framerate_type.h" #include "linkgraph/linkgraphschedule.h" @@ -186,7 +187,7 @@ static void ShowHelp() " -P password = Password to join company\n" " -D [ip][:port] = Start dedicated server\n" " -l ip[:port] = Redirect DEBUG()\n" -#if !defined(__MORPHOS__) && !defined(__AMIGA__) && !defined(WIN32) +#if !defined(__MORPHOS__) && !defined(__AMIGA__) && !defined(_WIN32) " -f = Fork into the background (dedicated only)\n" #endif #endif /* ENABLE_NETWORK */ @@ -230,7 +231,7 @@ static void ShowHelp() /* ShowInfo put output to stderr, but version information should go * to stdout; this is the only exception */ -#if !defined(WIN32) && !defined(WIN64) +#if !defined(_WIN32) printf("%s\n", buf); #else ShowInfo(buf); @@ -268,7 +269,7 @@ static void WriteSavegameInfo(const char *name) /* ShowInfo put output to stderr, but version information should go * to stdout; this is the only exception */ -#if !defined(WIN32) && !defined(WIN64) +#if !defined(_WIN32) printf("%s\n", buf); #else ShowInfo(buf); @@ -360,8 +361,7 @@ static void LoadIntroGame(bool load_newgrfs = true) CheckForMissingGlyphs(); - /* Play main theme */ - if (MusicDriver::GetInstance()->IsSongPlaying()) ResetMusic(); + MusicLoop(); // ensure music is correct } void MakeNewgameSettingsLive() @@ -384,6 +384,9 @@ void MakeNewgameSettingsLive() _settings_game.ai_config[c] = NULL; if (_settings_newgame.ai_config[c] != NULL) { _settings_game.ai_config[c] = new AIConfig(_settings_newgame.ai_config[c]); + if (!AIConfig::GetConfig(c, AIConfig::SSS_FORCE_GAME)->HasScript()) { + AIConfig::GetConfig(c, AIConfig::SSS_FORCE_GAME)->Change(NULL); + } } } _settings_game.game_config = NULL; @@ -404,7 +407,7 @@ void OpenBrowser(const char *url) /** Callback structure of statements to be executed after the NewGRF scan. */ struct AfterNewGRFScan : NewGRFScanCallback { Year startyear; ///< The start year. - uint generation_seed; ///< Seed for the new game. + uint32 generation_seed; ///< Seed for the new game. char *dedicated_host; ///< Hostname for the dedicated server. uint16 dedicated_port; ///< Port for the dedicated server. char *network_conn; ///< Information about the server to connect to, or NULL. @@ -424,6 +427,9 @@ struct AfterNewGRFScan : NewGRFScanCallback { join_server_password(NULL), join_company_password(NULL), save_config_ptr(save_config_ptr), save_config(true) { + /* Visual C++ 2015 fails compiling this line (AfterNewGRFScan::generation_seed undefined symbol) + * if it's placed outside a member function, directly in the struct body. */ + assert_compile(sizeof(generation_seed) == sizeof(_settings_game.game_creation.generation_seed)); } virtual void OnNewGRFsScanned() @@ -527,7 +533,7 @@ static const OptionData _options[] = { GETOPT_SHORT_VALUE('l'), GETOPT_SHORT_VALUE('p'), GETOPT_SHORT_VALUE('P'), -#if !defined(__MORPHOS__) && !defined(__AMIGA__) && !defined(WIN32) +#if !defined(__MORPHOS__) && !defined(__AMIGA__) && !defined(_WIN32) GETOPT_SHORT_NOVAL('f'), #endif #endif /* ENABLE_NETWORK */ @@ -627,7 +633,7 @@ int openttd_main(int argc, char *argv[]) case 'r': ParseResolution(&resolution, mgo.opt); break; case 't': scanner->startyear = atoi(mgo.opt); break; case 'd': { -#if defined(WIN32) +#if defined(_WIN32) CreateConsole(); #endif if (mgo.opt != NULL) SetDebugString(mgo.opt); @@ -685,7 +691,7 @@ int openttd_main(int argc, char *argv[]) goto exit_noshutdown; } - case 'G': scanner->generation_seed = atoi(mgo.opt); break; + case 'G': scanner->generation_seed = strtoul(mgo.opt, NULL, 10); break; case 'c': free(_config_file); _config_file = stredup(mgo.opt); break; case 'x': scanner->save_config = false; break; case 'h': @@ -711,11 +717,6 @@ int openttd_main(int argc, char *argv[]) goto exit_noshutdown; } -#if defined(WINCE) && defined(_DEBUG) - /* Switch on debug lvl 4 for WinCE if Debug release, as you can't give params, and you most likely do want this information */ - SetDebugString("4"); -#endif - DeterminePaths(argv[0]); TarScanner::DoScan(TarScanner::BASESET); @@ -1010,9 +1011,9 @@ static void MakeNewEditorWorld() * Load the specified savegame but on error do different things. * If loading fails due to corrupt savegame, bad version, etc. go back to * a previous correct state. In the menu for example load the intro game again. - * @param mode mode of loading, either SL_LOAD or SL_OLD_LOAD - * @param newgm switch to this mode of loading fails due to some unknown error * @param filename file to be loaded + * @param fop mode of loading, always SLO_LOAD + * @param newgm switch to this mode of loading fails due to some unknown error * @param subdir default directory to look for filename, set to 0 if not needed * @param lf Load filter to use, if NULL: use filename + subdir. */ @@ -1361,6 +1362,14 @@ void StateGameLoop() { /* don't execute the state loop during pause */ if (_pause_mode != PM_UNPAUSED) { + PerformanceMeasurer::Paused(PFE_GAMELOOP); + PerformanceMeasurer::Paused(PFE_GL_ECONOMY); + PerformanceMeasurer::Paused(PFE_GL_TRAINS); + PerformanceMeasurer::Paused(PFE_GL_ROADVEHS); + PerformanceMeasurer::Paused(PFE_GL_SHIPS); + PerformanceMeasurer::Paused(PFE_GL_AIRCRAFT); + PerformanceMeasurer::Paused(PFE_GL_LANDSCAPE); + UpdateLandscapingLimits(); #ifndef DEBUG_DUMP_COMMANDS Game::GameLoop(); @@ -1368,6 +1377,9 @@ void StateGameLoop() CallWindowTickEvent(); return; } + + PerformanceMeasurer framerate(PFE_GAMELOOP); + PerformanceAccumulator::Reset(PFE_GL_LANDSCAPE); if (HasModalProgress()) return; Layouter::ReduceLineCache(); @@ -1426,11 +1438,6 @@ static void DoAutosave() { char buf[MAX_PATH]; -#if defined(PSP) - /* Autosaving in networking is too time expensive for the PSP */ - if (_networking) return; -#endif /* PSP */ - if (_settings_client.gui.keep_all_autosave) { GenerateDefaultSaveName(buf, lastof(buf)); strecat(buf, ".sav", lastof(buf)); diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index db812f6c53..ba8a1a060d 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -1948,7 +1948,6 @@ void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist, bool reset_order_indic * Clamp the service interval to the correct min/max. The actual min/max values * depend on whether it's in percent or days. * @param interval proposed service interval - * @param company_id the owner of the vehicle * @return Clamped service interval */ uint16 GetServiceIntervalClamped(uint interval, bool ispercent) @@ -2018,6 +2017,7 @@ VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v) switch (order->GetConditionVariable()) { case OCV_LOAD_PERCENTAGE: skip_order = OrderConditionCompare(occ, CalcPercentVehicleFilled(v, NULL), value); break; case OCV_RELIABILITY: skip_order = OrderConditionCompare(occ, ToPercent16(v->reliability), value); break; + case OCV_MAX_RELIABILITY: skip_order = OrderConditionCompare(occ, ToPercent16(v->GetEngine()->reliability), value); break; case OCV_MAX_SPEED: skip_order = OrderConditionCompare(occ, v->GetDisplayMaxSpeed() * 10 / 16, value); break; case OCV_AGE: skip_order = OrderConditionCompare(occ, v->age / DAYS_IN_LEAP_YEAR, value); break; case OCV_REQUIRES_SERVICE: skip_order = OrderConditionCompare(occ, v->NeedsServicing(), value); break; diff --git a/src/order_gui.cpp b/src/order_gui.cpp index 9045fac6b5..81350deb74 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -152,6 +152,7 @@ static const StringID _order_goto_dropdown_aircraft[] = { static const OrderConditionVariable _order_conditional_variable[] = { OCV_LOAD_PERCENTAGE, OCV_RELIABILITY, + OCV_MAX_RELIABILITY, OCV_MAX_SPEED, OCV_AGE, OCV_REMAINING_LIFETIME, diff --git a/src/order_type.h b/src/order_type.h index d3a771ce8b..ac66bfa38f 100644 --- a/src/order_type.h +++ b/src/order_type.h @@ -123,6 +123,7 @@ enum OrderConditionVariable { OCV_REQUIRES_SERVICE, ///< Skip when the vehicle requires service OCV_UNCONDITIONALLY, ///< Always skip OCV_REMAINING_LIFETIME, ///< Skip based on the remaining lifetime + OCV_MAX_RELIABILITY, ///< Skip based on the maximum reliability OCV_END }; diff --git a/src/os/macosx/string_osx.cpp b/src/os/macosx/string_osx.cpp new file mode 100644 index 0000000000..1c5d558855 --- /dev/null +++ b/src/os/macosx/string_osx.cpp @@ -0,0 +1,450 @@ +/* $Id$ */ + +/* + * 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 . + */ + +/** @file string_osx.cpp Functions related to localized text support on OSX. */ + +#include "../../stdafx.h" +#include "string_osx.h" +#include "../../string_func.h" +#include "../../strings_func.h" +#include "../../table/control_codes.h" +#include "../../fontcache.h" +#include "macos.h" + +#include + + +#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) +/** Cached current locale. */ +static CFLocaleRef _osx_locale = NULL; +/** CoreText cache for font information, cleared when OTTD changes fonts. */ +static CTFontRef _font_cache[FS_END]; + + +/** + * Wrapper for doing layouts with CoreText. + */ +class CoreTextParagraphLayout : public ParagraphLayouter { +private: + const CoreTextParagraphLayoutFactory::CharType *text_buffer; + ptrdiff_t length; + const FontMap& font_map; + + CTTypesetterRef typesetter; + + CFIndex cur_offset = 0; ///< Offset from the start of the current run from where to output. + +public: + /** Visual run contains data about the bit of text with the same font. */ + class CoreTextVisualRun : public ParagraphLayouter::VisualRun { + private: + std::vector glyphs; + std::vector positions; + std::vector glyph_to_char; + + int total_advance = 0; + Font *font; + + public: + CoreTextVisualRun(CTRunRef run, Font *font, const CoreTextParagraphLayoutFactory::CharType *buff); + + virtual const GlyphID *GetGlyphs() const { return &this->glyphs[0]; } + virtual const float *GetPositions() const { return &this->positions[0]; } + virtual const int *GetGlyphToCharMap() const { return &this->glyph_to_char[0]; } + + virtual const Font *GetFont() const { return this->font; } + virtual int GetLeading() const { return this->font->fc->GetHeight(); } + virtual int GetGlyphCount() const { return (int)this->glyphs.size(); } + int GetAdvance() const { return this->total_advance; } + }; + + /** A single line worth of VisualRuns. */ + class CoreTextLine : public AutoDeleteSmallVector, public ParagraphLayouter::Line { + public: + CoreTextLine(CTLineRef line, const FontMap &fontMapping, const CoreTextParagraphLayoutFactory::CharType *buff) + { + CFArrayRef runs = CTLineGetGlyphRuns(line); + for (CFIndex i = 0; i < CFArrayGetCount(runs); i++) { + CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(runs, i); + + /* Extract font information for this run. */ + CFRange chars = CTRunGetStringRange(run); + FontMap::const_iterator map = fontMapping.Begin(); + while (map < fontMapping.End() - 1 && map->first <= chars.location) map++; + + *this->Append() = new CoreTextVisualRun(run, map->second, buff); + } + CFRelease(line); + } + + virtual int GetLeading() const; + virtual int GetWidth() const; + virtual int CountRuns() const { return this->Length(); } + virtual const VisualRun *GetVisualRun(int run) const { return *this->Get(run); } + + int GetInternalCharLength(WChar c) const + { + /* CoreText uses UTF-16 internally which means we need to account for surrogate pairs. */ + return c >= 0x010000U ? 2 : 1; + } + }; + + CoreTextParagraphLayout(CTTypesetterRef typesetter, const CoreTextParagraphLayoutFactory::CharType *buffer, ptrdiff_t len, const FontMap &fontMapping) : text_buffer(buffer), length(len), font_map(fontMapping), typesetter(typesetter) + { + this->Reflow(); + } + + virtual ~CoreTextParagraphLayout() + { + CFRelease(this->typesetter); + } + + virtual void Reflow() + { + this->cur_offset = 0; + } + + virtual const Line *NextLine(int max_width); +}; + + +/** Get the width of an encoded sprite font character. */ +static CGFloat SpriteFontGetWidth(void *ref_con) +{ + FontSize fs = (FontSize)((size_t)ref_con >> 24); + WChar c = (WChar)((size_t)ref_con & 0xFFFFFF); + + return GetGlyphWidth(fs, c); +} + +static CTRunDelegateCallbacks _sprite_font_callback = { + kCTRunDelegateCurrentVersion, NULL, NULL, NULL, + &SpriteFontGetWidth +}; + +/* static */ ParagraphLayouter *CoreTextParagraphLayoutFactory::GetParagraphLayout(CharType *buff, CharType *buff_end, FontMap &fontMapping) +{ + if (!MacOSVersionIsAtLeast(10, 5, 0)) return NULL; + + /* Can't layout an empty string. */ + ptrdiff_t length = buff_end - buff; + if (length == 0) return NULL; + + /* Can't layout our in-built sprite fonts. */ + for (FontMap::const_iterator i = fontMapping.Begin(); i != fontMapping.End(); i++) { + if (i->second->fc->IsBuiltInFont()) return NULL; + } + + /* Make attributed string with embedded font information. */ + CFMutableAttributedStringRef str = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0); + CFAttributedStringBeginEditing(str); + + CFStringRef base = CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, buff, length, kCFAllocatorNull); + CFAttributedStringReplaceString(str, CFRangeMake(0, 0), base); + CFRelease(base); + + /* Apply font and colour ranges to our string. This is important to make sure + * that we get proper glyph boundaries on style changes. */ + int last = 0; + for (FontMap::const_iterator i = fontMapping.Begin(); i != fontMapping.End(); i++) { + if (i->first - last == 0) continue; + + if (_font_cache[i->second->fc->GetSize()] == NULL) { + /* Cache font information. */ + CFStringRef font_name = CFStringCreateWithCString(kCFAllocatorDefault, i->second->fc->GetFontName(), kCFStringEncodingUTF8); + _font_cache[i->second->fc->GetSize()] = CTFontCreateWithName(font_name, i->second->fc->GetFontSize(), NULL); + CFRelease(font_name); + } + CFAttributedStringSetAttribute(str, CFRangeMake(last, i->first - last), kCTFontAttributeName, _font_cache[i->second->fc->GetSize()]); + + CGColorRef color = CGColorCreateGenericGray((uint8)i->second->colour / 255.0f, 1.0f); // We don't care about the real colours, just that they are different. + CFAttributedStringSetAttribute(str, CFRangeMake(last, i->first - last), kCTForegroundColorAttributeName, color); + CGColorRelease(color); + + /* Install a size callback for our special sprite glyphs. */ + for (ssize_t c = last; c < i->first; c++) { + if (buff[c] >= SCC_SPRITE_START && buff[c] <= SCC_SPRITE_END) { + CTRunDelegateRef del = CTRunDelegateCreate(&_sprite_font_callback, (void *)(size_t)(buff[c] | (i->second->fc->GetSize() << 24))); + CFAttributedStringSetAttribute(str, CFRangeMake(c, 1), kCTRunDelegateAttributeName, del); + CFRelease(del); + } + } + + last = i->first; + } + CFAttributedStringEndEditing(str); + + /* Create and return typesetter for the string. */ + CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedString(str); + CFRelease(str); + + return typesetter != NULL ? new CoreTextParagraphLayout(typesetter, buff, length, fontMapping) : NULL; +} + +/* virtual */ const CoreTextParagraphLayout::Line *CoreTextParagraphLayout::NextLine(int max_width) +{ + if (this->cur_offset >= this->length) return NULL; + + /* Get line break position, trying word breaking first and breaking somewhere if that doesn't work. */ + CFIndex len = CTTypesetterSuggestLineBreak(this->typesetter, this->cur_offset, max_width); + if (len <= 0) len = CTTypesetterSuggestClusterBreak(this->typesetter, this->cur_offset, max_width); + + /* Create line. */ + CTLineRef line = CTTypesetterCreateLine(this->typesetter, CFRangeMake(this->cur_offset, len)); + this->cur_offset += len; + + return line != NULL ? new CoreTextLine(line, this->font_map, this->text_buffer) : NULL; +} + +CoreTextParagraphLayout::CoreTextVisualRun::CoreTextVisualRun(CTRunRef run, Font *font, const CoreTextParagraphLayoutFactory::CharType *buff) : font(font) +{ + this->glyphs.resize(CTRunGetGlyphCount(run)); + + /* Query map of glyphs to source string index. */ + CFIndex map[this->glyphs.size()]; + CTRunGetStringIndices(run, CFRangeMake(0, 0), map); + + this->glyph_to_char.resize(this->glyphs.size()); + for (size_t i = 0; i < this->glyph_to_char.size(); i++) this->glyph_to_char[i] = (int)map[i]; + + CGPoint pts[this->glyphs.size()]; + CTRunGetPositions(run, CFRangeMake(0, 0), pts); + this->positions.resize(this->glyphs.size() * 2 + 2); + + /* Convert glyph array to our data type. At the same time, substitute + * the proper glyphs for our private sprite glyphs. */ + CGGlyph gl[this->glyphs.size()]; + CTRunGetGlyphs(run, CFRangeMake(0, 0), gl); + for (size_t i = 0; i < this->glyphs.size(); i++) { + if (buff[this->glyph_to_char[i]] >= SCC_SPRITE_START && buff[this->glyph_to_char[i]] <= SCC_SPRITE_END) { + this->glyphs[i] = font->fc->MapCharToGlyph(buff[this->glyph_to_char[i]]); + this->positions[i * 2 + 0] = pts[i].x; + this->positions[i * 2 + 1] = font->fc->GetAscender() - font->fc->GetGlyph(this->glyphs[i])->height - 1; // Align sprite glyphs to font baseline. + } else { + this->glyphs[i] = gl[i]; + this->positions[i * 2 + 0] = pts[i].x; + this->positions[i * 2 + 1] = pts[i].y; + } + } + this->total_advance = (int)CTRunGetTypographicBounds(run, CFRangeMake(0, 0), NULL, NULL, NULL); + this->positions[this->glyphs.size() * 2] = this->positions[0] + this->total_advance; +} + +/** + * Get the height of the line. + * @return The maximum height of the line. + */ +int CoreTextParagraphLayout::CoreTextLine::GetLeading() const +{ + int leading = 0; + for (const CoreTextVisualRun * const *run = this->Begin(); run != this->End(); run++) { + leading = max(leading, (*run)->GetLeading()); + } + + return leading; +} + +/** + * Get the width of this line. + * @return The width of the line. + */ +int CoreTextParagraphLayout::CoreTextLine::GetWidth() const +{ + if (this->Length() == 0) return 0; + + int total_width = 0; + for (const CoreTextVisualRun * const *run = this->Begin(); run != this->End(); run++) { + total_width += (*run)->GetAdvance(); + } + + return total_width; +} + + +/** Delete CoreText font reference for a specific font size. */ +void MacOSResetScriptCache(FontSize size) +{ + if (_font_cache[size] != NULL) { + CFRelease(_font_cache[size]); + _font_cache[size] = NULL; + } +} + +/** Store current language locale as a CoreFounation locale. */ +void MacOSSetCurrentLocaleName(const char *iso_code) +{ + if (!MacOSVersionIsAtLeast(10, 5, 0)) return; + + if (_osx_locale != NULL) CFRelease(_osx_locale); + + CFStringRef iso = CFStringCreateWithCString(kCFAllocatorNull, iso_code, kCFStringEncodingUTF8); + _osx_locale = CFLocaleCreate(kCFAllocatorDefault, iso); + CFRelease(iso); +} + +/** + * Compares two strings using case insensitive natural sort. + * + * @param s1 First string to compare. + * @param s2 Second string to compare. + * @return 1 if s1 < s2, 2 if s1 == s2, 3 if s1 > s2, or 0 if not supported by the OS. + */ +int MacOSStringCompare(const char *s1, const char *s2) +{ + static bool supported = MacOSVersionIsAtLeast(10, 5, 0); + if (!supported) return 0; + + CFStringCompareFlags flags = kCFCompareCaseInsensitive | kCFCompareNumerically | kCFCompareLocalized | kCFCompareWidthInsensitive | kCFCompareForcedOrdering; + + CFStringRef cf1 = CFStringCreateWithCString(kCFAllocatorDefault, s1, kCFStringEncodingUTF8); + CFStringRef cf2 = CFStringCreateWithCString(kCFAllocatorDefault, s2, kCFStringEncodingUTF8); + + CFComparisonResult res = CFStringCompareWithOptionsAndLocale(cf1, cf2, CFRangeMake(0, CFStringGetLength(cf1)), flags, _osx_locale); + + CFRelease(cf1); + CFRelease(cf2); + + return (int)res + 2; +} + + +/* virtual */ void OSXStringIterator::SetString(const char *s) +{ + const char *string_base = s; + + this->utf16_to_utf8.clear(); + this->str_info.clear(); + this->cur_pos = 0; + + /* CoreText operates on UTF-16, thus we have to convert the input string. + * To be able to return proper offsets, we have to create a mapping at the same time. */ + std::vector utf16_str; ///< UTF-16 copy of the string. + while (*s != '\0') { + size_t idx = s - string_base; + + WChar c = Utf8Consume(&s); + if (c < 0x10000) { + utf16_str.push_back((UniChar)c); + } else { + /* Make a surrogate pair. */ + utf16_str.push_back((UniChar)(0xD800 + ((c - 0x10000) >> 10))); + utf16_str.push_back((UniChar)(0xDC00 + ((c - 0x10000) & 0x3FF))); + this->utf16_to_utf8.push_back(idx); + } + this->utf16_to_utf8.push_back(idx); + } + this->utf16_to_utf8.push_back(s - string_base); + + /* Query CoreText for word and cluster break information. */ + this->str_info.resize(utf16_to_utf8.size()); + + if (utf16_str.size() > 0) { + CFStringRef str = CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, &utf16_str[0], utf16_str.size(), kCFAllocatorNull); + + /* Get cluster breaks. */ + for (CFIndex i = 0; i < CFStringGetLength(str); ) { + CFRange r = CFStringGetRangeOfComposedCharactersAtIndex(str, i); + this->str_info[r.location].char_stop = true; + + i += r.length; + } + + /* Get word breaks. */ + CFStringTokenizerRef tokenizer = CFStringTokenizerCreate(kCFAllocatorDefault, str, CFRangeMake(0, CFStringGetLength(str)), kCFStringTokenizerUnitWordBoundary, _osx_locale); + + CFStringTokenizerTokenType tokenType = kCFStringTokenizerTokenNone; + while ((tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer)) != kCFStringTokenizerTokenNone) { + /* Skip tokens that are white-space or punctuation tokens. */ + if ((tokenType & kCFStringTokenizerTokenHasNonLettersMask) != kCFStringTokenizerTokenHasNonLettersMask) { + CFRange r = CFStringTokenizerGetCurrentTokenRange(tokenizer); + this->str_info[r.location].word_stop = true; + } + } + + CFRelease(tokenizer); + CFRelease(str); + } + + /* End-of-string is always a valid stopping point. */ + this->str_info.back().char_stop = true; + this->str_info.back().word_stop = true; +} + +/* virtual */ size_t OSXStringIterator::SetCurPosition(size_t pos) +{ + /* Convert incoming position to an UTF-16 string index. */ + size_t utf16_pos = 0; + for (size_t i = 0; i < this->utf16_to_utf8.size(); i++) { + if (this->utf16_to_utf8[i] == pos) { + utf16_pos = i; + break; + } + } + + /* Sanitize in case we get a position inside a grapheme cluster. */ + while (utf16_pos > 0 && !this->str_info[utf16_pos].char_stop) utf16_pos--; + this->cur_pos = utf16_pos; + + return this->utf16_to_utf8[this->cur_pos]; +} + +/* virtual */ size_t OSXStringIterator::Next(IterType what) +{ + assert(this->cur_pos <= this->utf16_to_utf8.size()); + assert(what == StringIterator::ITER_CHARACTER || what == StringIterator::ITER_WORD); + + if (this->cur_pos == this->utf16_to_utf8.size()) return END; + + do { + this->cur_pos++; + } while (this->cur_pos < this->utf16_to_utf8.size() && (what == ITER_WORD ? !this->str_info[this->cur_pos].word_stop : !this->str_info[this->cur_pos].char_stop)); + + return this->cur_pos == this->utf16_to_utf8.size() ? END : this->utf16_to_utf8[this->cur_pos]; +} + +/* virtual */ size_t OSXStringIterator::Prev(IterType what) +{ + assert(this->cur_pos <= this->utf16_to_utf8.size()); + assert(what == StringIterator::ITER_CHARACTER || what == StringIterator::ITER_WORD); + + if (this->cur_pos == 0) return END; + + do { + this->cur_pos--; + } while (this->cur_pos > 0 && (what == ITER_WORD ? !this->str_info[this->cur_pos].word_stop : !this->str_info[this->cur_pos].char_stop)); + + return this->utf16_to_utf8[this->cur_pos]; +} + +/* static */ StringIterator *OSXStringIterator::Create() +{ + if (!MacOSVersionIsAtLeast(10, 5, 0)) return NULL; + + return new OSXStringIterator(); +} + +#else +void MacOSResetScriptCache(FontSize size) {} +void MacOSSetCurrentLocaleName(const char *iso_code) {} + +int MacOSStringCompare(const char *s1, const char *s2) +{ + return 0; +} + +/* static */ StringIterator *OSXStringIterator::Create() +{ + return NULL; +} + +/* static */ ParagraphLayouter *CoreTextParagraphLayoutFactory::GetParagraphLayout(CharType *buff, CharType *buff_end, FontMap &fontMapping) +{ + return NULL; +} +#endif /* (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) */ diff --git a/src/os/macosx/string_osx.h b/src/os/macosx/string_osx.h new file mode 100644 index 0000000000..d632b0a440 --- /dev/null +++ b/src/os/macosx/string_osx.h @@ -0,0 +1,90 @@ +/* $Id$ */ + +/* + * 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 . + */ + +/** @file string_osx.h Functions related to localized text support on OSX. */ + +#ifndef STRING_OSX_H +#define STRING_OSX_H + +#include "../../gfx_layout.h" +#include "../../string_base.h" +#include + +/** String iterator using CoreText as a backend. */ +class OSXStringIterator : public StringIterator { + /** Break info for a character. */ + struct CharInfo { + bool word_stop : 1; ///< Code point is suitable as a word break. + bool char_stop : 1; ///< Code point is the start of a grapheme cluster, i.e. a "character". + }; + + std::vector str_info; ///< Break information for each code point. + std::vector utf16_to_utf8; ///< Mapping from UTF-16 code point position to index in the UTF-8 source string. + + size_t cur_pos; ///< Current iteration position. + +public: + virtual void SetString(const char *s); + virtual size_t SetCurPosition(size_t pos); + virtual size_t Next(IterType what); + virtual size_t Prev(IterType what); + + static StringIterator *Create(); +}; + +/** + * Helper class to construct a new #CoreTextParagraphLayout. + */ +class CoreTextParagraphLayoutFactory { +public: + /** Helper for GetLayouter, to get the right type. */ + typedef UniChar CharType; + /** Helper for GetLayouter, to get whether the layouter supports RTL. */ + static const bool SUPPORTS_RTL = true; + + /** + * Get the actual ParagraphLayout for the given buffer. + * @param buff The begin of the buffer. + * @param buff_end The location after the last element in the buffer. + * @param fontMapping THe mapping of the fonts. + * @return The ParagraphLayout instance. + */ + static ParagraphLayouter *GetParagraphLayout(CharType *buff, CharType *buff_end, FontMap &fontMapping); + + /** + * Append a wide character to the internal buffer. + * @param buff The buffer to append to. + * @param buffer_last The end of the buffer. + * @param c The character to add. + * @return The number of buffer spaces that were used. + */ + static size_t AppendToBuffer(CharType *buff, const CharType *buffer_last, WChar c) + { + if (c >= 0x010000U) { + /* Character is encoded using surrogates in UTF-16. */ + if (buff + 1 <= buffer_last) { + buff[0] = (CharType)(((c - 0x010000U) >> 10) + 0xD800); + buff[1] = (CharType)(((c - 0x010000U) & 0x3FF) + 0xDC00); + } else { + /* Not enough space in buffer. */ + *buff = 0; + } + return 2; + } else { + *buff = (CharType)(c & 0xFFFF); + return 1; + } + } +}; + +void MacOSResetScriptCache(FontSize size); +void MacOSSetCurrentLocaleName(const char *iso_code); +int MacOSStringCompare(const char *s1, const char *s2); + +#endif /* STRING_OSX_H */ diff --git a/src/os/unix/unix.cpp b/src/os/unix/unix.cpp index d7c2304ce5..bea69ec931 100644 --- a/src/os/unix/unix.cpp +++ b/src/os/unix/unix.cpp @@ -308,9 +308,7 @@ bool GetClipboardContents(char *buffer, const char *last) void CSleep(int milliseconds) { - #if defined(PSP) - sceKernelDelayThread(milliseconds * 1000); - #elif defined(__BEOS__) + #if defined(__BEOS__) snooze(milliseconds * 1000); #elif defined(__AMIGA__) { diff --git a/src/os/windows/string_uniscribe.cpp b/src/os/windows/string_uniscribe.cpp new file mode 100644 index 0000000000..ce61537b2b --- /dev/null +++ b/src/os/windows/string_uniscribe.cpp @@ -0,0 +1,611 @@ +/* $Id$ */ + +/* + * 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 . + */ + +/** @file string_uniscribe.cpp Functions related to laying out text on Win32. */ + +#if defined(WITH_UNISCRIBE) + +#include "../../stdafx.h" +#include "../../debug.h" +#include "string_uniscribe.h" +#include "../../language.h" +#include "../../strings_func.h" +#include "../../string_func.h" +#include "../../table/control_codes.h" +#include "win32.h" +#include + +#include +#include + +#include "../../safeguards.h" + +#ifdef _MSC_VER +# pragma comment(lib, "usp10") +#endif + + +/** Uniscribe cache for internal font information, cleared when OTTD changes fonts. */ +static SCRIPT_CACHE _script_cache[FS_END]; + +/** + * Contains all information about a run of characters. A run are consecutive + * characters that share a single font and language. + */ +struct UniscribeRun { + int pos; + int len; + Font *font; + + std::vector ft_glyphs; + + SCRIPT_ANALYSIS sa; + std::vector char_to_glyph; + + std::vector vis_attribs; + std::vector glyphs; + std::vector advances; + std::vector offsets; + int total_advance; + + UniscribeRun(int pos, int len, Font *font, SCRIPT_ANALYSIS &sa) : pos(pos), len(len), font(font), sa(sa) {} +}; + +/** Break a string into language formatting ranges. */ +static std::vector UniscribeItemizeString(UniscribeParagraphLayoutFactory::CharType *buff, int32 length); +/** Generate and place glyphs for a run of characters. */ +static bool UniscribeShapeRun(const UniscribeParagraphLayoutFactory::CharType *buff, UniscribeRun &range); + +/** + * Wrapper for doing layouts with Uniscribe. + */ +class UniscribeParagraphLayout : public ParagraphLayouter { +private: + const UniscribeParagraphLayoutFactory::CharType *text_buffer; + + std::vector ranges; ///< All runs of the text. + std::vector::iterator cur_range; ///< The next run to be output. + int cur_range_offset = 0; ///< Offset from the start of the current run from where to output. + +public: + /** Visual run contains data about the bit of text with the same font. */ + class UniscribeVisualRun : public ParagraphLayouter::VisualRun { + private: + std::vector glyphs; + std::vector positions; + std::vector char_to_glyph; + + int start_pos; + int total_advance; + int num_glyphs; + Font *font; + + mutable int *glyph_to_char = NULL; + + public: + UniscribeVisualRun(const UniscribeRun &range, int x); + virtual ~UniscribeVisualRun() + { + free(this->glyph_to_char); + } + + virtual const GlyphID *GetGlyphs() const { return &this->glyphs[0]; } + virtual const float *GetPositions() const { return &this->positions[0]; } + virtual const int *GetGlyphToCharMap() const; + + virtual const Font *GetFont() const { return this->font; } + virtual int GetLeading() const { return this->font->fc->GetHeight(); } + virtual int GetGlyphCount() const { return this->num_glyphs; } + int GetAdvance() const { return this->total_advance; } + }; + + /** A single line worth of VisualRuns. */ + class UniscribeLine : public AutoDeleteSmallVector, public ParagraphLayouter::Line { + public: + virtual int GetLeading() const; + virtual int GetWidth() const; + virtual int CountRuns() const { return this->Length(); } + virtual const VisualRun *GetVisualRun(int run) const { return *this->Get(run); } + + int GetInternalCharLength(WChar c) const + { + /* Uniscribe uses UTF-16 internally which means we need to account for surrogate pairs. */ + return c >= 0x010000U ? 2 : 1; + } + }; + + UniscribeParagraphLayout(std::vector &ranges, const UniscribeParagraphLayoutFactory::CharType *buffer) : text_buffer(buffer), ranges(ranges) + { + this->Reflow(); + } + + virtual ~UniscribeParagraphLayout() {} + + virtual void Reflow() + { + this->cur_range = this->ranges.begin(); + this->cur_range_offset = 0; + } + + virtual const Line *NextLine(int max_width); +}; + +void UniscribeResetScriptCache(FontSize size) +{ + if (_script_cache[size] != NULL) { + ScriptFreeCache(&_script_cache[size]); + _script_cache[size] = NULL; + } +} + +/** Load the matching native Windows font. */ +static HFONT HFontFromFont(Font *font) +{ + LOGFONT logfont; + ZeroMemory(&logfont, sizeof(LOGFONT)); + logfont.lfHeight = font->fc->GetHeight(); + logfont.lfWeight = FW_NORMAL; + logfont.lfCharSet = DEFAULT_CHARSET; + convert_to_fs(font->fc->GetFontName(), logfont.lfFaceName, lengthof(logfont.lfFaceName)); + + return CreateFontIndirect(&logfont); +} + +/** Determine the glyph positions for a run. */ +static bool UniscribeShapeRun(const UniscribeParagraphLayoutFactory::CharType *buff, UniscribeRun &range) +{ + /* Initial size guess for the number of glyphs recommended by Uniscribe. */ + range.glyphs.resize(range.len * 3 / 2 + 16); + range.vis_attribs.resize(range.glyphs.size()); + + /* The char-to-glyph array is the same size as the input. */ + range.char_to_glyph.resize(range.len); + + HDC temp_dc = NULL; + HFONT old_font = NULL; + HFONT cur_font = NULL; + + while (true) { + /* Shape the text run by determining the glyphs needed for display. */ + int glyphs_used = 0; + HRESULT hr = ScriptShape(temp_dc, &_script_cache[range.font->fc->GetSize()], buff + range.pos, range.len, (int)range.glyphs.size(), &range.sa, &range.glyphs[0], &range.char_to_glyph[0], &range.vis_attribs[0], &glyphs_used); + + if (SUCCEEDED(hr)) { + range.glyphs.resize(glyphs_used); + range.vis_attribs.resize(glyphs_used); + + /* Calculate the glyph positions. */ + ABC abc; + range.advances.resize(range.glyphs.size()); + range.offsets.resize(range.glyphs.size()); + hr = ScriptPlace(temp_dc, &_script_cache[range.font->fc->GetSize()], &range.glyphs[0], (int)range.glyphs.size(), &range.vis_attribs[0], &range.sa, &range.advances[0], &range.offsets[0], &abc); + if (SUCCEEDED(hr)) { + /* We map our special sprite chars to values that don't fit into a WORD. Copy the glyphs + * into a new vector and query the real glyph to use for these special chars. */ + range.ft_glyphs.resize(range.glyphs.size()); + for (size_t g_id = 0; g_id < range.glyphs.size(); g_id++) { + range.ft_glyphs[g_id] = range.glyphs[g_id]; + } + for (int i = 0; i < range.len; i++) { + if (buff[range.pos + i] >= SCC_SPRITE_START && buff[range.pos + i] <= SCC_SPRITE_END) { + range.ft_glyphs[range.char_to_glyph[i]] = range.font->fc->MapCharToGlyph(buff[range.pos + i]); + range.offsets[range.char_to_glyph[i]].dv = range.font->fc->GetAscender() - range.font->fc->GetGlyph(range.ft_glyphs[range.char_to_glyph[i]])->height - 1; // Align sprite glyphs to font baseline. + } + } + + /* FreeType and GDI/Uniscribe seems to occasionally disagree over the width of a glyph. */ + range.total_advance = 0; + for (size_t i = 0; i < range.advances.size(); i++) { + if (range.advances[i] > 0 && range.ft_glyphs[i] != 0xFFFF) range.advances[i] = range.font->fc->GetGlyphWidth(range.ft_glyphs[i]); + range.total_advance += range.advances[i]; + } + break; + } + } + + if (hr == E_OUTOFMEMORY) { + /* The glyph buffer needs to be larger. Just double it every time. */ + range.glyphs.resize(range.glyphs.size() * 2); + range.vis_attribs.resize(range.vis_attribs.size() * 2); + } else if (hr == E_PENDING) { + /* Glyph data is not in cache, load native font. */ + cur_font = HFontFromFont(range.font); + if (cur_font == NULL) return false; // Sorry, no dice. + + temp_dc = CreateCompatibleDC(NULL); + SetMapMode(temp_dc, MM_TEXT); + old_font = (HFONT)SelectObject(temp_dc, cur_font); + } else if (hr == USP_E_SCRIPT_NOT_IN_FONT && range.sa.eScript != SCRIPT_UNDEFINED) { + /* Try again with the generic shaping engine. */ + range.sa.eScript = SCRIPT_UNDEFINED; + } else { + /* Some unknown other error. */ + if (temp_dc != NULL) { + SelectObject(temp_dc, old_font); + DeleteObject(cur_font); + ReleaseDC(NULL, temp_dc); + } + return false; + } + } + + if (temp_dc != NULL) { + SelectObject(temp_dc, old_font); + DeleteObject(cur_font); + ReleaseDC(NULL, temp_dc); + } + + return true; +} + +static std::vector UniscribeItemizeString(UniscribeParagraphLayoutFactory::CharType *buff, int32 length) +{ + /* Itemize text. */ + SCRIPT_CONTROL control; + ZeroMemory(&control, sizeof(SCRIPT_CONTROL)); + control.uDefaultLanguage = _current_language->winlangid; + + SCRIPT_STATE state; + ZeroMemory(&state, sizeof(SCRIPT_STATE)); + state.uBidiLevel = _current_text_dir == TD_RTL ? 1 : 0; + + std::vector items(16); + while (true) { + /* We subtract one from max_items to work around a buffer overflow on some older versions of Windows. */ + int generated = 0; + HRESULT hr = ScriptItemize(buff, length, (int)items.size() - 1, &control, &state, &items[0], &generated); + + if (SUCCEEDED(hr)) { + /* Resize the item buffer. Note that Uniscribe will always add an additional end sentinel item. */ + items.resize(generated + 1); + break; + } + /* Some kind of error except item buffer too small. */ + if (hr != E_OUTOFMEMORY) return std::vector(); + + items.resize(items.size() * 2); + } + + return items; +} + +/* static */ ParagraphLayouter *UniscribeParagraphLayoutFactory::GetParagraphLayout(CharType *buff, CharType *buff_end, FontMap &fontMapping) +{ + int32 length = buff_end - buff; + /* Can't layout an empty string. */ + if (length == 0) return NULL; + + /* Can't layout our in-built sprite fonts. */ + for (FontMap::const_iterator i = fontMapping.Begin(); i != fontMapping.End(); i++) { + if (i->second->fc->IsBuiltInFont()) return NULL; + } + + /* Itemize text. */ + std::vector items = UniscribeItemizeString(buff, length); + if (items.size() == 0) return NULL; + + /* Build ranges from the items and the font map. A range is a run of text + * that is part of a single item and formatted using a single font style. */ + std::vector ranges; + + int cur_pos = 0; + std::vector::iterator cur_item = items.begin(); + for (FontMap::const_iterator i = fontMapping.Begin(); i != fontMapping.End(); i++) { + while (cur_pos < i->first && cur_item != items.end() - 1) { + /* Add a range that spans the intersection of the remaining item and font run. */ + int stop_pos = min(i->first, (cur_item + 1)->iCharPos); + assert(stop_pos - cur_pos > 0); + ranges.push_back(UniscribeRun(cur_pos, stop_pos - cur_pos, i->second, cur_item->a)); + + /* Shape the range. */ + if (!UniscribeShapeRun(buff, ranges.back())) { + return NULL; + } + + /* If we are at the end of the current item, advance to the next item. */ + if (stop_pos == (cur_item + 1)->iCharPos) cur_item++; + cur_pos = stop_pos; + } + } + + return new UniscribeParagraphLayout(ranges, buff); +} + +/* virtual */ const ParagraphLayouter::Line *UniscribeParagraphLayout::NextLine(int max_width) +{ + std::vector::iterator start_run = this->cur_range; + std::vector::iterator last_run = this->cur_range; + + if (start_run == this->ranges.end()) return NULL; + + /* Add remaining width of the first run if it is a broken run. */ + int cur_width = 0; + if (this->cur_range_offset != 0) { + std::vector dx(start_run->len); + ScriptGetLogicalWidths(&start_run->sa, start_run->len, (int)start_run->glyphs.size(), &start_run->advances[0], &start_run->char_to_glyph[0], &start_run->vis_attribs[0], &dx[0]); + + for (std::vector::const_iterator c = dx.begin() + this->cur_range_offset; c != dx.end(); c++) { + cur_width += *c; + } + ++last_run; + } + + /* Gather runs until the line is full. */ + while (last_run != this->ranges.end() && cur_width < max_width) { + cur_width += last_run->total_advance; + ++last_run; + } + + /* If the text does not fit into the available width, find a suitable breaking point. */ + int remaing_offset = (last_run - 1)->len; + if (cur_width > max_width) { + std::vector log_attribs; + + /* Get word break information. */ + int width_avail = max_width; + int num_chars = this->cur_range_offset; + int start_offs = this->cur_range_offset; + int last_cluster = this->cur_range_offset + 1; + for (std::vector::iterator r = start_run; r != last_run; r++) { + log_attribs.resize(r->pos - start_run->pos + r->len); + if (FAILED(ScriptBreak(this->text_buffer + r->pos + start_offs, r->len - start_offs, &r->sa, &log_attribs[r->pos - start_run->pos + start_offs]))) return NULL; + + std::vector dx(r->len); + ScriptGetLogicalWidths(&r->sa, r->len, (int)r->glyphs.size(), &r->advances[0], &r->char_to_glyph[0], &r->vis_attribs[0], &dx[0]); + + /* Count absolute max character count on the line. */ + for (int c = start_offs; c < r->len && width_avail > 0; c++, num_chars++) { + if (c > start_offs && log_attribs[num_chars].fCharStop) last_cluster = num_chars; + width_avail -= dx[c]; + } + + start_offs = 0; + } + + /* Walk backwards to find the last suitable breaking point. */ + while (--num_chars > this->cur_range_offset && !log_attribs[num_chars].fSoftBreak && !log_attribs[num_chars].fWhiteSpace) {} + + if (num_chars == this->cur_range_offset) { + /* Didn't find any suitable word break point, just break on the last cluster boundary. */ + num_chars = last_cluster; + } + + /* Include whitespace characters after the breaking point. */ + while (num_chars < (int)log_attribs.size() && log_attribs[num_chars].fWhiteSpace) { + num_chars++; + } + + /* Get last run that corresponds to the number of characters to show. */ + for (std::vector::iterator run = start_run; run != last_run; run++) { + num_chars -= run->len; + + if (num_chars <= 0) { + remaing_offset = num_chars + run->len + 1; + last_run = run + 1; + assert(remaing_offset - 1 > 0); + break; + } + } + } + + /* Build display order from the runs. */ + std::vector bidi_level; + for (std::vector::iterator r = start_run; r != last_run; r++) { + bidi_level.push_back(r->sa.s.uBidiLevel); + } + std::vector vis_to_log(bidi_level.size()); + if (FAILED(ScriptLayout((int)bidi_level.size(), &bidi_level[0], &vis_to_log[0], NULL))) return NULL; + + /* Create line. */ + UniscribeLine *line = new UniscribeLine(); + + int cur_pos = 0; + for (std::vector::iterator l = vis_to_log.begin(); l != vis_to_log.end(); l++) { + std::vector::iterator i_run = start_run + *l; + UniscribeRun run = *i_run; + + /* Partial run after line break (either start or end)? Reshape run to get the first/last glyphs right. */ + if (i_run == last_run - 1 && remaing_offset < (last_run - 1)->len) { + run.len = remaing_offset - 1; + + if (!UniscribeShapeRun(this->text_buffer, run)) return NULL; + } + if (i_run == start_run && this->cur_range_offset > 0) { + assert(run.len - this->cur_range_offset > 0); + run.pos += this->cur_range_offset; + run.len -= this->cur_range_offset; + + if (!UniscribeShapeRun(this->text_buffer, run)) return NULL; + } + + *line->Append() = new UniscribeVisualRun(run, cur_pos); + cur_pos += run.total_advance; + } + + if (remaing_offset < (last_run - 1)->len) { + /* We didn't use up all of the last run, store remainder for the next line. */ + this->cur_range_offset = remaing_offset - 1; + this->cur_range = last_run - 1; + assert(this->cur_range->len > this->cur_range_offset); + } else { + this->cur_range_offset = 0; + this->cur_range = last_run; + } + + return line; +} + +/** + * Get the height of the line. + * @return The maximum height of the line. + */ +int UniscribeParagraphLayout::UniscribeLine::GetLeading() const +{ + int leading = 0; + for (const UniscribeVisualRun * const *run = this->Begin(); run != this->End(); run++) { + leading = max(leading, (*run)->GetLeading()); + } + + return leading; +} + +/** + * Get the width of this line. + * @return The width of the line. + */ +int UniscribeParagraphLayout::UniscribeLine::GetWidth() const +{ + int length = 0; + for (const UniscribeVisualRun * const *run = this->Begin(); run != this->End(); run++) { + length += (*run)->GetAdvance(); + } + + return length; +} + +UniscribeParagraphLayout::UniscribeVisualRun::UniscribeVisualRun(const UniscribeRun &range, int x) : glyphs(range.ft_glyphs), char_to_glyph(range.char_to_glyph), start_pos(range.pos), total_advance(range.total_advance), font(range.font) +{ + this->num_glyphs = (int)glyphs.size(); + this->positions.resize(this->num_glyphs * 2 + 2); + + int advance = 0; + for (int i = 0; i < this->num_glyphs; i++) { + this->positions[i * 2 + 0] = range.offsets[i].du + advance + x; + this->positions[i * 2 + 1] = range.offsets[i].dv; + + advance += range.advances[i]; + } + this->positions[this->num_glyphs * 2] = advance + x; +} + +const int *UniscribeParagraphLayout::UniscribeVisualRun::GetGlyphToCharMap() const +{ + if (this->glyph_to_char == NULL) { + this->glyph_to_char = CallocT(this->GetGlyphCount()); + + /* The char to glyph array contains the first glyph index of the cluster that is associated + * with each character. It is possible for a cluster to be formed of several chars. */ + for (int c = 0; c < (int)this->char_to_glyph.size(); c++) { + /* If multiple chars map to one glyph, only refer back to the first character. */ + if (this->glyph_to_char[this->char_to_glyph[c]] == 0) this->glyph_to_char[this->char_to_glyph[c]] = c + this->start_pos; + } + + /* We only marked the first glyph of each cluster in the loop above. Fill the gaps. */ + int last_char = this->glyph_to_char[0]; + for (int g = 0; g < this->GetGlyphCount(); g++) { + if (this->glyph_to_char[g] != 0) last_char = this->glyph_to_char[g]; + this->glyph_to_char[g] = last_char; + } + } + + return this->glyph_to_char; +} + + +/* virtual */ void UniscribeStringIterator::SetString(const char *s) +{ + const char *string_base = s; + + this->utf16_to_utf8.clear(); + this->str_info.clear(); + this->cur_pos = 0; + + /* Uniscribe operates on UTF-16, thus we have to convert the input string. + * To be able to return proper offsets, we have to create a mapping at the same time. */ + std::vector utf16_str; ///< UTF-16 copy of the string. + while (*s != '\0') { + size_t idx = s - string_base; + + WChar c = Utf8Consume(&s); + if (c < 0x10000) { + utf16_str.push_back((wchar_t)c); + } else { + /* Make a surrogate pair. */ + utf16_str.push_back((wchar_t)(0xD800 + ((c - 0x10000) >> 10))); + utf16_str.push_back((wchar_t)(0xDC00 + ((c - 0x10000) & 0x3FF))); + this->utf16_to_utf8.push_back(idx); + } + this->utf16_to_utf8.push_back(idx); + } + this->utf16_to_utf8.push_back(s - string_base); + + /* Query Uniscribe for word and cluster break information. */ + this->str_info.resize(utf16_to_utf8.size()); + + if (utf16_str.size() > 0) { + /* Itemize string into language runs. */ + std::vector runs = UniscribeItemizeString(&utf16_str[0], (int32)utf16_str.size()); + + for (std::vector::const_iterator run = runs.begin(); runs.size() > 0 && run != runs.end() - 1; run++) { + /* Get information on valid word and character break.s */ + int len = (run + 1)->iCharPos - run->iCharPos; + std::vector attr(len); + ScriptBreak(&utf16_str[run->iCharPos], len, &run->a, &attr[0]); + + /* Extract the information we're interested in. */ + for (size_t c = 0; c < attr.size(); c++) { + /* First character of a run is always a valid word break. */ + this->str_info[c + run->iCharPos].word_stop = attr[c].fWordStop || c == 0; + this->str_info[c + run->iCharPos].char_stop = attr[c].fCharStop; + } + } + } + + /* End-of-string is always a valid stopping point. */ + this->str_info.back().char_stop = true; + this->str_info.back().word_stop = true; +} + +/* virtual */ size_t UniscribeStringIterator::SetCurPosition(size_t pos) +{ + /* Convert incoming position to an UTF-16 string index. */ + size_t utf16_pos = 0; + for (size_t i = 0; i < this->utf16_to_utf8.size(); i++) { + if (this->utf16_to_utf8[i] == pos) { + utf16_pos = i; + break; + } + } + + /* Sanitize in case we get a position inside a grapheme cluster. */ + while (utf16_pos > 0 && !this->str_info[utf16_pos].char_stop) utf16_pos--; + this->cur_pos = utf16_pos; + + return this->utf16_to_utf8[this->cur_pos]; +} + +/* virtual */ size_t UniscribeStringIterator::Next(IterType what) +{ + assert(this->cur_pos <= this->utf16_to_utf8.size()); + assert(what == StringIterator::ITER_CHARACTER || what == StringIterator::ITER_WORD); + + if (this->cur_pos == this->utf16_to_utf8.size()) return END; + + do { + this->cur_pos++; + } while (this->cur_pos < this->utf16_to_utf8.size() && (what == ITER_WORD ? !this->str_info[this->cur_pos].word_stop : !this->str_info[this->cur_pos].char_stop)); + + return this->cur_pos == this->utf16_to_utf8.size() ? END : this->utf16_to_utf8[this->cur_pos]; +} + +/*virtual */ size_t UniscribeStringIterator::Prev(IterType what) +{ + assert(this->cur_pos <= this->utf16_to_utf8.size()); + assert(what == StringIterator::ITER_CHARACTER || what == StringIterator::ITER_WORD); + + if (this->cur_pos == 0) return END; + + do { + this->cur_pos--; + } while (this->cur_pos > 0 && (what == ITER_WORD ? !this->str_info[this->cur_pos].word_stop : !this->str_info[this->cur_pos].char_stop)); + + return this->utf16_to_utf8[this->cur_pos]; +} + +#endif /* defined(WITH_UNISCRIBE) */ diff --git a/src/os/windows/string_uniscribe.h b/src/os/windows/string_uniscribe.h new file mode 100644 index 0000000000..6af858a88f --- /dev/null +++ b/src/os/windows/string_uniscribe.h @@ -0,0 +1,92 @@ +/* $Id$ */ + +/* + * 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 . + */ + +/** @file string_uniscribe.h Functions related to laying out text on Win32. */ + +#ifndef STRING_UNISCRIBE_H +#define STRING_UNISCRIBE_H + +#if defined(WITH_UNISCRIBE) + +#include "../../gfx_layout.h" +#include "../../string_base.h" +#include + + +void UniscribeResetScriptCache(FontSize size); + + +/** + * Helper class to construct a new #UniscribeParagraphLayout. + */ +class UniscribeParagraphLayoutFactory { +public: + /** Helper for GetLayouter, to get the right type. */ + typedef wchar_t CharType; + /** Helper for GetLayouter, to get whether the layouter supports RTL. */ + static const bool SUPPORTS_RTL = true; + + /** + * Get the actual ParagraphLayout for the given buffer. + * @param buff The begin of the buffer. + * @param buff_end The location after the last element in the buffer. + * @param fontMapping THe mapping of the fonts. + * @return The ParagraphLayout instance. + */ + static ParagraphLayouter *GetParagraphLayout(CharType *buff, CharType *buff_end, FontMap &fontMapping); + + /** + * Append a wide character to the internal buffer. + * @param buff The buffer to append to. + * @param buffer_last The end of the buffer. + * @param c The character to add. + * @return The number of buffer spaces that were used. + */ + static size_t AppendToBuffer(CharType *buff, const CharType *buffer_last, WChar c) + { + if (c >= 0x010000U) { + /* Character is encoded using surrogates in UTF-16. */ + if (buff + 1 <= buffer_last) { + buff[0] = (CharType)(((c - 0x010000U) >> 10) + 0xD800); + buff[1] = (CharType)(((c - 0x010000U) & 0x3FF) + 0xDC00); + } else { + /* Not enough space in buffer. */ + *buff = 0; + } + return 2; + } else { + *buff = (CharType)(c & 0xFFFF); + return 1; + } + } +}; + +/** String iterator using Uniscribe as a backend. */ +class UniscribeStringIterator : public StringIterator { + /** */ + struct CharInfo { + bool word_stop : 1; ///< Code point is suitable as a word break. + bool char_stop : 1; ///< Code point is the start of a grapheme cluster, i.e. a "character". + }; + + std::vector str_info; ///< Break information for each code point. + std::vector utf16_to_utf8; ///< Mapping from UTF-16 code point position to index in the UTF-8 source string. + + size_t cur_pos; ///< Current iteration position. + +public: + virtual void SetString(const char *s); + virtual size_t SetCurPosition(size_t pos); + virtual size_t Next(IterType what); + virtual size_t Prev(IterType what); +}; + +#endif /* defined(WITH_UNISCRIBE) */ + +#endif /* STRING_UNISCRIBE_H */ diff --git a/src/os/windows/win32.cpp b/src/os/windows/win32.cpp index 3fd1777fa8..bb1a0a4209 100644 --- a/src/os/windows/win32.cpp +++ b/src/os/windows/win32.cpp @@ -28,6 +28,7 @@ #include "../../crashlog.h" #include #include +#include "../../language.h" /* Due to TCHAR, strncat and strncpy have to remain (for a while). */ #include "../../safeguards.h" @@ -67,11 +68,7 @@ bool LoadLibraryList(Function proc[], const char *dll) while (*dll++ != '\0') { /* Nothing */ } if (*dll == '\0') break; -#if defined(WINCE) - p = GetProcAddress(lib, MB_TO_WIDE(dll)); -#else p = GetProcAddress(lib, dll); -#endif if (p == NULL) return false; *proc++ = (Function)p; } @@ -210,14 +207,6 @@ bool FiosIsRoot(const char *file) void FiosGetDrives(FileList &file_list) { -#if defined(WINCE) - /* WinCE only knows one drive: / */ - FiosItem *fios = file_list.Append(); - fios->type = FIOS_TYPE_DRIVE; - fios->mtime = 0; - seprintf(fios->name, lastof(fios->name), PATHSEP ""); - strecpy(fios->title, fios->name, lastof(fios->title)); -#else TCHAR drives[256]; const TCHAR *s; @@ -230,7 +219,6 @@ void FiosGetDrives(FileList &file_list) strecpy(fios->title, fios->name, lastof(fios->title)); while (*s++ != '\0') { /* Nothing */ } } -#endif } bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb) @@ -306,16 +294,13 @@ static int ParseCommandLine(char *line, char **argv, int max_argc) void CreateConsole() { -#if defined(WINCE) - /* WinCE doesn't support console stuff */ -#else HANDLE hand; CONSOLE_SCREEN_BUFFER_INFO coninfo; if (_has_console) return; _has_console = true; - AllocConsole(); + if (!AllocConsole()) return; hand = GetStdHandle(STD_OUTPUT_HANDLE); GetConsoleScreenBufferInfo(hand, &coninfo); @@ -358,7 +343,6 @@ void CreateConsole() setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); -#endif } /** Temporary pointer to get the help message to the window */ @@ -426,18 +410,14 @@ void ShowInfo(const char *str) } } -#if defined(WINCE) -int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) -#else int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) -#endif { int argc; char *argv[64]; // max 64 command line arguments CrashLog::InitialiseCrashLog(); -#if defined(UNICODE) && !defined(WINCE) +#if defined(UNICODE) /* Check if a win9x user started the win32 version */ if (HasBit(GetVersion(), 31)) usererror("This version of OpenTTD doesn't run on windows 95/98/ME.\nPlease download the win9x binary and try again."); #endif @@ -451,9 +431,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi CreateConsole(); #endif -#if !defined(WINCE) _set_error_mode(_OUT_TO_MSGBOX); // force assertion output to messagebox -#endif /* setup random seed to something quite random */ SetRandomSeed(GetTickCount()); @@ -468,35 +446,11 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi return 0; } -#if defined(WINCE) -void GetCurrentDirectoryW(int length, wchar_t *path) -{ - /* Get the name of this module */ - GetModuleFileName(NULL, path, length); - - /* Remove the executable name, this we call CurrentDir */ - wchar_t *pDest = wcsrchr(path, '\\'); - if (pDest != NULL) { - int result = pDest - path + 1; - path[result] = '\0'; - } -} -#endif - char *getcwd(char *buf, size_t size) { -#if defined(WINCE) - TCHAR path[MAX_PATH]; - GetModuleFileName(NULL, path, MAX_PATH); - convert_from_fs(path, buf, size); - /* GetModuleFileName returns dir with file, so remove everything behind latest '\\' */ - char *p = strrchr(buf, '\\'); - if (p != NULL) *p = '\0'; -#else TCHAR path[MAX_PATH]; GetCurrentDirectory(MAX_PATH - 1, path); convert_from_fs(path, buf, size); -#endif return buf; } @@ -671,11 +625,11 @@ char *convert_from_fs(const TCHAR *name, char *utf8_buf, size_t buflen) * Convert from OpenTTD's encoding to that of the environment in * UNICODE. OpenTTD encoding is UTF8, local is wide * @param name pointer to a valid string that will be converted - * @param utf16_buf pointer to a valid wide-char buffer that will receive the + * @param system_buf pointer to a valid wide-char buffer that will receive the * converted string * @param buflen length in wide characters of the receiving buffer * @param console_cp convert to the console encoding instead of the normal system encoding. - * @return pointer to utf16_buf. If conversion fails the string is of zero-length + * @return pointer to system_buf. If conversion fails the string is of zero-length */ TCHAR *convert_to_fs(const char *name, TCHAR *system_buf, size_t buflen, bool console_cp) { @@ -786,17 +740,80 @@ uint GetCPUCoreCount() return info.dwNumberOfProcessors; } + +static WCHAR _cur_iso_locale[16] = L""; + +void Win32SetCurrentLocaleName(const char *iso_code) +{ + /* Convert the iso code into the format that windows expects. */ + char iso[16]; + if (strcmp(iso_code, "zh_TW") == 0) { + strecpy(iso, "zh-Hant", lastof(iso)); + } else if (strcmp(iso_code, "zh_CN") == 0) { + strecpy(iso, "zh-Hans", lastof(iso)); + } else { + /* Windows expects a '-' between language and country code, but we use a '_'. */ + strecpy(iso, iso_code, lastof(iso)); + for (char *c = iso; *c != '\0'; c++) { + if (*c == '_') *c = '-'; + } + } + + MultiByteToWideChar(CP_UTF8, 0, iso, -1, _cur_iso_locale, lengthof(_cur_iso_locale)); +} + +int OTTDStringCompare(const char *s1, const char *s2) +{ + typedef int (WINAPI *PFNCOMPARESTRINGEX)(LPCWSTR, DWORD, LPCWCH, int, LPCWCH, int, LPVOID, LPVOID, LPARAM); + static PFNCOMPARESTRINGEX _CompareStringEx = NULL; + static bool first_time = true; + +#ifndef SORT_DIGITSASNUMBERS +# define SORT_DIGITSASNUMBERS 0x00000008 // use digits as numbers sort method +#endif +#ifndef LINGUISTIC_IGNORECASE +# define LINGUISTIC_IGNORECASE 0x00000010 // linguistically appropriate 'ignore case' +#endif + + if (first_time) { + _CompareStringEx = (PFNCOMPARESTRINGEX)GetProcAddress(GetModuleHandle(_T("Kernel32")), "CompareStringEx"); + first_time = false; + } + + if (_CompareStringEx != NULL) { + /* CompareStringEx takes UTF-16 strings, even in ANSI-builds. */ + int len_s1 = MultiByteToWideChar(CP_UTF8, 0, s1, -1, NULL, 0); + int len_s2 = MultiByteToWideChar(CP_UTF8, 0, s2, -1, NULL, 0); + + if (len_s1 != 0 && len_s2 != 0) { + LPWSTR str_s1 = AllocaM(WCHAR, len_s1); + LPWSTR str_s2 = AllocaM(WCHAR, len_s2); + + MultiByteToWideChar(CP_UTF8, 0, s1, -1, str_s1, len_s1); + MultiByteToWideChar(CP_UTF8, 0, s2, -1, str_s2, len_s2); + + int result = _CompareStringEx(_cur_iso_locale, LINGUISTIC_IGNORECASE | SORT_DIGITSASNUMBERS, str_s1, -1, str_s2, -1, NULL, NULL, 0); + if (result != 0) return result; + } + } + + TCHAR s1_buf[512], s2_buf[512]; + convert_to_fs(s1, s1_buf, lengthof(s1_buf)); + convert_to_fs(s2, s2_buf, lengthof(s2_buf)); + + return CompareString(MAKELCID(_current_language->winlangid, SORT_DEFAULT), NORM_IGNORECASE, s1_buf, -1, s2_buf, -1); +} + #ifdef _MSC_VER -/* Code from MSDN: https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx */ +/* Based on code from MSDN: https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx */ const DWORD MS_VC_EXCEPTION = 0x406D1388; -#pragma pack(push,8) -typedef struct { + +PACK_N(struct THREADNAME_INFO { DWORD dwType; ///< Must be 0x1000. LPCSTR szName; ///< Pointer to name (in user addr space). DWORD dwThreadID; ///< Thread ID (-1=caller thread). DWORD dwFlags; ///< Reserved for future use, must be zero. -} THREADNAME_INFO; -#pragma pack(pop) +}, 8); /** * Signal thread name to any attached debuggers. diff --git a/src/os/windows/win32.h b/src/os/windows/win32.h index 16632f6e9a..4f813c4a6f 100644 --- a/src/os/windows/win32.h +++ b/src/os/windows/win32.h @@ -45,4 +45,7 @@ void SetWin32ThreadName(DWORD dwThreadID, const char* threadName); static inline void SetWin32ThreadName(DWORD dwThreadID, const char* threadName) {} #endif +void Win32SetCurrentLocaleName(const char *iso_code); +int OTTDStringCompare(const char *s1, const char *s2); + #endif /* WIN32_H */ diff --git a/src/osk_gui.cpp b/src/osk_gui.cpp index 974e465f43..dc069d1686 100644 --- a/src/osk_gui.cpp +++ b/src/osk_gui.cpp @@ -437,9 +437,9 @@ void UpdateOSKOriginalText(const Window *parent, int button) /** * Check whether the OSK is opened for a specific editbox. - * @parent w Window to check for + * @param w Window to check for * @param button Editbox of \a w to check for - * @return true if the OSK is oppened for \a button. + * @return true if the OSK is opened for \a button. */ bool IsOSKOpenedFor(const Window *w, int button) { diff --git a/src/pathfinder/follow_track.hpp b/src/pathfinder/follow_track.hpp index 9f19b029c0..9b4377248e 100644 --- a/src/pathfinder/follow_track.hpp +++ b/src/pathfinder/follow_track.hpp @@ -73,7 +73,8 @@ struct CFollowTrackT inline void Init(Owner o, RailTypes railtype_override, CPerformanceTimer *pPerf) { - assert((!IsRoadTT() || m_veh != NULL) && (!IsRailTT() || railtype_override != INVALID_RAILTYPES)); + assert(!IsRoadTT() || m_veh != NULL); + assert(!IsRailTT() || railtype_override != INVALID_RAILTYPES); m_veh_owner = o; m_pPerf = pPerf; /* don't worry, all is inlined so compiler should remove unnecessary initializations */ @@ -123,8 +124,12 @@ struct CFollowTrackT m_old_tile = old_tile; m_old_td = old_td; m_err = EC_NONE; - assert(((TrackStatusToTrackdirBits(GetTileTrackStatus(m_old_tile, TT(), IsRoadTT() ? RoadVehicle::From(m_veh)->compatible_roadtypes : 0)) & TrackdirToTrackdirBits(m_old_td)) != 0) || - (IsTram() && GetSingleTramBit(m_old_tile) != INVALID_DIAGDIR)); // Disable the assertion for single tram bits + assert( + ((TrackStatusToTrackdirBits( + GetTileTrackStatus(m_old_tile, TT(), (IsRoadTT() && m_veh != NULL) ? RoadVehicle::From(m_veh)->compatible_roadtypes : 0) + ) & TrackdirToTrackdirBits(m_old_td)) != 0) || + (IsTram() && GetSingleTramBit(m_old_tile) != INVALID_DIAGDIR) // Disable the assertion for single tram bits + ); m_exitdir = TrackdirToExitdir(m_old_td); if (ForcedReverse()) return true; if (!CanExitOldTile()) return false; @@ -219,16 +224,13 @@ protected: } /* normal or station tile, do one step */ - TileIndexDiff diff = TileOffsByDiagDir(m_exitdir); - m_new_tile = TILE_ADD(m_old_tile, diff); + m_new_tile = TileAddByDiagDir(m_old_tile, m_exitdir); /* special handling for stations */ if (IsRailTT() && HasStationTileRail(m_new_tile)) { m_is_station = true; } else if (IsRoadTT() && IsRoadStopTile(m_new_tile)) { m_is_station = true; - } else { - m_is_station = false; } } @@ -241,7 +243,7 @@ protected: } else { m_new_td_bits = TrackStatusToTrackdirBits(GetTileTrackStatus(m_new_tile, TT(), IsRoadTT() ? RoadVehicle::From(m_veh)->compatible_roadtypes : 0)); - if (IsTram() && m_new_td_bits == 0) { + if (IsTram() && m_new_td_bits == TRACKDIR_BIT_NONE) { /* GetTileTrackStatus() returns 0 for single tram bits. * As we cannot change it there (easily) without breaking something, change it here */ switch (GetSingleTramBit(m_new_tile)) { @@ -408,8 +410,9 @@ protected: } } - /* single tram bits cause reversing */ - if (IsTram() && GetSingleTramBit(m_old_tile) == ReverseDiagDir(m_exitdir)) { + /* Single tram bits and standard road stops cause reversing. */ + if (IsRoadTT() && ((IsTram() && GetSingleTramBit(m_old_tile) == ReverseDiagDir(m_exitdir)) || + (IsStandardRoadStopTile(m_old_tile) && GetRoadStopDir(m_old_tile) == ReverseDiagDir(m_exitdir)))) { /* reverse */ m_new_tile = m_old_tile; m_new_td_bits = TrackdirToTrackdirBits(ReverseTrackdir(m_old_td)); diff --git a/src/pathfinder/npf/aystar.cpp b/src/pathfinder/npf/aystar.cpp index 9ef2bca479..8bd63beb7b 100644 --- a/src/pathfinder/npf/aystar.cpp +++ b/src/pathfinder/npf/aystar.cpp @@ -156,7 +156,7 @@ void AyStar::CheckTile(AyStarNode *current, OpenListNode *parent) * his neighbour items. If they are valid, they are added to be checked too. * @return Possible values: * - #AYSTAR_EMPTY_OPENLIST : indicates all items are tested, and no path has been found. - * - #AYSTAR_LIMIT_REACHED : Indicates that the max_nodes limit has been reached. + * - #AYSTAR_LIMIT_REACHED : Indicates that the max_search_nodes limit has been reached. * - #AYSTAR_FOUND_END_NODE : indicates we found the end. Path_found now is true, and in path is the path found. * - #AYSTAR_STILL_BUSY : indicates we have done this tile, did not found the path yet, and have items left to try. */ diff --git a/src/pathfinder/npf/aystar.h b/src/pathfinder/npf/aystar.h index eaa70bf915..4ee9df3329 100644 --- a/src/pathfinder/npf/aystar.h +++ b/src/pathfinder/npf/aystar.h @@ -30,7 +30,7 @@ enum AystarStatus { AYSTAR_EMPTY_OPENLIST, ///< All items are tested, and no path has been found. AYSTAR_STILL_BUSY, ///< Some checking was done, but no path found yet, and there are still items left to try. AYSTAR_NO_PATH, ///< No path to the goal was found. - AYSTAR_LIMIT_REACHED, ///< The #max_nodes limit has been reached, aborting search. + AYSTAR_LIMIT_REACHED, ///< The #AyStar::max_search_nodes limit has been reached, aborting search. AYSTAR_DONE, ///< Not an end-tile, or wrong direction. }; @@ -93,9 +93,9 @@ typedef int32 AyStar_CalculateG(AyStar *aystar, AyStarNode *current, OpenListNod typedef int32 AyStar_CalculateH(AyStar *aystar, AyStarNode *current, OpenListNode *parent); /** - * This function requests the tiles around the current tile and put them in #tiles_around. - * #tiles_around is never reset, so if you are not using directions, just leave it alone. - * \warning Never add more tiles_around than memory allocated for it. + * This function requests the tiles around the current tile and put them in #neighbours. + * #neighbours is never reset, so if you are not using directions, just leave it alone. + * @warning Never add more #neighbours than memory allocated for it. */ typedef void AyStar_GetNeighbours(AyStar *aystar, OpenListNode *current); diff --git a/src/pathfinder/npf/npf.cpp b/src/pathfinder/npf/npf.cpp index f989ff2c34..9535ac0636 100644 --- a/src/pathfinder/npf/npf.cpp +++ b/src/pathfinder/npf/npf.cpp @@ -807,7 +807,7 @@ static TrackdirBits GetDriveableTrackdirBits(TileIndex dst_tile, Trackdir src_tr { TrackdirBits trackdirbits = TrackStatusToTrackdirBits(GetTileTrackStatus(dst_tile, type, subtype)); - if (trackdirbits == 0 && type == TRANSPORT_ROAD && HasBit(subtype, ROADTYPE_TRAM)) { + if (trackdirbits == TRACKDIR_BIT_NONE && type == TRANSPORT_ROAD && HasBit(subtype, ROADTYPE_TRAM)) { /* GetTileTrackStatus() returns 0 for single tram bits. * As we cannot change it there (easily) without breaking something, change it here */ switch (GetSingleTramBit(dst_tile)) { @@ -900,7 +900,7 @@ static void NPFFollowTrack(AyStar *aystar, OpenListNode *current) trackdirbits = GetDriveableTrackdirBits(dst_tile, src_trackdir, type, subtype); - if (trackdirbits == 0) { + if (trackdirbits == TRACKDIR_BIT_NONE) { /* We cannot enter the next tile. Road vehicles can reverse, others reach dead end */ if (type != TRANSPORT_ROAD || HasBit(subtype, ROADTYPE_TRAM)) return; @@ -924,7 +924,7 @@ static void NPFFollowTrack(AyStar *aystar, OpenListNode *current) /* Enumerate possible track */ uint i = 0; - while (trackdirbits != 0) { + while (trackdirbits != TRACKDIR_BIT_NONE) { Trackdir dst_trackdir = RemoveFirstTrackdir(&trackdirbits); DEBUG(npf, 5, "Expanded into trackdir: %d, remaining trackdirs: 0x%X", dst_trackdir, trackdirbits); @@ -959,12 +959,13 @@ static void NPFFollowTrack(AyStar *aystar, OpenListNode *current) * multiple targets that are spread around, we should perform a breadth first * search by specifiying CalcZero as our heuristic. */ -static NPFFoundTargetData NPFRouteInternal(AyStarNode *start1, bool ignore_start_tile1, AyStarNode *start2, bool ignore_start_tile2, NPFFindStationOrTileData *target, AyStar_EndNodeCheck target_proc, AyStar_CalculateH heuristic_proc, AyStarUserData *user, uint reverse_penalty, bool ignore_reserved = false) +static NPFFoundTargetData NPFRouteInternal(AyStarNode *start1, bool ignore_start_tile1, AyStarNode *start2, bool ignore_start_tile2, NPFFindStationOrTileData *target, AyStar_EndNodeCheck target_proc, AyStar_CalculateH heuristic_proc, AyStarUserData *user, uint reverse_penalty, bool ignore_reserved = false, int max_penalty = 0) { int r; NPFFoundTargetData result; /* Initialize procs */ + _npf_aystar.max_path_cost = max_penalty; _npf_aystar.CalculateH = heuristic_proc; _npf_aystar.EndNodeCheck = target_proc; _npf_aystar.FoundEndNode = NPFSaveTargetData; @@ -1052,7 +1053,7 @@ static NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir track * reverse_penalty applied (NPF_TILE_LENGTH is the equivalent of one full * tile). */ -static NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, bool ignore_start_tile1, TileIndex tile2, Trackdir trackdir2, bool ignore_start_tile2, NPFFindStationOrTileData *target, AyStarUserData *user, uint reverse_penalty) +static NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, bool ignore_start_tile1, TileIndex tile2, Trackdir trackdir2, bool ignore_start_tile2, NPFFindStationOrTileData *target, AyStarUserData *user, uint reverse_penalty, int max_penalty) { AyStarNode start1; AyStarNode start2; @@ -1064,7 +1065,7 @@ static NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Tra /* perform a breadth first search. Target is NULL, * since we are just looking for any depot...*/ - return NPFRouteInternal(&start1, ignore_start_tile1, (IsValidTile(tile2) ? &start2 : NULL), ignore_start_tile2, target, NPFFindDepot, NPFCalcZero, user, reverse_penalty); + return NPFRouteInternal(&start1, ignore_start_tile1, (IsValidTile(tile2) ? &start2 : NULL), ignore_start_tile2, target, NPFFindDepot, NPFCalcZero, user, reverse_penalty, false, max_penalty); } void InitializeNPF() @@ -1114,7 +1115,7 @@ FindDepotData NPFRoadVehicleFindNearestDepot(const RoadVehicle *v, int max_penal Trackdir trackdir = v->GetVehicleTrackdir(); AyStarUserData user = { v->owner, TRANSPORT_ROAD, INVALID_RAILTYPES, v->compatible_roadtypes }; - NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, v->tile, ReverseTrackdir(trackdir), false, NULL, &user, 0); + NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, INVALID_TILE, INVALID_TRACKDIR, false, NULL, &user, 0, max_penalty); if (ftd.best_bird_dist != 0) return FindDepotData(); @@ -1169,7 +1170,7 @@ Track NPFShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, * we did not find our target, but ftd.best_trackdir contains the direction leading * to the tile closest to our target. */ path_found = (ftd.best_bird_dist == 0); - if (ftd.best_trackdir == 0xff) return INVALID_TRACK; + if (ftd.best_trackdir == INVALID_TRACKDIR) return INVALID_TRACK; return TrackdirToTrack(ftd.best_trackdir); } @@ -1204,7 +1205,7 @@ FindDepotData NPFTrainFindNearestDepot(const Train *v, int max_penalty) assert(trackdir != INVALID_TRACKDIR); AyStarUserData user = { v->owner, TRANSPORT_RAIL, v->compatible_railtypes, ROADTYPES_NONE }; - NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, last->tile, trackdir_rev, false, &fstd, &user, NPF_INFINITE_PENALTY); + NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, last->tile, trackdir_rev, false, &fstd, &user, NPF_INFINITE_PENALTY, max_penalty); if (ftd.best_bird_dist != 0) return FindDepotData(); /* Found target */ diff --git a/src/pathfinder/opf/opf_ship.cpp b/src/pathfinder/opf/opf_ship.cpp index 023c6a4a09..c993f82033 100644 --- a/src/pathfinder/opf/opf_ship.cpp +++ b/src/pathfinder/opf/opf_ship.cpp @@ -145,6 +145,7 @@ static uint FindShipTrack(const Ship *v, TileIndex tile, DiagDirection dir, Trac Track best_track = INVALID_TRACK; + assert(bits != TRACK_BIT_NONE); do { Track i = RemoveFirstTrack(&bits); @@ -176,16 +177,21 @@ good:; best_length = pfs.best_length; bad:; - } while (bits != 0); + } while (bits != TRACK_BIT_NONE); *track = best_track; return best_bird_dist; } /** - * returns the track to choose on the next tile, or -1 when it's better to - * reverse. The tile given is the tile we are about to enter, enterdir is the - * direction in which we are entering the tile + * Finds the best track to choose on the next tile and + * returns INVALID_TRACK when it is better to reverse. + * @param v The ship. + * @param tile The tile we are about to enter. + * @param enterdir The direction entering the tile. + * @param tracks The tracks available on new tile. + * @param[out] path_found Whether a path has been found. + * @return Best track on next tile or INVALID_TRACK when better to reverse. */ Track OPFShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found) { @@ -195,13 +201,15 @@ Track OPFShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, Track track; /* Let's find out how far it would be if we would reverse first */ - Trackdir trackdir = v->GetVehicleTrackdir(); - TrackBits b = TrackStatusToTrackBits(GetTileTrackStatus(tile2, TRANSPORT_WATER, 0)) & DiagdirReachesTracks(ReverseDiagDir(enterdir)) & TrackdirBitsToTrackBits(TrackdirToTrackdirBits(trackdir)); + uint rev_dist = UINT_MAX; // distance if we reverse + Track cur_track = TrackdirToTrack(v->GetVehicleTrackdir()); // track on the current tile + DiagDirection rev_enterdir = ReverseDiagDir(enterdir); + TrackBits rev_tracks = TrackStatusToTrackBits(GetTileTrackStatus(tile2, TRANSPORT_WATER, 0)) & + DiagdirReachesTracks(rev_enterdir); - uint distr = UINT_MAX; // distance if we reversed - if (b != 0) { - distr = FindShipTrack(v, tile2, ReverseDiagDir(enterdir), b, tile, &track); - if (distr != UINT_MAX) distr++; // penalty for reversing + if (HasTrack(rev_tracks, cur_track)) { + rev_dist = FindShipTrack(v, tile2, rev_enterdir, TrackToTrackBits(cur_track), tile, &track); + if (rev_dist != UINT_MAX) rev_dist++; // penalty for reversing } /* And if we would not reverse? */ @@ -209,6 +217,6 @@ Track OPFShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, /* Due to the way this pathfinder works we cannot determine whether we're lost or not. */ path_found = true; - if (dist <= distr) return track; + if (dist <= rev_dist) return track; return INVALID_TRACK; // We could better reverse } diff --git a/src/pathfinder/pathfinder_type.h b/src/pathfinder/pathfinder_type.h index 9f5a42d76d..73031d5c81 100644 --- a/src/pathfinder/pathfinder_type.h +++ b/src/pathfinder/pathfinder_type.h @@ -20,8 +20,8 @@ static const int NPF_TILE_LENGTH = 100; /** * This penalty is the equivalent of "infinite", which means that paths that * get this penalty will be chosen, but only if there is no other route - * without it. Be careful with not applying this penalty to often, or the - * total path cost might overflow.. + * without it. Be careful with not applying this penalty too often, or the + * total path cost might overflow. */ static const int NPF_INFINITE_PENALTY = 1000 * NPF_TILE_LENGTH; @@ -35,8 +35,8 @@ static const int YAPF_TILE_CORNER_LENGTH = 71; /** * This penalty is the equivalent of "infinite", which means that paths that * get this penalty will be chosen, but only if there is no other route - * without it. Be careful with not applying this penalty to often, or the - * total path cost might overflow.. + * without it. Be careful with not applying this penalty too often, or the + * total path cost might overflow. */ static const int YAPF_INFINITE_PENALTY = 1000 * YAPF_TILE_LENGTH; diff --git a/src/pathfinder/yapf/nodelist.hpp b/src/pathfinder/yapf/nodelist.hpp index e82f869f1e..87e65fd26e 100644 --- a/src/pathfinder/yapf/nodelist.hpp +++ b/src/pathfinder/yapf/nodelist.hpp @@ -25,7 +25,7 @@ template class CNodeList_HashTableT { public: typedef Titem_ Titem; ///< Make #Titem_ visible from outside of class. - typedef typename Titem_::Key Key; ///< Make Titem_::Key a property of #HashTable. + typedef typename Titem_::Key Key; ///< Make Titem_::Key a property of this class. typedef SmallArray CItemArray; ///< Type that we will use as item container. typedef CHashTableT COpenList; ///< How pointers to open nodes will be stored. typedef CHashTableT CClosedList; ///< How pointers to closed nodes will be stored. diff --git a/src/pathfinder/yapf/yapf_common.hpp b/src/pathfinder/yapf/yapf_common.hpp index 660c231161..8ff69b3f6b 100644 --- a/src/pathfinder/yapf/yapf_common.hpp +++ b/src/pathfinder/yapf/yapf_common.hpp @@ -142,8 +142,7 @@ public: /** Called by YAPF to detect if node ends in the desired destination */ inline bool PfDetectDestination(Node &n) { - bool bDest = (n.m_key.m_tile == m_destTile) && ((m_destTrackdirs & TrackdirToTrackdirBits(n.GetTrackdir())) != TRACKDIR_BIT_NONE); - return bDest; + return (n.m_key.m_tile == m_destTile) && HasTrackdir(m_destTrackdirs, n.GetTrackdir()); } /** diff --git a/src/pathfinder/yapf/yapf_costrail.hpp b/src/pathfinder/yapf/yapf_costrail.hpp index ca317f09a7..022b9a1678 100644 --- a/src/pathfinder/yapf/yapf_costrail.hpp +++ b/src/pathfinder/yapf/yapf_costrail.hpp @@ -104,7 +104,7 @@ public: assert(IsValidTrackdir(td2)); int cost = 0; if (TrackFollower::Allow90degTurns() - && ((TrackdirToTrackdirBits(td2) & (TrackdirBits)TrackdirCrossesTrackdirs(td1)) != 0)) { + && HasTrackdir(TrackdirCrossesTrackdirs(td1), td2)) { /* 90-deg curve penalty */ cost += Yapf().PfGetSettings().rail_curve90_penalty; } else if (td2 != NextTrackdir(td1)) { @@ -280,7 +280,7 @@ public: { assert(!n.flags_u.flags_s.m_targed_seen); assert(tf->m_new_tile == n.m_key.m_tile); - assert((TrackdirToTrackdirBits(n.m_key.m_td) & tf->m_new_td_bits) != TRACKDIR_BIT_NONE); + assert((HasTrackdir(tf->m_new_td_bits, n.m_key.m_td))); CPerfStart perf_cost(Yapf().m_perf_cost); diff --git a/src/pathfinder/yapf/yapf_destrail.hpp b/src/pathfinder/yapf/yapf_destrail.hpp index 03519b059f..1d1833fbfd 100644 --- a/src/pathfinder/yapf/yapf_destrail.hpp +++ b/src/pathfinder/yapf/yapf_destrail.hpp @@ -166,16 +166,13 @@ public: /** Called by YAPF to detect if node ends in the desired destination */ inline bool PfDetectDestination(TileIndex tile, Trackdir td) { - bool bDest; if (m_dest_station_id != INVALID_STATION) { - bDest = HasStationTileRail(tile) + return HasStationTileRail(tile) && (GetStationIndex(tile) == m_dest_station_id) && (GetRailStationTrack(tile) == TrackdirToTrack(td)); - } else { - bDest = (tile == m_destTile) - && ((m_destTrackdirs & TrackdirToTrackdirBits(td)) != TRACKDIR_BIT_NONE); } - return bDest; + + return (tile == m_destTile) && HasTrackdir(m_destTrackdirs, td); } /** diff --git a/src/pathfinder/yapf/yapf_rail.cpp b/src/pathfinder/yapf/yapf_rail.cpp index dccee36860..d3f8e8aeee 100644 --- a/src/pathfinder/yapf/yapf_rail.cpp +++ b/src/pathfinder/yapf/yapf_rail.cpp @@ -28,6 +28,8 @@ template void DumpState(Tpf &pf1, Tpf &pf2) pf2.DumpBase(dmp2); FILE *f1 = fopen("yapf1.txt", "wt"); FILE *f2 = fopen("yapf2.txt", "wt"); + assert(f1 != NULL); + assert(f2 != NULL); fwrite(dmp1.m_out.Data(), 1, dmp1.m_out.Size(), f1); fwrite(dmp2.m_out.Data(), 1, dmp2.m_out.Size(), f2); fclose(f1); diff --git a/src/pathfinder/yapf/yapf_road.cpp b/src/pathfinder/yapf/yapf_road.cpp index 380b641da7..0240eb9366 100644 --- a/src/pathfinder/yapf/yapf_road.cpp +++ b/src/pathfinder/yapf/yapf_road.cpp @@ -27,6 +27,10 @@ public: typedef typename Node::Key Key; ///< key to hash tables protected: + int m_max_cost; + + CYapfCostRoadT() : m_max_cost(0) {}; + /** to access inherited path finder */ Tpf& Yapf() { @@ -97,6 +101,11 @@ protected: } public: + inline void SetMaxCost(int max_cost) + { + m_max_cost = max_cost; + } + /** * Called by YAPF to calculate the cost from the origin to the given node. * Calculates only the cost of given node, adds it to the parent node cost @@ -109,6 +118,8 @@ public: /* start at n.m_key.m_tile / n.m_key.m_td and walk to the end of segment */ TileIndex tile = n.m_key.m_tile; Trackdir trackdir = n.m_key.m_td; + int parent_cost = (n.m_parent != NULL) ? n.m_parent->m_cost : 0; + for (;;) { /* base tile cost depending on distance between edges */ segment_cost += Yapf().OneTileCost(tile, trackdir); @@ -117,6 +128,12 @@ public: /* we have reached the vehicle's destination - segment should end here to avoid target skipping */ if (Yapf().PfDetectDestinationTile(tile, trackdir)) break; + /* Finish if we already exceeded the maximum path cost (i.e. when + * searching for the nearest depot). */ + if (m_max_cost > 0 && (parent_cost + segment_cost) > m_max_cost) { + return false; + } + /* stop if we have just entered the depot */ if (IsRoadDepotTile(tile) && trackdir == DiagDirToDiagTrackdir(ReverseDiagDir(GetRoadDepotDirection(tile)))) { /* next time we will reverse and leave the depot */ @@ -160,7 +177,6 @@ public: n.m_segment_last_td = trackdir; /* save also tile cost */ - int parent_cost = (n.m_parent != NULL) ? n.m_parent->m_cost : 0; n.m_cost = parent_cost + segment_cost; return true; } @@ -185,8 +201,7 @@ public: /** Called by YAPF to detect if node ends in the desired destination */ inline bool PfDetectDestination(Node &n) { - bool bDest = IsRoadDepotTile(n.m_segment_last_tile); - return bDest; + return IsRoadDepotTile(n.m_segment_last_tile); } inline bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir) @@ -261,7 +276,7 @@ public: (m_non_artic || IsDriveThroughStopTile(tile)); } - return tile == m_destTile && ((m_destTrackdirs & TrackdirToTrackdirBits(trackdir)) != TRACKDIR_BIT_NONE); + return tile == m_destTile && HasTrackdir(m_destTrackdirs, trackdir); } /** @@ -421,7 +436,7 @@ public: /* set origin (tile, trackdir) */ TileIndex src_tile = v->tile; Trackdir src_td = v->GetVehicleTrackdir(); - if ((TrackStatusToTrackdirBits(GetTileTrackStatus(src_tile, TRANSPORT_ROAD, v->compatible_roadtypes)) & TrackdirToTrackdirBits(src_td)) == 0) { + if (!HasTrackdir(TrackStatusToTrackdirBits(GetTileTrackStatus(src_tile, TRANSPORT_ROAD, v->compatible_roadtypes)), src_td)) { /* sometimes the roadveh is not on the road (it resides on non-existing track) * how should we handle that situation? */ return false; @@ -442,15 +457,12 @@ public: * @param tile Tile of the vehicle. * @param td Trackdir of the vehicle. * @param max_distance max length (penalty) for paths. - * @todo max_distance not used by YAPF for road vehicles. - * It can be removed or copy the SetMaxCost() strategy - * applied in YAPF for rail. The best depot can be at - * a distance greater than max_distance. */ inline FindDepotData FindNearestDepot(const RoadVehicle *v, TileIndex tile, Trackdir td, int max_distance) { /* Set origin. */ Yapf().SetOrigin(tile, TrackdirToTrackdirBits(td)); + Yapf().SetMaxCost(max_distance); /* Find the best path and return if no depot is found. */ if (!Yapf().FindPath(v)) return FindDepotData(); @@ -504,7 +516,7 @@ FindDepotData YapfRoadVehicleFindNearestDepot(const RoadVehicle *v, int max_dist { TileIndex tile = v->tile; Trackdir trackdir = v->GetVehicleTrackdir(); - if ((TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, v->compatible_roadtypes)) & TrackdirToTrackdirBits(trackdir)) == 0) { + if (!HasTrackdir(TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, v->compatible_roadtypes)), trackdir)) { return FindDepotData(); } diff --git a/src/pathfinder/yapf/yapf_ship.cpp b/src/pathfinder/yapf/yapf_ship.cpp index e4b99462d2..44a5c0cfa7 100644 --- a/src/pathfinder/yapf/yapf_ship.cpp +++ b/src/pathfinder/yapf/yapf_ship.cpp @@ -65,11 +65,11 @@ public: /* use vehicle's current direction if that's possible, otherwise use first usable one. */ Trackdir veh_dir = v->GetVehicleTrackdir(); - return ((trackdirs & TrackdirToTrackdirBits(veh_dir)) != 0) ? veh_dir : (Trackdir)FindFirstBit2x64(trackdirs); + return (HasTrackdir(trackdirs, veh_dir)) ? veh_dir : (Trackdir)FindFirstBit2x64(trackdirs); } /* move back to the old tile/trackdir (where ship is coming from) */ - TileIndex src_tile = TILE_ADD(tile, TileOffsByDiagDir(ReverseDiagDir(enterdir))); + TileIndex src_tile = TileAddByDiagDir(tile, ReverseDiagDir(enterdir)); Trackdir trackdir = v->GetVehicleTrackdir(); assert(IsValidTrackdir(trackdir)); diff --git a/src/pbs.cpp b/src/pbs.cpp index 133293909f..6bb35a6964 100644 --- a/src/pbs.cpp +++ b/src/pbs.cpp @@ -81,7 +81,7 @@ void SetRailStationPlatformReservation(TileIndex start, DiagDirection dir, bool */ bool TryReserveRailTrack(TileIndex tile, Track t, bool trigger_stations) { - assert((GetTileTrackStatus(tile, TRANSPORT_RAIL, 0) & TrackToTrackBits(t)) != 0); + assert(HasTrack(TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_RAIL, 0)), t)); if (_settings_client.gui.show_track_reservation) { /* show the reserved rail if needed */ @@ -142,7 +142,7 @@ bool TryReserveRailTrack(TileIndex tile, Track t, bool trigger_stations) */ void UnreserveRailTrack(TileIndex tile, Track t) { - assert((GetTileTrackStatus(tile, TRANSPORT_RAIL, 0) & TrackToTrackBits(t)) != 0); + assert(HasTrack(TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_RAIL, 0)), t)); if (_settings_client.gui.show_track_reservation) { if (IsBridgeTile(tile)) { diff --git a/src/rail.cpp b/src/rail.cpp index d538064a23..1664f78e9a 100644 --- a/src/rail.cpp +++ b/src/rail.cpp @@ -251,7 +251,7 @@ RailTypes AddDateIntroducedRailTypes(RailTypes current, Date date) /** * Get the rail types the given company can build. - * @param c the company to get the rail types for. + * @param company the company to get the rail types for. * @return the rail types. */ RailTypes GetCompanyRailtypes(CompanyID company) diff --git a/src/rail.h b/src/rail.h index 1bc403d7fd..b7258d3016 100644 --- a/src/rail.h +++ b/src/rail.h @@ -239,7 +239,7 @@ public: * When #INVALID_DATE or a vehicle using this railtype gets introduced earlier, * the vehicle's introduction date will be used instead for this railtype. * The introduction at this date is furthermore limited by the - * #introduction_required_types. + * #introduction_required_railtypes. */ Date introduction_date; diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 9f284fc305..a0fd968cc6 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -166,11 +166,11 @@ RailType AllocateRailType(RailTypeLabel label) rti->alternate_labels.Clear(); /* Make us compatible with ourself. */ - rti->powered_railtypes = (RailTypes)(1 << rt); - rti->compatible_railtypes = (RailTypes)(1 << rt); + rti->powered_railtypes = (RailTypes)(1LL << rt); + rti->compatible_railtypes = (RailTypes)(1LL << rt); /* We also introduce ourself. */ - rti->introduces_railtypes = (RailTypes)(1 << rt); + rti->introduces_railtypes = (RailTypes)(1LL << rt); /* Default sort order; order of allocation, but with some * offsets so it's easier for NewGRF to pick a spot without @@ -441,7 +441,7 @@ static inline bool ValParamTrackOrientation(Track track) */ CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { - RailType railtype = Extract(p1); + RailType railtype = Extract(p1); Track track = Extract(p2); CommandCost cost(EXPENSES_CONSTRUCTION); @@ -554,8 +554,8 @@ CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, u if (IsLevelCrossing(tile) && GetCrossingRailBits(tile) == trackbit) { return_cmd_error(STR_ERROR_ALREADY_BUILT); } + FALLTHROUGH; } - FALLTHROUGH; default: { /* Will there be flat water on the lower halftile? */ @@ -854,19 +854,19 @@ static CommandCost ValidateAutoDrag(Trackdir *trackdir, TileIndex start, TileInd * @param flags operation to perform * @param p1 end tile of drag * @param p2 various bitstuffed elements - * - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev), only used for building - * - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum) - * - p2 = (bit 7) - 0 = build, 1 = remove tracks - * - p2 = (bit 8) - 0 = build up to an obstacle, 1 = fail if an obstacle is found (used for AIs). + * - p2 = (bit 0-5) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev), only used for building + * - p2 = (bit 6-8) - track-orientation, valid values: 0-5 (Track enum) + * - p2 = (bit 9) - 0 = build, 1 = remove tracks + * - p2 = (bit 10) - 0 = build up to an obstacle, 1 = fail if an obstacle is found (used for AIs). * @param text unused * @return the cost of this operation or an error */ static CommandCost CmdRailTrackHelper(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { CommandCost total_cost(EXPENSES_CONSTRUCTION); - Track track = Extract(p2); - bool remove = HasBit(p2, 7); - RailType railtype = Extract(p2); + Track track = Extract(p2); + bool remove = HasBit(p2, 9); + RailType railtype = Extract(p2); if ((!remove && !ValParamRailtype(railtype)) || !ValParamTrackOrientation(track)) return CMD_ERROR; if (p1 >= MapSize()) return CMD_ERROR; @@ -884,7 +884,7 @@ static CommandCost CmdRailTrackHelper(TileIndex tile, DoCommandFlag flags, uint3 if (ret.Failed()) { last_error = ret; if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT && !remove) { - if (HasBit(p2, 8)) return last_error; + if (HasBit(p2, 10)) return last_error; break; } @@ -914,16 +914,16 @@ static CommandCost CmdRailTrackHelper(TileIndex tile, DoCommandFlag flags, uint3 * @param flags operation to perform * @param p1 end tile of drag * @param p2 various bitstuffed elements - * - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev) - * - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum) - * - p2 = (bit 7) - 0 = build, 1 = remove tracks + * - p2 = (bit 0-5) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev) + * - p2 = (bit 6-8) - track-orientation, valid values: 0-5 (Track enum) + * - p2 = (bit 9) - 0 = build, 1 = remove tracks * @param text unused * @return the cost of this operation or an error * @see CmdRailTrackHelper */ CommandCost CmdBuildRailroadTrack(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { - return CmdRailTrackHelper(tile, flags, p1, ClrBit(p2, 7), text); + return CmdRailTrackHelper(tile, flags, p1, ClrBit(p2, 9), text); } /** @@ -933,16 +933,16 @@ CommandCost CmdBuildRailroadTrack(TileIndex tile, DoCommandFlag flags, uint32 p1 * @param flags operation to perform * @param p1 end tile of drag * @param p2 various bitstuffed elements - * - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev), only used for building - * - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum) - * - p2 = (bit 7) - 0 = build, 1 = remove tracks + * - p2 = (bit 0-5) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev), only used for building + * - p2 = (bit 6-8) - track-orientation, valid values: 0-5 (Track enum) + * - p2 = (bit 9) - 0 = build, 1 = remove tracks * @param text unused * @return the cost of this operation or an error * @see CmdRailTrackHelper */ CommandCost CmdRemoveRailroadTrack(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { - return CmdRailTrackHelper(tile, flags, p1, SetBit(p2, 7), text); + return CmdRailTrackHelper(tile, flags, p1, SetBit(p2, 9), text); } /** @@ -960,13 +960,15 @@ CommandCost CmdRemoveRailroadTrack(TileIndex tile, DoCommandFlag flags, uint32 p CommandCost CmdBuildTrainDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { /* check railtype and valid direction for depot (0 through 3), 4 in total */ - RailType railtype = Extract(p1); + RailType railtype = Extract(p1); if (!ValParamRailtype(railtype)) return CMD_ERROR; Slope tileh = GetTileSlope(tile); DiagDirection dir = Extract(p2); + CommandCost cost(EXPENSES_CONSTRUCTION); + /* Prohibit construction if * The tile is non-flat AND * 1) build-on-slopes is disabled @@ -974,14 +976,14 @@ CommandCost CmdBuildTrainDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, u * 3) the exit points in the wrong direction */ - if (tileh != SLOPE_FLAT && ( - !_settings_game.construction.build_on_slopes || - !CanBuildDepotByTileh(dir, tileh) - )) { - return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED); + if (tileh != SLOPE_FLAT) { + if (!_settings_game.construction.build_on_slopes || !CanBuildDepotByTileh(dir, tileh)) { + return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED); + } + cost.AddCost(_price[PR_BUILD_FOUNDATION]); } - CommandCost cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + cost.AddCost(DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR)); if (cost.Failed()) return cost; if (IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); @@ -1540,17 +1542,17 @@ static Vehicle *UpdateTrainPowerProc(Vehicle *v, void *data) * @param flags operation to perform * @param p1 start tile of drag * @param p2 various bitstuffed elements: - * - p2 = (bit 0- 3) new railtype to convert to. - * - p2 = (bit 4) build diagonally or not. + * - p2 = (bit 0- 5) new railtype to convert to. + * - p2 = (bit 6) build diagonally or not. * @param text unused * @return the cost of this operation or an error */ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { - RailType totype = Extract(p2); + RailType totype = Extract(p2); TileIndex area_start = p1; TileIndex area_end = tile; - bool diagonal = HasBit(p2, 4); + bool diagonal = HasBit(p2, 6); if (!ValParamRailtype(totype)) return CMD_ERROR; if (area_start >= MapSize()) return CMD_ERROR; @@ -2895,11 +2897,9 @@ int TicksToLeaveDepot(const Train *v) case DIAGDIR_NE: return ((int)(v->x_pos & 0x0F) - ((_fractcoords_enter[dir] & 0x0F) - (length + 1))); case DIAGDIR_SE: return -((int)(v->y_pos & 0x0F) - ((_fractcoords_enter[dir] >> 4) + (length + 1))); case DIAGDIR_SW: return -((int)(v->x_pos & 0x0F) - ((_fractcoords_enter[dir] & 0x0F) + (length + 1))); - default: case DIAGDIR_NW: return ((int)(v->y_pos & 0x0F) - ((_fractcoords_enter[dir] >> 4) - (length + 1))); + default: NOT_REACHED(); } - - return 0; // make compilers happy } /** diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 73fe29da0d..5a533e5c55 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -192,7 +192,7 @@ static void PlaceRail_Station(TileIndex tile) VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_BUILD_STATION); VpSetPlaceSizingLimit(_settings_game.station.station_spread); } else { - uint32 p1 = _cur_railtype | _railstation.orientation << 4 | _settings_client.gui.station_numtracks << 8 | _settings_client.gui.station_platlength << 16 | _ctrl_pressed << 24; + uint32 p1 = _cur_railtype | _railstation.orientation << 6 | _settings_client.gui.station_numtracks << 8 | _settings_client.gui.station_platlength << 16 | _ctrl_pressed << 24; uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16; int w = _settings_client.gui.station_numtracks; @@ -352,7 +352,7 @@ static void BuildRailClick_Remove(Window *w) static void DoRailroadTrack(int mode) { - DoCommandP(TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), _cur_railtype | (mode << 4), + DoCommandP(TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), _cur_railtype | (mode << 6), _remove_button_clicked ? CMD_REMOVE_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK) : CMD_BUILD_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK), @@ -711,7 +711,7 @@ struct BuildRailToolbarWindow : Window { break; case DDSP_CONVERT_RAIL: - DoCommandP(end_tile, start_tile, _cur_railtype | (_ctrl_pressed ? 0x10 : 0), CMD_CONVERT_RAIL | CMD_MSG(STR_ERROR_CAN_T_CONVERT_RAIL), CcPlaySound_SPLAT_RAIL); + DoCommandP(end_tile, start_tile, _cur_railtype | (_ctrl_pressed ? 1 << 6 : 0), CMD_CONVERT_RAIL | CMD_MSG(STR_ERROR_CAN_T_CONVERT_RAIL), CcPlaySound_SPLAT_RAIL); break; case DDSP_REMOVE_STATION: @@ -729,7 +729,7 @@ struct BuildRailToolbarWindow : Window { DoCommandP(end_tile, start_tile, _ctrl_pressed ? 0 : 1, CMD_REMOVE_FROM_RAIL_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT), CcPlaySound_SPLAT_RAIL); } else { TileArea ta(start_tile, end_tile); - uint32 p1 = _cur_railtype | (select_method == VPM_X_LIMITED ? AXIS_X : AXIS_Y) << 4 | ta.w << 8 | ta.h << 16 | _ctrl_pressed << 24; + uint32 p1 = _cur_railtype | (select_method == VPM_X_LIMITED ? AXIS_X : AXIS_Y) << 6 | ta.w << 8 | ta.h << 16 | _ctrl_pressed << 24; uint32 p2 = STAT_CLASS_WAYP | _cur_waypoint_type << 8 | INVALID_STATION << 16; CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT), CcPlaySound_SPLAT_RAIL, "" }; @@ -886,7 +886,7 @@ static void HandleStationPlacement(TileIndex start, TileIndex end) if (_railstation.orientation == AXIS_X) Swap(numtracks, platlength); - uint32 p1 = _cur_railtype | _railstation.orientation << 4 | numtracks << 8 | platlength << 16 | _ctrl_pressed << 24; + uint32 p1 = _cur_railtype | _railstation.orientation << 6 | numtracks << 8 | platlength << 16 | _ctrl_pressed << 24; uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16; CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION), CcStation, "" }; @@ -1908,7 +1908,7 @@ static void SetDefaultRailGui() RailType rt = (RailType)(_settings_client.gui.default_rail_type + RAILTYPE_END); if (rt == DEF_RAILTYPE_MOST_USED) { /* Find the most used rail type */ - RailType count[RAILTYPE_END]; + uint count[RAILTYPE_END]; memset(count, 0, sizeof(count)); for (TileIndex t = 0; t < MapSize(); t++) { if (IsTileType(t, MP_RAILWAY) || IsLevelCrossingTile(t) || HasStationTileRail(t) || diff --git a/src/rail_map.h b/src/rail_map.h index 2431a79202..74afe5ace5 100644 --- a/src/rail_map.h +++ b/src/rail_map.h @@ -115,7 +115,7 @@ static inline bool IsRailDepotTile(TileIndex t) */ static inline RailType GetRailType(TileIndex t) { - return (RailType)GB(_m[t].m3, 0, 4); + return (RailType)GB(_me[t].m8, 0, 6); } /** @@ -125,7 +125,7 @@ static inline RailType GetRailType(TileIndex t) */ static inline void SetRailType(TileIndex t, RailType r) { - SB(_m[t].m3, 0, 4, r); + SB(_me[t].m8, 0, 6, r); } @@ -522,11 +522,12 @@ static inline void MakeRailNormal(TileIndex t, Owner o, TrackBits b, RailType r) SetTileType(t, MP_RAILWAY); SetTileOwner(t, o); _m[t].m2 = 0; - _m[t].m3 = r; + _m[t].m3 = 0; _m[t].m4 = 0; _m[t].m5 = RAIL_TILE_NORMAL << 6 | b; SB(_me[t].m6, 2, 4, 0); _me[t].m7 = 0; + _me[t].m8 = r; } @@ -535,11 +536,12 @@ static inline void MakeRailDepot(TileIndex t, Owner o, DepotID did, DiagDirectio SetTileType(t, MP_RAILWAY); SetTileOwner(t, o); _m[t].m2 = did; - _m[t].m3 = r; + _m[t].m3 = 0; _m[t].m4 = 0; _m[t].m5 = RAIL_TILE_DEPOT << 6 | d; SB(_me[t].m6, 2, 4, 0); _me[t].m7 = 0; + _me[t].m8 = r; } #endif /* RAIL_MAP_H */ diff --git a/src/rail_type.h b/src/rail_type.h index ee589898b8..2bd602a37e 100644 --- a/src/rail_type.h +++ b/src/rail_type.h @@ -32,7 +32,7 @@ enum RailType { RAILTYPE_ELECTRIC = 1, ///< Electric rails RAILTYPE_MONO = 2, ///< Monorail RAILTYPE_MAGLEV = 3, ///< Maglev - RAILTYPE_END = 16, ///< Used for iterations + RAILTYPE_END = 64, ///< Used for iterations INVALID_RAILTYPE = 0xFF, ///< Flag for invalid railtype DEF_RAILTYPE_FIRST = RAILTYPE_END, ///< Default railtype: first available @@ -43,19 +43,20 @@ enum RailType { /** Allow incrementing of Track variables */ DECLARE_POSTFIX_INCREMENT(RailType) /** Define basic enum properties */ -template <> struct EnumPropsT : MakeEnumPropsT {}; +template <> struct EnumPropsT : MakeEnumPropsT {}; typedef TinyEnumT RailTypeByte; /** - * The different roadtypes we support, but then a bitmask of them + * The different railtypes we support, but then a bitmask of them. + * @note Must be treated as a uint64 type, narrowing it causes bit membership tests to give wrong results, as in bug #6951. */ -enum RailTypes { +enum RailTypes : uint64 { RAILTYPES_NONE = 0, ///< No rail types RAILTYPES_RAIL = 1 << RAILTYPE_RAIL, ///< Non-electrified rails RAILTYPES_ELECTRIC = 1 << RAILTYPE_ELECTRIC, ///< Electrified rails RAILTYPES_MONO = 1 << RAILTYPE_MONO, ///< Monorail! RAILTYPES_MAGLEV = 1 << RAILTYPE_MAGLEV, ///< Ever fast maglev - INVALID_RAILTYPES = UINT_MAX, ///< Invalid railtypes + INVALID_RAILTYPES = UINT64_MAX, ///< Invalid railtypes }; DECLARE_ENUM_AS_BIT_SET(RailTypes) diff --git a/src/rev.cpp.in b/src/rev.cpp.in index 6689fe6891..0f4b2a6b57 100644 --- a/src/rev.cpp.in +++ b/src/rev.cpp.in @@ -64,13 +64,13 @@ const byte _openttd_revision_modified = !!MODIFIED!!; * 24-27 minor version * 20-23 build * 19 1 if it is a release, 0 if it is not. - * 0-18 used to be the SVN revision, currently unused + * 0-18 used to be the SVN revision, now just last revision before switch to git * * The 19th bit is there so the development/betas/alpha, etc. leading to a * final release will always have a lower version number than the released * version, thus making comparisons on specific revisions easy. */ -const uint32 _openttd_newgrf_version = 1 << 28 | 9 << 24 | 0 << 20 | 0 << 19; +const uint32 _openttd_newgrf_version = 1 << 28 | 9 << 24 | 0 << 20 | 0 << 19 | 28004; #ifdef __MORPHOS__ /** diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 5e432a2e6b..bdc8ce7f30 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -1017,15 +1017,17 @@ CommandCost CmdBuildRoadDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, ui if (!IsValidRoadType(rt) || !ValParamRoadType(rt)) return CMD_ERROR; + CommandCost cost(EXPENSES_CONSTRUCTION); + Slope tileh = GetTileSlope(tile); - if (tileh != SLOPE_FLAT && ( - !_settings_game.construction.build_on_slopes || - !CanBuildDepotByTileh(dir, tileh) - )) { - return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED); + if (tileh != SLOPE_FLAT) { + if (!_settings_game.construction.build_on_slopes || !CanBuildDepotByTileh(dir, tileh)) { + return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED); + } + cost.AddCost(_price[PR_BUILD_FOUNDATION]); } - CommandCost cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + cost.AddCost(DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR)); if (cost.Failed()) return cost; if (IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); diff --git a/src/road_func.h b/src/road_func.h index c4af229d53..06be7c4aa0 100644 --- a/src/road_func.h +++ b/src/road_func.h @@ -39,7 +39,7 @@ static inline bool IsValidRoadType(RoadType rt) /** * Whether the given roadtype is valid. - * @param rt the roadtype to check for validness + * @param r the roadtype to check for validness * @return true if and only if valid */ static inline bool IsValidRoadBits(RoadBits r) diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 801d334351..6faa422627 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -633,24 +633,28 @@ struct BuildRoadToolbarWindow : Window { break; case DDSP_BUILD_BUSSTOP: - PlaceRoadStop(start_tile, end_tile, (_ctrl_pressed << 5) | RoadTypeToRoadTypes(_cur_roadtype) << 2 | ROADSTOP_BUS, CMD_BUILD_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_build_station[ROADSTOP_BUS])); + case DDSP_REMOVE_BUSSTOP: + if (this->IsWidgetLowered(WID_ROT_BUS_STATION)) { + if (_remove_button_clicked) { + TileArea ta(start_tile, end_tile); + DoCommandP(ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_BUS, CMD_REMOVE_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_remove_station[ROADSTOP_BUS]), CcPlaySound_SPLAT_OTHER); + } else { + PlaceRoadStop(start_tile, end_tile, (_ctrl_pressed << 5) | RoadTypeToRoadTypes(_cur_roadtype) << 2 | ROADSTOP_BUS, CMD_BUILD_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_build_station[ROADSTOP_BUS])); + } + } break; case DDSP_BUILD_TRUCKSTOP: - PlaceRoadStop(start_tile, end_tile, (_ctrl_pressed << 5) | RoadTypeToRoadTypes(_cur_roadtype) << 2 | ROADSTOP_TRUCK, CMD_BUILD_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_build_station[ROADSTOP_TRUCK])); + case DDSP_REMOVE_TRUCKSTOP: + if (this->IsWidgetLowered(WID_ROT_TRUCK_STATION)) { + if (_remove_button_clicked) { + TileArea ta(start_tile, end_tile); + DoCommandP(ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_TRUCK, CMD_REMOVE_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_remove_station[ROADSTOP_TRUCK]), CcPlaySound_SPLAT_OTHER); + } else { + PlaceRoadStop(start_tile, end_tile, (_ctrl_pressed << 5) | RoadTypeToRoadTypes(_cur_roadtype) << 2 | ROADSTOP_TRUCK, CMD_BUILD_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_build_station[ROADSTOP_TRUCK])); + } + } break; - - case DDSP_REMOVE_BUSSTOP: { - TileArea ta(start_tile, end_tile); - DoCommandP(ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_BUS, CMD_REMOVE_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_remove_station[ROADSTOP_BUS]), CcPlaySound_SPLAT_OTHER); - break; - } - - case DDSP_REMOVE_TRUCKSTOP: { - TileArea ta(start_tile, end_tile); - DoCommandP(ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_TRUCK, CMD_REMOVE_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_remove_station[ROADSTOP_TRUCK]), CcPlaySound_SPLAT_OTHER); - break; - } } } } diff --git a/src/road_map.h b/src/road_map.h index 693730294e..49526d37f2 100644 --- a/src/road_map.h +++ b/src/road_map.h @@ -449,6 +449,7 @@ enum Roadside { ROADSIDE_GRASS = 1, ///< Road on grass ROADSIDE_PAVED = 2, ///< Road with paved sidewalks ROADSIDE_STREET_LIGHTS = 3, ///< Road with street lights on paved sidewalks + // 4 is unused for historical reasons ROADSIDE_TREES = 5, ///< Road with trees on paved sidewalks ROADSIDE_GRASS_ROAD_WORKS = 6, ///< Road on grass with road works ROADSIDE_PAVED_ROAD_WORKS = 7, ///< Road with sidewalks and road works @@ -579,11 +580,12 @@ static inline void MakeRoadCrossing(TileIndex t, Owner road, Owner tram, Owner r SetTileType(t, MP_ROAD); SetTileOwner(t, rail); _m[t].m2 = town; - _m[t].m3 = rat; + _m[t].m3 = 0; _m[t].m4 = 0; _m[t].m5 = ROAD_TILE_CROSSING << 6 | roaddir; SB(_me[t].m6, 2, 4, 0); _me[t].m7 = rot << 6 | road; + _me[t].m8 = rat; SetRoadOwner(t, ROADTYPE_TRAM, tram); } diff --git a/src/roadveh.h b/src/roadveh.h index b1865fc22e..ca069b7acf 100644 --- a/src/roadveh.h +++ b/src/roadveh.h @@ -105,7 +105,7 @@ struct RoadVehicle FINAL : public GroundVehicle { friend struct GroundVehicle; // GroundVehicle needs to use the acceleration functions defined at RoadVehicle. void MarkDirty(); - void UpdateDeltaXY(Direction direction); + void UpdateDeltaXY(); ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_ROADVEH_INC : EXPENSES_ROADVEH_RUN; } bool IsPrimaryVehicle() const { return this->IsFrontEngine(); } void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const; diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 7adc532b6b..207a3f23b2 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -35,6 +35,7 @@ #include "core/backup_type.hpp" #include "newgrf.h" #include "zoom_func.h" +#include "framerate_type.h" #include "table/strings.h" @@ -254,7 +255,7 @@ void RoadVehUpdateCache(RoadVehicle *v, bool same_length) * @param flags type of operation. * @param e the engine to build. * @param data unused. - * @param ret[out] the vehicle that has been built. + * @param[out] ret the vehicle that has been built. * @return the cost of this operation or an error. */ CommandCost CmdBuildRoadVehicle(TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **ret) @@ -403,7 +404,7 @@ void RoadVehicle::MarkDirty() this->CargoChanged(); } -void RoadVehicle::UpdateDeltaXY(Direction direction) +void RoadVehicle::UpdateDeltaXY() { static const int8 _delta_xy_table[8][10] = { /* y_extent, x_extent, y_offs, x_offs, y_bb_offs, x_bb_offs, y_extent_shorten, x_extent_shorten, y_bb_offs_shorten, x_bb_offs_shorten */ @@ -418,9 +419,9 @@ void RoadVehicle::UpdateDeltaXY(Direction direction) }; int shorten = VEHICLE_LENGTH - this->gcache.cached_veh_length; - if (!IsDiagonalDirection(direction)) shorten >>= 1; + if (!IsDiagonalDirection(this->direction)) shorten >>= 1; - const int8 *bb = _delta_xy_table[direction]; + const int8 *bb = _delta_xy_table[this->direction]; this->x_bb_offs = bb[5] + bb[9] * shorten; this->y_bb_offs = bb[4] + bb[8] * shorten;; this->x_offs = bb[3]; @@ -1449,7 +1450,7 @@ again: /* Vehicle has arrived at a bay in a road stop */ if (IsDriveThroughStopTile(v->tile)) { - TileIndex next_tile = TILE_ADD(v->tile, TileOffsByDir(v->direction)); + TileIndex next_tile = TileAddByDir(v->tile, v->direction); /* Check if next inline bay is free and has compatible road. */ if (RoadStop::IsDriveThroughRoadStopContinuation(v->tile, next_tile) && (GetRoadTypes(next_tile) & v->compatible_roadtypes) != 0) { @@ -1587,6 +1588,8 @@ Money RoadVehicle::GetRunningCost() const bool RoadVehicle::Tick() { + PerformanceAccumulator framerate(PFE_GL_ROADVEHS); + this->tick_counter++; if (this->IsFrontEngine()) { diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index f01afb425d..077f86bf62 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -1214,6 +1214,38 @@ bool AfterLoadGame() } } + /* Railtype moved from m3 to m8 in version 200. */ + if (IsSavegameVersionBefore(200)) { + for (TileIndex t = 0; t < map_size; t++) { + switch (GetTileType(t)) { + case MP_RAILWAY: + SetRailType(t, (RailType)GB(_m[t].m3, 0, 4)); + break; + + case MP_ROAD: + if (IsLevelCrossing(t)) { + SetRailType(t, (RailType)GB(_m[t].m3, 0, 4)); + } + break; + + case MP_STATION: + if (HasStationRail(t)) { + SetRailType(t, (RailType)GB(_m[t].m3, 0, 4)); + } + break; + + case MP_TUNNELBRIDGE: + if (GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL) { + SetRailType(t, (RailType)GB(_m[t].m3, 0, 4)); + } + break; + + default: + break; + } + } + } + /* Elrails got added in rev 24 */ if (IsSavegameVersionBefore(24)) { RailType min_rail = RAILTYPE_ELECTRIC; @@ -2969,6 +3001,49 @@ bool AfterLoadGame() #endif } + if (IsSavegameVersionBefore(198)) { + /* Convert towns growth_rate and grow_counter to ticks */ + Town *t; + FOR_ALL_TOWNS(t) { + /* 0x8000 = TOWN_GROWTH_RATE_CUSTOM previously */ + if (t->growth_rate & 0x8000) SetBit(t->flags, TOWN_CUSTOM_GROWTH); + if (t->growth_rate != TOWN_GROWTH_RATE_NONE) { + t->growth_rate = TownTicksToGameTicks(t->growth_rate & ~0x8000); + } + /* Add t->index % TOWN_GROWTH_TICKS to spread growth across ticks. */ + t->grow_counter = TownTicksToGameTicks(t->grow_counter) + t->index % TOWN_GROWTH_TICKS; + } + } + + if (IsSavegameVersionBefore(202)) { + /* Make sure added industry cargo slots are cleared */ + Industry *i; + FOR_ALL_INDUSTRIES(i) { + for (size_t ci = 2; ci < lengthof(i->produced_cargo); ci++) { + i->produced_cargo[ci] = CT_INVALID; + i->produced_cargo_waiting[ci] = 0; + i->production_rate[ci] = 0; + i->last_month_production[ci] = 0; + i->last_month_transported[ci] = 0; + i->last_month_pct_transported[ci] = 0; + i->this_month_production[ci] = 0; + i->this_month_transported[ci] = 0; + } + for (size_t ci = 3; ci < lengthof(i->accepts_cargo); ci++) { + i->accepts_cargo[ci] = CT_INVALID; + i->incoming_cargo_waiting[ci] = 0; + } + /* Make sure last_cargo_accepted_at is copied to elements for every valid input cargo. + * The loading routine should put the original singular value into the first array element. */ + for (size_t ci = 0; ci < lengthof(i->accepts_cargo); ci++) { + if (i->accepts_cargo[ci] != CT_INVALID) { + i->last_cargo_accepted_at[ci] = i->last_cargo_accepted_at[0]; + } else { + i->last_cargo_accepted_at[ci] = 0; + } + } + } + } /* Station acceptance is some kind of cache */ if (IsSavegameVersionBefore(127)) { diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index d7c3130271..ce388e2141 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -259,7 +259,7 @@ static const SaveLoad _company_desc[] = { SLE_VAR(CompanyProperties, colour, SLE_UINT8), SLE_VAR(CompanyProperties, money_fraction, SLE_UINT8), - SLE_CONDVAR(CompanyProperties, avail_railtypes, SLE_VAR_I32 | SLE_FILE_I8, 0, 57), + SLE_CONDNULL(1, 0, 57), ///< avail_railtypes SLE_VAR(CompanyProperties, block_preview, SLE_UINT8), SLE_CONDNULL(2, 0, 93), ///< cargo_types @@ -350,7 +350,8 @@ static const SaveLoad _company_economy_desc[] = { SLE_CONDVAR(CompanyEconomyEntry, company_value, SLE_INT64, 2, SL_MAX_VERSION), SLE_CONDVAR(CompanyEconomyEntry, delivered_cargo[NUM_CARGO - 1], SLE_INT32, 0, 169), - SLE_CONDARR(CompanyEconomyEntry, delivered_cargo, SLE_UINT32, NUM_CARGO, 170, SL_MAX_VERSION), + SLE_CONDARR(CompanyEconomyEntry, delivered_cargo, SLE_UINT32, 32, 170, 198), + SLE_CONDARR(CompanyEconomyEntry, delivered_cargo, SLE_UINT32, NUM_CARGO, 199, SL_MAX_VERSION), SLE_VAR(CompanyEconomyEntry, performance_history, SLE_INT32), SLE_END() @@ -497,7 +498,6 @@ static void Check_PLYR() int index; while ((index = SlIterateArray()) != -1) { CompanyProperties *cprops = new CompanyProperties(); - memset(cprops, 0, sizeof(*cprops)); SaveLoad_PLYR_common(NULL, cprops); /* We do not load old custom names */ diff --git a/src/saveload/economy_sl.cpp b/src/saveload/economy_sl.cpp index dabf120fca..0effb5b2ff 100644 --- a/src/saveload/economy_sl.cpp +++ b/src/saveload/economy_sl.cpp @@ -29,7 +29,7 @@ static void Load_PRIC() /** Cargo payment rates in pre 126 savegames */ static void Load_CAPR() { - uint num_cargo = IsSavegameVersionBefore(55) ? 12 : NUM_CARGO; + uint num_cargo = IsSavegameVersionBefore(55) ? 12 : IsSavegameVersionBefore(199) ? 32 : NUM_CARGO; int vt = IsSavegameVersionBefore(65) ? SLE_FILE_I32 : SLE_FILE_I64; SlArray(NULL, num_cargo, vt | SLE_VAR_NULL); SlArray(NULL, num_cargo, SLE_FILE_U16 | SLE_VAR_NULL); diff --git a/src/saveload/industry_sl.cpp b/src/saveload/industry_sl.cpp index b28730e3c3..a9c84e62ab 100644 --- a/src/saveload/industry_sl.cpp +++ b/src/saveload/industry_sl.cpp @@ -26,18 +26,28 @@ static const SaveLoad _industry_desc[] = { SLE_VAR(Industry, location.h, SLE_FILE_U8 | SLE_VAR_U16), SLE_REF(Industry, town, REF_TOWN), SLE_CONDNULL( 2, 0, 60), ///< used to be industry's produced_cargo - SLE_CONDARR(Industry, produced_cargo, SLE_UINT8, 2, 78, SL_MAX_VERSION), - SLE_CONDARR(Industry, incoming_cargo_waiting, SLE_UINT16, 3, 70, SL_MAX_VERSION), - SLE_ARR(Industry, produced_cargo_waiting, SLE_UINT16, 2), - SLE_ARR(Industry, production_rate, SLE_UINT8, 2), + SLE_CONDARR(Industry, produced_cargo, SLE_UINT8, 2, 78, 201), + SLE_CONDARR(Industry, produced_cargo, SLE_UINT8, 16, 202, SL_MAX_VERSION), + SLE_CONDARR(Industry, incoming_cargo_waiting, SLE_UINT16, 3, 70, 201), + SLE_CONDARR(Industry, incoming_cargo_waiting, SLE_UINT16, 16, 202, SL_MAX_VERSION), + SLE_CONDARR(Industry, produced_cargo_waiting, SLE_UINT16, 2, 0, 201), + SLE_CONDARR(Industry, produced_cargo_waiting, SLE_UINT16, 16, 202, SL_MAX_VERSION), + SLE_CONDARR(Industry, production_rate, SLE_UINT8, 2, 0, 201), + SLE_CONDARR(Industry, production_rate, SLE_UINT8, 16, 202, SL_MAX_VERSION), SLE_CONDNULL( 3, 0, 60), ///< used to be industry's accepts_cargo - SLE_CONDARR(Industry, accepts_cargo, SLE_UINT8, 3, 78, SL_MAX_VERSION), + SLE_CONDARR(Industry, accepts_cargo, SLE_UINT8, 3, 78, 201), + SLE_CONDARR(Industry, accepts_cargo, SLE_UINT8, 16, 202, SL_MAX_VERSION), SLE_VAR(Industry, prod_level, SLE_UINT8), - SLE_ARR(Industry, this_month_production, SLE_UINT16, 2), - SLE_ARR(Industry, this_month_transported, SLE_UINT16, 2), - SLE_ARR(Industry, last_month_pct_transported, SLE_UINT8, 2), - SLE_ARR(Industry, last_month_production, SLE_UINT16, 2), - SLE_ARR(Industry, last_month_transported, SLE_UINT16, 2), + SLE_CONDARR(Industry, this_month_production, SLE_UINT16, 2, 0, 201), + SLE_CONDARR(Industry, this_month_production, SLE_UINT16, 16, 202, SL_MAX_VERSION), + SLE_CONDARR(Industry, this_month_transported, SLE_UINT16, 2, 0, 201), + SLE_CONDARR(Industry, this_month_transported, SLE_UINT16, 16, 202, SL_MAX_VERSION), + SLE_CONDARR(Industry, last_month_pct_transported, SLE_UINT8, 2, 0, 201), + SLE_CONDARR(Industry, last_month_pct_transported, SLE_UINT8, 16, 202, SL_MAX_VERSION), + SLE_CONDARR(Industry, last_month_production, SLE_UINT16, 2, 0, 201), + SLE_CONDARR(Industry, last_month_production, SLE_UINT16, 16, 202, SL_MAX_VERSION), + SLE_CONDARR(Industry, last_month_transported, SLE_UINT16, 2, 0, 201), + SLE_CONDARR(Industry, last_month_transported, SLE_UINT16, 16, 202, SL_MAX_VERSION), SLE_VAR(Industry, counter, SLE_UINT16), @@ -51,7 +61,8 @@ static const SaveLoad _industry_desc[] = { SLE_CONDVAR(Industry, founder, SLE_UINT8, 70, SL_MAX_VERSION), SLE_CONDVAR(Industry, construction_date, SLE_INT32, 70, SL_MAX_VERSION), SLE_CONDVAR(Industry, construction_type, SLE_UINT8, 70, SL_MAX_VERSION), - SLE_CONDVAR(Industry, last_cargo_accepted_at, SLE_INT32, 70, SL_MAX_VERSION), + SLE_CONDVAR(Industry, last_cargo_accepted_at[0], SLE_INT32, 70, 201), + SLE_CONDARR(Industry, last_cargo_accepted_at, SLE_INT32, 16, 202, SL_MAX_VERSION), SLE_CONDVAR(Industry, selected_layout, SLE_UINT8, 73, SL_MAX_VERSION), SLEG_CONDARR(_old_ind_persistent_storage.storage, SLE_UINT32, 16, 76, 160), @@ -101,7 +112,7 @@ static void Load_INDY() /* Store the old persistent storage. The GRFID will be added later. */ assert(PersistentStorage::CanAllocateItem()); i->psa = new PersistentStorage(0, 0, 0); - memcpy(i->psa->storage, _old_ind_persistent_storage.storage, sizeof(i->psa->storage)); + memcpy(i->psa->storage, _old_ind_persistent_storage.storage, sizeof(_old_ind_persistent_storage.storage)); } Industry::IncIndustryTypeCount(i->type); } diff --git a/src/saveload/linkgraph_sl.cpp b/src/saveload/linkgraph_sl.cpp index a65f4fc8a5..6044316a47 100644 --- a/src/saveload/linkgraph_sl.cpp +++ b/src/saveload/linkgraph_sl.cpp @@ -132,7 +132,7 @@ static const SaveLoad _edge_desc[] = { /** * Save/load a link graph. - * @param comp Link graph to be saved or loaded. + * @param lg Link graph to be saved or loaded. */ void SaveLoad_LinkGraph(LinkGraph &lg) { diff --git a/src/saveload/map_sl.cpp b/src/saveload/map_sl.cpp index 86a185ca42..693ddb7ce3 100644 --- a/src/saveload/map_sl.cpp +++ b/src/saveload/map_sl.cpp @@ -272,6 +272,30 @@ static void Save_MAP7() } } +static void Load_MAP8() +{ + SmallStackSafeStackAlloc buf; + TileIndex size = MapSize(); + + for (TileIndex i = 0; i != size;) { + SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT16); + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m8 = buf[j]; + } +} + +static void Save_MAP8() +{ + SmallStackSafeStackAlloc buf; + TileIndex size = MapSize(); + + SlSetLength(size * sizeof(uint16)); + for (TileIndex i = 0; i != size;) { + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m8; + SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT16); + } +} + + extern const ChunkHandler _map_chunk_handlers[] = { { 'MAPS', Save_MAPS, Load_MAPS, NULL, Check_MAPS, CH_RIFF }, { 'MAPT', Save_MAPT, Load_MAPT, NULL, NULL, CH_RIFF }, @@ -282,5 +306,6 @@ extern const ChunkHandler _map_chunk_handlers[] = { { 'M3HI', Save_MAP4, Load_MAP4, NULL, NULL, CH_RIFF }, { 'MAP5', Save_MAP5, Load_MAP5, NULL, NULL, CH_RIFF }, { 'MAPE', Save_MAP6, Load_MAP6, NULL, NULL, CH_RIFF }, - { 'MAP7', Save_MAP7, Load_MAP7, NULL, NULL, CH_RIFF | CH_LAST }, + { 'MAP7', Save_MAP7, Load_MAP7, NULL, NULL, CH_RIFF }, + { 'MAP8', Save_MAP8, Load_MAP8, NULL, NULL, CH_RIFF | CH_LAST }, }; diff --git a/src/saveload/oldloader.cpp b/src/saveload/oldloader.cpp index 13ee0e5b06..e0ad0e732a 100644 --- a/src/saveload/oldloader.cpp +++ b/src/saveload/oldloader.cpp @@ -265,7 +265,7 @@ static SavegameType DetermineOldSavegameType(FILE *f, char *title, const char *l case SGT_TTD: title = strecpy(title, "(TTD) ", last); break; default: title = strecpy(title, "(broken) ", last); break; } - title = strecpy(title, temp, last); + strecpy(title, temp, last); } return type; diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index 61a5aa5c6d..1974bb31fa 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -946,7 +946,7 @@ static const OldChunks _company_chunk[] = { OCL_SVAR( OC_UINT8, Company, block_preview ), OCL_CNULL( OC_TTD, 1 ), // Old AI - OCL_SVAR( OC_TTD | OC_UINT8, Company, avail_railtypes ), + OCL_CNULL( OC_TTD, 1 ), // avail_railtypes OCL_SVAR( OC_TILE, Company, location_of_HQ ), OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[0] ), OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[1] ), diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index cea80b59df..8cf5ee36b6 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -265,8 +265,13 @@ * 195 27572 1.6.x * 196 27778 1.7.x * 197 27978 1.8.x + * 198 + * 199 + * 200 #6805 Extend railtypes to 64, adding uint16 to map array. + * 201 #6885 Extend NewGRF persistant storages. + * 202 #6867 Increase industry cargo slots to 16 in, 16 out */ -extern const uint16 SAVEGAME_VERSION = 197; ///< Current savegame version of OpenTTD. +extern const uint16 SAVEGAME_VERSION = 202; ///< Current savegame version of OpenTTD. SavegameType _savegame_type; ///< type of savegame we are loading FileToSaveLoad _file_to_saveload; ///< File to save or load in the openttd loop. @@ -2782,7 +2787,7 @@ SaveOrLoadResult LoadWithFilter(LoadFilter *reader) * Main Save or Load function where the high-level saveload functions are * handled. It opens the savegame, selects format and checks versions * @param filename The name of the savegame being created/loaded - * @param mode Save or load mode. Load can also be a TTD(Patch) game. Use #SL_LOAD, #SL_OLD_LOAD, #SL_LOAD_CHECK, or #SL_SAVE. + * @param fop Save or load mode. Load can also be a TTD(Patch) game. * @param sb The sub directory to save the savegame in * @param threaded True when threaded saving is allowed * @return Return the result of the action. #SL_OK, #SL_ERROR, or #SL_REINIT ("unload" the game) diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index d492558c5a..cca56ce07e 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -436,7 +436,7 @@ typedef SaveLoad SaveLoadGlobVarList; * @param variable Name of the global variable. * @param type Storage of the data in memory and in the savegame. */ -#define SLEG_STR(variable, type) SLEG_CONDSTR(variable, type, lengthof(variable), 0, SL_MAX_VERSION) +#define SLEG_STR(variable, type) SLEG_CONDSTR(variable, type, sizeof(variable), 0, SL_MAX_VERSION) /** * Storage of a global list in every savegame version. @@ -488,7 +488,7 @@ static inline bool SlIsObjectCurrentlyValid(uint16 version_from, uint16 version_ * Get the NumberType of a setting. This describes the integer type * as it is represented in memory * @param type VarType holding information about the variable-type - * @return return the SLE_VAR_* part of a variable-type description + * @return the SLE_VAR_* part of a variable-type description */ static inline VarType GetVarMemType(VarType type) { @@ -496,10 +496,10 @@ static inline VarType GetVarMemType(VarType type) } /** - * Get the #FileType of a setting. This describes the integer type + * Get the FileType of a setting. This describes the integer type * as it is represented in a savegame/file * @param type VarType holding information about the file-type - * @param return the SLE_FILE_* part of a variable-type description + * @return the SLE_FILE_* part of a variable-type description */ static inline VarType GetVarFileType(VarType type) { diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index 391ba30a8e..670d6fcf06 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -329,6 +329,7 @@ static void Load_STNS() _cargo_days = 0; _cargo_feeder_share = 0; + uint num_cargo = IsSavegameVersionBefore(55) ? 12 : IsSavegameVersionBefore(199) ? 32 : NUM_CARGO; int index; while ((index = SlIterateArray()) != -1) { Station *st = new (index) Station(); @@ -337,7 +338,6 @@ static void Load_STNS() _waiting_acceptance = 0; - uint num_cargo = IsSavegameVersionBefore(55) ? 12 : NUM_CARGO; for (CargoID i = 0; i < num_cargo; i++) { GoodsEntry *ge = &st->goods[i]; SlObject(ge, GetGoodsDesc()); @@ -377,10 +377,11 @@ static void Ptrs_STNS() /* Don't run when savegame version is higher than or equal to 123. */ if (!IsSavegameVersionBefore(123)) return; + uint num_cargo = IsSavegameVersionBefore(199) ? 32 : NUM_CARGO; Station *st; FOR_ALL_STATIONS(st) { if (!IsSavegameVersionBefore(68)) { - for (CargoID i = 0; i < NUM_CARGO; i++) { + for (CargoID i = 0; i < num_cargo; i++) { GoodsEntry *ge = &st->goods[i]; SwapPackets(ge); SlObject(ge, GetGoodsDesc()); @@ -440,7 +441,8 @@ static const SaveLoad _station_desc[] = { SLE_VAR(Station, last_vehicle_type, SLE_UINT8), SLE_VAR(Station, had_vehicle_of_type, SLE_UINT8), SLE_LST(Station, loading_vehicles, REF_VEHICLE), - SLE_CONDVAR(Station, always_accepted, SLE_UINT32, 127, SL_MAX_VERSION), + SLE_CONDVAR(Station, always_accepted, SLE_FILE_U32 | SLE_VAR_U64, 127, 198), + SLE_CONDVAR(Station, always_accepted, SLE_UINT64, 199, SL_MAX_VERSION), SLE_END() }; @@ -520,6 +522,7 @@ static void Load_STNN() { _num_flows = 0; + uint num_cargo = IsSavegameVersionBefore(199) ? 32 : NUM_CARGO; int index; while ((index = SlIterateArray()) != -1) { bool waypoint = (SlReadByte() & FACIL_WAYPOINT) != 0; @@ -535,10 +538,10 @@ static void Load_STNN() /* Store the old persistent storage. The GRFID will be added later. */ assert(PersistentStorage::CanAllocateItem()); st->airport.psa = new PersistentStorage(0, 0, 0); - memcpy(st->airport.psa->storage, _old_st_persistent_storage.storage, sizeof(st->airport.psa->storage)); + memcpy(st->airport.psa->storage, _old_st_persistent_storage.storage, sizeof(_old_st_persistent_storage.storage)); } - for (CargoID i = 0; i < NUM_CARGO; i++) { + for (CargoID i = 0; i < num_cargo; i++) { SlObject(&st->goods[i], GetGoodsDesc()); FlowSaveLoad flow; FlowStat *fs = NULL; @@ -580,9 +583,10 @@ static void Ptrs_STNN() /* Don't run when savegame version lower than 123. */ if (IsSavegameVersionBefore(123)) return; + uint num_cargo = IsSavegameVersionBefore(199) ? 32 : NUM_CARGO; Station *st; FOR_ALL_STATIONS(st) { - for (CargoID i = 0; i < NUM_CARGO; i++) { + for (CargoID i = 0; i < num_cargo; i++) { GoodsEntry *ge = &st->goods[i]; if (IsSavegameVersionBefore(183)) { SwapPackets(ge); diff --git a/src/saveload/storage_sl.cpp b/src/saveload/storage_sl.cpp index 110df63a7c..04980c7c37 100644 --- a/src/saveload/storage_sl.cpp +++ b/src/saveload/storage_sl.cpp @@ -18,7 +18,8 @@ /** Description of the data to save and load in #PersistentStorage. */ static const SaveLoad _storage_desc[] = { SLE_CONDVAR(PersistentStorage, grfid, SLE_UINT32, 6, SL_MAX_VERSION), - SLE_CONDARR(PersistentStorage, storage, SLE_UINT32, 16, 161, SL_MAX_VERSION), + SLE_CONDARR(PersistentStorage, storage, SLE_UINT32, 16, 161, 200), + SLE_CONDARR(PersistentStorage, storage, SLE_UINT32, 256, 201, SL_MAX_VERSION), SLE_END() }; diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index 3af5171b87..13438d85bf 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -192,7 +192,8 @@ static const SaveLoad _town_desc[] = { SLE_CONDLST(Town, psa_list, REF_STORAGE, 161, SL_MAX_VERSION), - SLE_CONDVAR(Town, cargo_produced, SLE_UINT32, 166, SL_MAX_VERSION), + SLE_CONDVAR(Town, cargo_produced, SLE_FILE_U32 | SLE_VAR_U64, 166, 198), + SLE_CONDVAR(Town, cargo_produced, SLE_UINT64, 199, SL_MAX_VERSION), /* reserve extra space in savegame here. (currently 30 bytes) */ SLE_CONDNULL(30, 2, SL_MAX_VERSION), @@ -274,12 +275,13 @@ static void Save_TOWN() static void Load_TOWN() { int index; + uint num_cargo = IsSavegameVersionBefore(199) ? 32 : NUM_CARGO; while ((index = SlIterateArray()) != -1) { Town *t = new (index) Town(); SlObject(t, _town_desc); - for (CargoID i = 0; i < NUM_CARGO; i++) { + for (CargoID i = 0; i < num_cargo; i++) { SlObject(&t->supplied[i], _town_supplied_desc); } for (int i = TE_BEGIN; i < TE_END; i++) { @@ -295,7 +297,7 @@ static void Load_TOWN() SlObject(&t->cargo_accepted, GetTileMatrixDesc()); if (t->cargo_accepted.area.w != 0) { uint arr_len = t->cargo_accepted.area.w / AcceptanceMatrix::GRID * t->cargo_accepted.area.h / AcceptanceMatrix::GRID; - t->cargo_accepted.data = MallocT(arr_len); + t->cargo_accepted.data = MallocT(arr_len); SlArray(t->cargo_accepted.data, arr_len, SLE_UINT32); /* Rebuild total cargo acceptance. */ diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 2234659aba..bb3db3fe3e 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -433,8 +433,8 @@ void AfterLoadVehicles(bool part_of_load) RoadVehicle *rv = RoadVehicle::From(v); rv->roadtype = HasBit(EngInfo(v->First()->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD; rv->compatible_roadtypes = RoadTypeToRoadTypes(rv->roadtype); + FALLTHROUGH; } - FALLTHROUGH; case VEH_TRAIN: case VEH_SHIP: @@ -461,7 +461,7 @@ void AfterLoadVehicles(bool part_of_load) default: break; } - v->UpdateDeltaXY(v->direction); + v->UpdateDeltaXY(); v->coord.left = INVALID_COORD; v->UpdatePosition(); v->UpdateViewport(false); diff --git a/src/screenshot.cpp b/src/screenshot.cpp index a24cc6b211..700a065669 100644 --- a/src/screenshot.cpp +++ b/src/screenshot.cpp @@ -71,23 +71,16 @@ struct ScreenshotFormat { /************************************************* **** SCREENSHOT CODE FOR WINDOWS BITMAP (.BMP) *************************************************/ -#if defined(_MSC_VER) || defined(__WATCOMC__) -#pragma pack(push, 1) -#endif /** BMP File Header (stored in little endian) */ -struct BitmapFileHeader { +PACK(struct BitmapFileHeader { uint16 type; uint32 size; uint32 reserved; uint32 off_bits; -} GCC_PACK; +}); assert_compile(sizeof(BitmapFileHeader) == 14); -#if defined(_MSC_VER) || defined(__WATCOMC__) -#pragma pack(pop) -#endif - /** BMP Info Header (stored in little endian) */ struct BitmapInfoHeader { uint32 size; @@ -715,7 +708,7 @@ static bool MakeSmallScreenshot(bool crashlog) /** * Configure a ViewPort for rendering (a part of) the map into a screenshot. * @param t Screenshot type - * @param [out] vp Result viewport + * @param[out] vp Result viewport */ void SetupScreenshotViewport(ScreenshotType t, ViewPort *vp) { @@ -771,7 +764,7 @@ static bool MakeLargeWorldScreenshot(ScreenshotType t) /** * Callback for generating a heightmap. Supports 8bpp grayscale only. * @param userdata Pointer to user data. - * @param buf Destination buffer. + * @param buffer Destination buffer. * @param y Line number of the first line to write. * @param pitch Number of pixels to write (1 byte for 8bpp, 4 bytes for 32bpp). @see Colour * @param n Number of lines to write. diff --git a/src/script/api/ai/ai_airport.hpp.sq b/src/script/api/ai/ai_airport.hpp.sq index 63ee130981..89e7ba1258 100644 --- a/src/script/api/ai/ai_airport.hpp.sq +++ b/src/script/api/ai/ai_airport.hpp.sq @@ -52,6 +52,7 @@ void SQAIAirport_Register(Squirrel *engine) SQAIAirport.DefSQStaticMethod(engine, &ScriptAirport::GetNoiseLevelIncrease, "GetNoiseLevelIncrease", 3, ".ii"); SQAIAirport.DefSQStaticMethod(engine, &ScriptAirport::GetNearestTown, "GetNearestTown", 3, ".ii"); SQAIAirport.DefSQStaticMethod(engine, &ScriptAirport::GetMaintenanceCostFactor, "GetMaintenanceCostFactor", 2, ".i"); + SQAIAirport.DefSQStaticMethod(engine, &ScriptAirport::GetMonthlyMaintenanceCost, "GetMonthlyMaintenanceCost", 2, ".i"); SQAIAirport.PostRegister(engine); } diff --git a/src/script/api/ai/ai_order.hpp.sq b/src/script/api/ai/ai_order.hpp.sq index 71cc8cfe90..ab25e4810d 100644 --- a/src/script/api/ai/ai_order.hpp.sq +++ b/src/script/api/ai/ai_order.hpp.sq @@ -44,6 +44,7 @@ void SQAIOrder_Register(Squirrel *engine) SQAIOrder.DefSQConst(engine, ScriptOrder::OF_INVALID, "OF_INVALID"); SQAIOrder.DefSQConst(engine, ScriptOrder::OC_LOAD_PERCENTAGE, "OC_LOAD_PERCENTAGE"); SQAIOrder.DefSQConst(engine, ScriptOrder::OC_RELIABILITY, "OC_RELIABILITY"); + SQAIOrder.DefSQConst(engine, ScriptOrder::OC_MAX_RELIABILITY, "OC_MAX_RELIABILITY"); SQAIOrder.DefSQConst(engine, ScriptOrder::OC_MAX_SPEED, "OC_MAX_SPEED"); SQAIOrder.DefSQConst(engine, ScriptOrder::OC_AGE, "OC_AGE"); SQAIOrder.DefSQConst(engine, ScriptOrder::OC_REQUIRES_SERVICE, "OC_REQUIRES_SERVICE"); diff --git a/src/script/api/ai/ai_station.hpp.sq b/src/script/api/ai/ai_station.hpp.sq index af7012d354..1850c1e740 100644 --- a/src/script/api/ai/ai_station.hpp.sq +++ b/src/script/api/ai/ai_station.hpp.sq @@ -33,7 +33,6 @@ void SQAIStation_Register(Squirrel *engine) SQAIStation.DefSQConst(engine, ScriptStation::STATION_ANY, "STATION_ANY"); ScriptError::RegisterErrorMap(STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT, ScriptStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION); - ScriptError::RegisterErrorMap(STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION, ScriptStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION); ScriptError::RegisterErrorMap(STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK, ScriptStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION); ScriptError::RegisterErrorMap(STR_ERROR_TOO_MANY_STATIONS_LOADING, ScriptStation::ERR_STATION_TOO_MANY_STATIONS); ScriptError::RegisterErrorMap(STR_ERROR_TOO_MANY_TRUCK_STOPS, ScriptStation::ERR_STATION_TOO_MANY_STATIONS); diff --git a/src/script/api/ai_changelog.hpp b/src/script/api/ai_changelog.hpp index 25e8b3e378..03e9831a11 100644 --- a/src/script/api/ai_changelog.hpp +++ b/src/script/api/ai_changelog.hpp @@ -18,10 +18,12 @@ * \b 1.9.0 * * 1.9.0 is not yet released. The following changes are not set in stone yet. + * API additions: + * \li AIAirport::GetMonthlyMaintenanceCost * * \b 1.8.0 * - * 1.8.0 is not yet released. The following changes are not set in stone yet. + * No changes * * \b 1.7.0 - 1.7.2 * diff --git a/src/script/api/game/game_airport.hpp.sq b/src/script/api/game/game_airport.hpp.sq index cfa99ba377..d8f3a2a64c 100644 --- a/src/script/api/game/game_airport.hpp.sq +++ b/src/script/api/game/game_airport.hpp.sq @@ -52,6 +52,7 @@ void SQGSAirport_Register(Squirrel *engine) SQGSAirport.DefSQStaticMethod(engine, &ScriptAirport::GetNoiseLevelIncrease, "GetNoiseLevelIncrease", 3, ".ii"); SQGSAirport.DefSQStaticMethod(engine, &ScriptAirport::GetNearestTown, "GetNearestTown", 3, ".ii"); SQGSAirport.DefSQStaticMethod(engine, &ScriptAirport::GetMaintenanceCostFactor, "GetMaintenanceCostFactor", 2, ".i"); + SQGSAirport.DefSQStaticMethod(engine, &ScriptAirport::GetMonthlyMaintenanceCost, "GetMonthlyMaintenanceCost", 2, ".i"); SQGSAirport.PostRegister(engine); } diff --git a/src/script/api/game/game_goal.hpp.sq b/src/script/api/game/game_goal.hpp.sq index 7d8a3bf5e7..4cf15b3fc4 100644 --- a/src/script/api/game/game_goal.hpp.sq +++ b/src/script/api/game/game_goal.hpp.sq @@ -51,15 +51,16 @@ void SQGSGoal_Register(Squirrel *engine) SQGSGoal.DefSQConst(engine, ScriptGoal::BUTTON_SURRENDER, "BUTTON_SURRENDER"); SQGSGoal.DefSQConst(engine, ScriptGoal::BUTTON_CLOSE, "BUTTON_CLOSE"); - SQGSGoal.DefSQStaticMethod(engine, &ScriptGoal::IsValidGoal, "IsValidGoal", 2, ".i"); - SQGSGoal.DefSQStaticMethod(engine, &ScriptGoal::New, "New", 5, ".i.ii"); - SQGSGoal.DefSQStaticMethod(engine, &ScriptGoal::Remove, "Remove", 2, ".i"); - SQGSGoal.DefSQStaticMethod(engine, &ScriptGoal::SetText, "SetText", 3, ".i."); - SQGSGoal.DefSQStaticMethod(engine, &ScriptGoal::SetProgress, "SetProgress", 3, ".i."); - SQGSGoal.DefSQStaticMethod(engine, &ScriptGoal::SetCompleted, "SetCompleted", 3, ".ib"); - SQGSGoal.DefSQStaticMethod(engine, &ScriptGoal::IsCompleted, "IsCompleted", 2, ".i"); - SQGSGoal.DefSQStaticMethod(engine, &ScriptGoal::Question, "Question", 6, ".ii.ii"); - SQGSGoal.DefSQStaticMethod(engine, &ScriptGoal::CloseQuestion, "CloseQuestion", 2, ".i"); + SQGSGoal.DefSQStaticMethod(engine, &ScriptGoal::IsValidGoal, "IsValidGoal", 2, ".i"); + SQGSGoal.DefSQStaticMethod(engine, &ScriptGoal::New, "New", 5, ".i.ii"); + SQGSGoal.DefSQStaticMethod(engine, &ScriptGoal::Remove, "Remove", 2, ".i"); + SQGSGoal.DefSQStaticMethod(engine, &ScriptGoal::SetText, "SetText", 3, ".i."); + SQGSGoal.DefSQStaticMethod(engine, &ScriptGoal::SetProgress, "SetProgress", 3, ".i."); + SQGSGoal.DefSQStaticMethod(engine, &ScriptGoal::SetCompleted, "SetCompleted", 3, ".ib"); + SQGSGoal.DefSQStaticMethod(engine, &ScriptGoal::IsCompleted, "IsCompleted", 2, ".i"); + SQGSGoal.DefSQStaticMethod(engine, &ScriptGoal::Question, "Question", 6, ".ii.ii"); + SQGSGoal.DefSQStaticMethod(engine, &ScriptGoal::QuestionClient, "QuestionClient", 6, ".ii.ii"); + SQGSGoal.DefSQStaticMethod(engine, &ScriptGoal::CloseQuestion, "CloseQuestion", 2, ".i"); SQGSGoal.PostRegister(engine); } diff --git a/src/script/api/game/game_order.hpp.sq b/src/script/api/game/game_order.hpp.sq index f95dce925a..e2126c603d 100644 --- a/src/script/api/game/game_order.hpp.sq +++ b/src/script/api/game/game_order.hpp.sq @@ -44,6 +44,7 @@ void SQGSOrder_Register(Squirrel *engine) SQGSOrder.DefSQConst(engine, ScriptOrder::OF_INVALID, "OF_INVALID"); SQGSOrder.DefSQConst(engine, ScriptOrder::OC_LOAD_PERCENTAGE, "OC_LOAD_PERCENTAGE"); SQGSOrder.DefSQConst(engine, ScriptOrder::OC_RELIABILITY, "OC_RELIABILITY"); + SQGSOrder.DefSQConst(engine, ScriptOrder::OC_MAX_RELIABILITY, "OC_MAX_RELIABILITY"); SQGSOrder.DefSQConst(engine, ScriptOrder::OC_MAX_SPEED, "OC_MAX_SPEED"); SQGSOrder.DefSQConst(engine, ScriptOrder::OC_AGE, "OC_AGE"); SQGSOrder.DefSQConst(engine, ScriptOrder::OC_REQUIRES_SERVICE, "OC_REQUIRES_SERVICE"); diff --git a/src/script/api/game/game_station.hpp.sq b/src/script/api/game/game_station.hpp.sq index e3a7425caa..4c2f63b384 100644 --- a/src/script/api/game/game_station.hpp.sq +++ b/src/script/api/game/game_station.hpp.sq @@ -33,7 +33,6 @@ void SQGSStation_Register(Squirrel *engine) SQGSStation.DefSQConst(engine, ScriptStation::STATION_ANY, "STATION_ANY"); ScriptError::RegisterErrorMap(STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT, ScriptStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION); - ScriptError::RegisterErrorMap(STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION, ScriptStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION); ScriptError::RegisterErrorMap(STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK, ScriptStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION); ScriptError::RegisterErrorMap(STR_ERROR_TOO_MANY_STATIONS_LOADING, ScriptStation::ERR_STATION_TOO_MANY_STATIONS); ScriptError::RegisterErrorMap(STR_ERROR_TOO_MANY_TRUCK_STOPS, ScriptStation::ERR_STATION_TOO_MANY_STATIONS); diff --git a/src/script/api/game/game_window.hpp.sq b/src/script/api/game/game_window.hpp.sq index f52de827d9..9fc9526cc2 100644 --- a/src/script/api/game/game_window.hpp.sq +++ b/src/script/api/game/game_window.hpp.sq @@ -138,6 +138,8 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WC_SPRITE_ALIGNER, "WC_SPRITE_ALIGNER"); SQGSWindow.DefSQConst(engine, ScriptWindow::WC_LINKGRAPH_LEGEND, "WC_LINKGRAPH_LEGEND"); SQGSWindow.DefSQConst(engine, ScriptWindow::WC_SAVE_PRESET, "WC_SAVE_PRESET"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WC_FRAMERATE_DISPLAY, "WC_FRAMERATE_DISPLAY"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WC_FRAMETIME_GRAPH, "WC_FRAMETIME_GRAPH"); SQGSWindow.DefSQConst(engine, ScriptWindow::WC_INVALID, "WC_INVALID"); SQGSWindow.DefSQConst(engine, ScriptWindow::TC_BLUE, "TC_BLUE"); SQGSWindow.DefSQConst(engine, ScriptWindow::TC_SILVER, "TC_SILVER"); @@ -436,6 +438,7 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SL_CAPTION, "WID_SL_CAPTION"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SL_SORT_BYNAME, "WID_SL_SORT_BYNAME"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SL_SORT_BYDATE, "WID_SL_SORT_BYDATE"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SL_FILTER, "WID_SL_FILTER"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SL_BACKGROUND, "WID_SL_BACKGROUND"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SL_FILE_BACKGROUND, "WID_SL_FILE_BACKGROUND"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SL_HOME_BUTTON, "WID_SL_HOME_BUTTON"); @@ -450,6 +453,16 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SL_NEWGRF_INFO, "WID_SL_NEWGRF_INFO"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SL_LOAD_BUTTON, "WID_SL_LOAD_BUTTON"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SL_MISSING_NEWGRFS, "WID_SL_MISSING_NEWGRFS"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_FRW_CAPTION, "WID_FRW_CAPTION"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_FRW_RATE_GAMELOOP, "WID_FRW_RATE_GAMELOOP"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_FRW_RATE_DRAWING, "WID_FRW_RATE_DRAWING"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_FRW_RATE_FACTOR, "WID_FRW_RATE_FACTOR"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_FRW_INFO_DATA_POINTS, "WID_FRW_INFO_DATA_POINTS"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_FRW_TIMES_NAMES, "WID_FRW_TIMES_NAMES"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_FRW_TIMES_CURRENT, "WID_FRW_TIMES_CURRENT"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_FRW_TIMES_AVERAGE, "WID_FRW_TIMES_AVERAGE"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_FGW_CAPTION, "WID_FGW_CAPTION"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_FGW_GRAPH, "WID_FGW_GRAPH"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_GL_TEMPERATE, "WID_GL_TEMPERATE"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_GL_ARCTIC, "WID_GL_ARCTIC"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_GL_TROPICAL, "WID_GL_TROPICAL"); @@ -551,6 +564,7 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_GL_DELETE_GROUP, "WID_GL_DELETE_GROUP"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_GL_RENAME_GROUP, "WID_GL_RENAME_GROUP"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_GL_REPLACE_PROTECTION, "WID_GL_REPLACE_PROTECTION"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_GL_INFO, "WID_GL_INFO"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_H_BACKGROUND, "WID_H_BACKGROUND"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_DPI_MATRIX_WIDGET, "WID_DPI_MATRIX_WIDGET"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_DPI_SCROLLBAR, "WID_DPI_SCROLLBAR"); @@ -626,9 +640,11 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TF_BACKGROUND, "WID_TF_BACKGROUND"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TF_VSCROLLBAR, "WID_TF_VSCROLLBAR"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TF_HSCROLLBAR, "WID_TF_HSCROLLBAR"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_CAPTION, "WID_MTS_CAPTION"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_LIST_LEFT, "WID_MTS_LIST_LEFT"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_PLAYLIST, "WID_MTS_PLAYLIST"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_LIST_RIGHT, "WID_MTS_LIST_RIGHT"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_MUSICSET, "WID_MTS_MUSICSET"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_ALL, "WID_MTS_ALL"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_OLD, "WID_MTS_OLD"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MTS_NEW, "WID_MTS_NEW"); @@ -1180,7 +1196,7 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_TRAINS, "WID_TN_TRAINS"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_ROADVEHS, "WID_TN_ROADVEHS"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_SHIPS, "WID_TN_SHIPS"); - SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_AIRCRAFTS, "WID_TN_AIRCRAFTS"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_AIRCRAFT, "WID_TN_AIRCRAFT"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_ZOOM_IN, "WID_TN_ZOOM_IN"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_ZOOM_OUT, "WID_TN_ZOOM_OUT"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_BUILDING_TOOLS_START, "WID_TN_BUILDING_TOOLS_START"); diff --git a/src/script/api/game_changelog.hpp b/src/script/api/game_changelog.hpp index 5f278e4f08..7aad75b442 100644 --- a/src/script/api/game_changelog.hpp +++ b/src/script/api/game_changelog.hpp @@ -19,12 +19,14 @@ * * 1.9.0 is not yet released. The following changes are not set in stone yet. * API additions: + * \li GSAirport::GetMonthlyMaintenanceCost * \li GSClient * \li GSClientList * \li GSClientList_Company * \li GSViewport::ScrollEveryoneTo * \li GSViewport::ScrollCompanyClientsTo * \li GSViewport::ScrollClientTo + * \li GSGoal::QuestionClient * * \b 1.8.0 * diff --git a/src/script/api/script_airport.cpp b/src/script/api/script_airport.cpp index edb912609e..8e19d257df 100644 --- a/src/script/api/script_airport.cpp +++ b/src/script/api/script_airport.cpp @@ -163,3 +163,10 @@ return AirportSpec::Get(type)->maintenance_cost; } + +/* static */ Money ScriptAirport::GetMonthlyMaintenanceCost(AirportType type) +{ + if (!IsAirportInformationAvailable(type)) return -1; + + return (int64)GetMaintenanceCostFactor(type) * _price[PR_INFRASTRUCTURE_AIRPORT] >> 3; +} diff --git a/src/script/api/script_airport.hpp b/src/script/api/script_airport.hpp index e4c0a217d2..6073a2bdd6 100644 --- a/src/script/api/script_airport.hpp +++ b/src/script/api/script_airport.hpp @@ -201,6 +201,14 @@ public: * @return Maintenance cost factor of the airport type. */ static uint16 GetMaintenanceCostFactor(AirportType type); + + /** + * Get the monthly maintenance cost of an airport type. + * @param type The airport type to get the monthly maintenance cost of. + * @pre IsAirportInformationAvailable(type) + * @return Monthly maintenance cost of the airport type. + */ + static Money GetMonthlyMaintenanceCost(AirportType type); }; #endif /* SCRIPT_AIRPORT_HPP */ diff --git a/src/script/api/script_company.hpp b/src/script/api/script_company.hpp index 4bfe0d02e6..dc917500b7 100644 --- a/src/script/api/script_company.hpp +++ b/src/script/api/script_company.hpp @@ -55,12 +55,12 @@ public: EXPENSES_NEW_VEHICLES = ::EXPENSES_NEW_VEHICLES, ///< New vehicles. EXPENSES_TRAIN_RUN = ::EXPENSES_TRAIN_RUN, ///< Running costs trains. EXPENSES_ROADVEH_RUN = ::EXPENSES_ROADVEH_RUN, ///< Running costs road vehicles. - EXPENSES_AIRCRAFT_RUN = ::EXPENSES_AIRCRAFT_RUN, ///< Running costs aircrafts. + EXPENSES_AIRCRAFT_RUN = ::EXPENSES_AIRCRAFT_RUN, ///< Running costs aircraft. EXPENSES_SHIP_RUN = ::EXPENSES_SHIP_RUN, ///< Running costs ships. EXPENSES_PROPERTY = ::EXPENSES_PROPERTY, ///< Property costs. EXPENSES_TRAIN_INC = ::EXPENSES_TRAIN_INC, ///< Income from trains. EXPENSES_ROADVEH_INC = ::EXPENSES_ROADVEH_INC, ///< Income from road vehicles. - EXPENSES_AIRCRAFT_INC = ::EXPENSES_AIRCRAFT_INC, ///< Income from aircrafts. + EXPENSES_AIRCRAFT_INC = ::EXPENSES_AIRCRAFT_INC, ///< Income from aircraft. EXPENSES_SHIP_INC = ::EXPENSES_SHIP_INC, ///< Income from ships. EXPENSES_LOAN_INT = ::EXPENSES_LOAN_INT, ///< Interest payments over the loan. EXPENSES_OTHER = ::EXPENSES_OTHER, ///< Other expenses. diff --git a/src/script/api/script_companymode.cpp b/src/script/api/script_companymode.cpp index 1931a5db78..a5d3963a2d 100644 --- a/src/script/api/script_companymode.cpp +++ b/src/script/api/script_companymode.cpp @@ -10,6 +10,7 @@ /** @file script_companymode.cpp Implementation of ScriptCompanyMode. */ #include "../../stdafx.h" +#include "../../company_base.h" #include "script_companymode.hpp" #include "../../safeguards.h" @@ -17,6 +18,7 @@ ScriptCompanyMode::ScriptCompanyMode(int company) { if (company < OWNER_BEGIN || company >= MAX_COMPANIES) company = INVALID_COMPANY; + if (!::Company::IsValidID(company)) company = INVALID_COMPANY; this->last_company = ScriptObject::GetCompany(); ScriptObject::SetCompany((CompanyID)company); diff --git a/src/script/api/script_event_types.hpp b/src/script/api/script_event_types.hpp index 9430168977..f13e588eed 100644 --- a/src/script/api/script_event_types.hpp +++ b/src/script/api/script_event_types.hpp @@ -363,7 +363,7 @@ private: class ScriptEventCompanyAskMerger : public ScriptEvent { public: /** - * @param owner The company that can be bough. + * @param owner The company that can be bought. * @param value The value/costs of buying the company. */ ScriptEventCompanyAskMerger(Owner owner, int32 value) : diff --git a/src/script/api/script_goal.cpp b/src/script/api/script_goal.cpp index 5153e0ef0e..c183b75834 100644 --- a/src/script/api/script_goal.cpp +++ b/src/script/api/script_goal.cpp @@ -10,6 +10,7 @@ /** @file script_goal.cpp Implementation of ScriptGoal. */ #include "../../stdafx.h" +#include "script_game.hpp" #include "script_goal.hpp" #include "script_error.hpp" #include "script_industry.hpp" @@ -19,6 +20,7 @@ #include "../script_instance.hpp" #include "../../goal_base.h" #include "../../string_func.h" +#include "../../network/network_base.h" #include "../../safeguards.h" @@ -107,7 +109,7 @@ return g != NULL && g->completed; } -/* static */ bool ScriptGoal::Question(uint16 uniqueid, ScriptCompany::CompanyID company, Text *question, QuestionType type, int buttons) +/* static */ bool ScriptGoal::DoQuestion(uint16 uniqueid, uint8 target, bool is_client, Text *question, QuestionType type, int buttons) { CCountedPtr counter(question); @@ -115,15 +117,32 @@ EnforcePrecondition(false, question != NULL); const char *text = question->GetEncodedText(); EnforcePreconditionEncodedText(false, text); - EnforcePrecondition(false, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID); EnforcePrecondition(false, CountBits(buttons) >= 1 && CountBits(buttons) <= 3); EnforcePrecondition(false, buttons < (1 << ::GOAL_QUESTION_BUTTON_COUNT)); EnforcePrecondition(false, (int)type < ::GOAL_QUESTION_TYPE_COUNT); + return ScriptObject::DoCommand(0, uniqueid | (target << 16) | (type << 24) | (is_client ? (1 << 31) : 0), buttons, CMD_GOAL_QUESTION, text); +} + +/* static */ bool ScriptGoal::Question(uint16 uniqueid, ScriptCompany::CompanyID company, Text *question, QuestionType type, int buttons) +{ + EnforcePrecondition(false, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID); uint8 c = company; if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY; - return ScriptObject::DoCommand(0, uniqueid | (c << 16) | (type << 24), buttons, CMD_GOAL_QUESTION, text); + return DoQuestion(uniqueid, c, false, question, type, buttons); +} + +/* static */ bool ScriptGoal::QuestionClient(uint16 uniqueid, ScriptClient::ClientID client, Text *question, QuestionType type, int buttons) +{ + EnforcePrecondition(false, ScriptGame::IsMultiplayer()); + EnforcePrecondition(false, ScriptClient::ResolveClientID(client) != ScriptClient::CLIENT_INVALID); +#ifdef ENABLE_NETWORK + ClientIndex c = NetworkClientInfo::GetByClientID((::ClientID)client)->index; + return DoQuestion(uniqueid, c, true, question, type, buttons); +#else + return false; +#endif } /* static */ bool ScriptGoal::CloseQuestion(uint16 uniqueid) diff --git a/src/script/api/script_goal.hpp b/src/script/api/script_goal.hpp index a9c7b239d5..f5dfba095f 100644 --- a/src/script/api/script_goal.hpp +++ b/src/script/api/script_goal.hpp @@ -12,6 +12,7 @@ #ifndef SCRIPT_GOAL_HPP #define SCRIPT_GOAL_HPP +#include "script_client.hpp" #include "script_company.hpp" #include "../../goal_type.h" @@ -160,7 +161,7 @@ public: static bool IsCompleted(GoalID goal_id); /** - * Ask a question. + * Ask a question of all players in a company. * @param uniqueid Your unique id to distinguish results of multiple questions in the returning event. * @param company The company to ask the question, or ScriptCompany::COMPANY_INVALID for all. * @param question The question to ask (can be either a raw string, or a ScriptText object). @@ -176,6 +177,24 @@ public: */ static bool Question(uint16 uniqueid, ScriptCompany::CompanyID company, Text *question, QuestionType type, int buttons); + /** + * Ask client a question. + * @param uniqueid Your unique id to distinguish results of multiple questions in the returning event. + * @param client The client to ask the question. + * @param question The question to ask (can be either a raw string, or a ScriptText object). + * @param type The type of question that is being asked. + * @param buttons Any combinations (at least 1, up to 3) of buttons defined in QuestionButton. Like BUTTON_YES + BUTTON_NO. + * @return True if the action succeeded. + * @pre No ScriptCompanyMode may be in scope. + * @pre ScriptGame::IsMultiplayer() + * @pre question != NULL && len(question) != 0. + * @pre ResolveClientID(client) != CLIENT_INVALID. + * @pre CountBits(buttons) >= 1 && CountBits(buttons) <= 3. + * @note Replies to the question are given by you via the event ScriptEvent_GoalQuestionAnswer. + * @note There is no guarantee you ever get a reply on your question. + */ + static bool QuestionClient(uint16 uniqueid, ScriptClient::ClientID client, Text *question, QuestionType type, int buttons); + /** * Close the question on all clients. * @param uniqueid The uniqueid of the question you want to close. @@ -187,6 +206,12 @@ public: * companies, but you are only interested in the reply of the first. */ static bool CloseQuestion(uint16 uniqueid); + +protected: + /** + * Does common checks and asks the question. + */ + static bool DoQuestion(uint16 uniqueid, uint8 target, bool is_client, Text *question, QuestionType type, int buttons); }; #endif /* SCRIPT_GOAL_HPP */ diff --git a/src/script/api/script_order.cpp b/src/script/api/script_order.cpp index 676262dc77..a1390bf8f5 100644 --- a/src/script/api/script_order.cpp +++ b/src/script/api/script_order.cpp @@ -214,6 +214,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr switch (condition) { case OC_LOAD_PERCENTAGE: case OC_RELIABILITY: + case OC_MAX_RELIABILITY: case OC_MAX_SPEED: case OC_AGE: case OC_REMAINING_LIFETIME: diff --git a/src/script/api/script_order.hpp b/src/script/api/script_order.hpp index 63089a2bd4..a4f945511e 100644 --- a/src/script/api/script_order.hpp +++ b/src/script/api/script_order.hpp @@ -91,6 +91,7 @@ public: /* Note: these values represent part of the in-game OrderConditionVariable enum */ OC_LOAD_PERCENTAGE = ::OCV_LOAD_PERCENTAGE, ///< Skip based on the amount of load, value is in tons. OC_RELIABILITY = ::OCV_RELIABILITY, ///< Skip based on the reliability, value is percent (0..100). + OC_MAX_RELIABILITY = ::OCV_MAX_RELIABILITY, ///< Skip based on the maximum reliability. Value in percent OC_MAX_SPEED = ::OCV_MAX_SPEED, ///< Skip based on the maximum speed, value is in OpenTTD's internal speed unit, see ScriptEngine::GetMaxSpeed. OC_AGE = ::OCV_AGE, ///< Skip based on the age, value is in years. OC_REQUIRES_SERVICE = ::OCV_REQUIRES_SERVICE, ///< Skip when the vehicle requires service, no value. diff --git a/src/script/api/script_rail.cpp b/src/script/api/script_rail.cpp index af68a3edc8..f7682cfd8f 100644 --- a/src/script/api/script_rail.cpp +++ b/src/script/api/script_rail.cpp @@ -157,7 +157,7 @@ EnforcePrecondition(false, station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id)); uint32 p1 = GetCurrentRailType() | (platform_length << 16) | (num_platforms << 8); - if (direction == RAILTRACK_NW_SE) p1 |= (1 << 4); + if (direction == RAILTRACK_NW_SE) p1 |= (1 << 6); if (station_id != ScriptStation::STATION_JOIN_ADJACENT) p1 |= (1 << 24); return ScriptObject::DoCommand(tile, p1, (ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16, CMD_BUILD_RAIL_STATION); } @@ -176,7 +176,7 @@ EnforcePrecondition(false, goal_industry == ScriptIndustryType::INDUSTRYTYPE_UNKNOWN || goal_industry == ScriptIndustryType::INDUSTRYTYPE_TOWN || ScriptIndustryType::IsValidIndustryType(goal_industry)); uint32 p1 = GetCurrentRailType() | (platform_length << 16) | (num_platforms << 8); - if (direction == RAILTRACK_NW_SE) p1 |= 1 << 4; + if (direction == RAILTRACK_NW_SE) p1 |= 1 << 6; if (station_id != ScriptStation::STATION_JOIN_ADJACENT) p1 |= (1 << 24); const GRFFile *file; @@ -204,7 +204,7 @@ EnforcePrecondition(false, GetRailTracks(tile) == RAILTRACK_NE_SW || GetRailTracks(tile) == RAILTRACK_NW_SE); EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType())); - return ScriptObject::DoCommand(tile, GetCurrentRailType() | (GetRailTracks(tile) == RAILTRACK_NE_SW ? AXIS_X : AXIS_Y) << 4 | 1 << 8 | 1 << 16, STAT_CLASS_WAYP | INVALID_STATION << 16, CMD_BUILD_RAIL_WAYPOINT); + return ScriptObject::DoCommand(tile, GetCurrentRailType() | (GetRailTracks(tile) == RAILTRACK_NE_SW ? AXIS_X : AXIS_Y) << 6 | 1 << 8 | 1 << 16, STAT_CLASS_WAYP | INVALID_STATION << 16, CMD_BUILD_RAIL_WAYPOINT); } /* static */ bool ScriptRail::RemoveRailWaypointTileRectangle(TileIndex tile, TileIndex tile2, bool keep_rail) @@ -244,7 +244,7 @@ EnforcePrecondition(false, KillFirstBit((uint)rail_track) == 0); EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType())); - return ScriptObject::DoCommand(tile, tile, GetCurrentRailType() | (FindFirstTrack((::TrackBits)rail_track) << 4), CMD_BUILD_RAILROAD_TRACK); + return ScriptObject::DoCommand(tile, tile, GetCurrentRailType() | (FindFirstTrack((::TrackBits)rail_track) << 6), CMD_BUILD_RAILROAD_TRACK); } /* static */ bool ScriptRail::RemoveRailTrack(TileIndex tile, RailTrack rail_track) @@ -255,7 +255,7 @@ EnforcePrecondition(false, GetRailTracks(tile) & rail_track); EnforcePrecondition(false, KillFirstBit((uint)rail_track) == 0); - return ScriptObject::DoCommand(tile, tile, FindFirstTrack((::TrackBits)rail_track) << 4, CMD_REMOVE_RAILROAD_TRACK); + return ScriptObject::DoCommand(tile, tile, FindFirstTrack((::TrackBits)rail_track) << 6, CMD_REMOVE_RAILROAD_TRACK); } /* static */ bool ScriptRail::AreTilesConnected(TileIndex from, TileIndex tile, TileIndex to) @@ -288,16 +288,16 @@ static uint32 SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) int diag_offset = abs(abs((int)::TileX(*to) - (int)::TileX(tile)) - abs((int)::TileY(*to) - (int)::TileY(tile))); uint32 p2 = 0; if (::TileY(from) == ::TileY(*to)) { - p2 |= (TRACK_X << 4); + p2 |= (TRACK_X << 6); *to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1); } else if (::TileX(from) == ::TileX(*to)) { - p2 |= (TRACK_Y << 4); + p2 |= (TRACK_Y << 6); *to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1); } else if (::TileY(from) < ::TileY(tile)) { if (::TileX(*to) < ::TileX(tile)) { - p2 |= (TRACK_UPPER << 4); + p2 |= (TRACK_UPPER << 6); } else { - p2 |= (TRACK_LEFT << 4); + p2 |= (TRACK_LEFT << 6); } if (diag_offset != 0) { *to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1); @@ -306,9 +306,9 @@ static uint32 SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) } } else if (::TileY(from) > ::TileY(tile)) { if (::TileX(*to) < ::TileX(tile)) { - p2 |= (TRACK_RIGHT << 4); + p2 |= (TRACK_RIGHT << 6); } else { - p2 |= (TRACK_LOWER << 4); + p2 |= (TRACK_LOWER << 6); } if (diag_offset != 0) { *to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1); @@ -317,9 +317,9 @@ static uint32 SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) } } else if (::TileX(from) < ::TileX(tile)) { if (::TileY(*to) < ::TileY(tile)) { - p2 |= (TRACK_UPPER << 4); + p2 |= (TRACK_UPPER << 6); } else { - p2 |= (TRACK_RIGHT << 4); + p2 |= (TRACK_RIGHT << 6); } if (diag_offset == 0) { *to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1); @@ -328,9 +328,9 @@ static uint32 SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) } } else if (::TileX(from) > ::TileX(tile)) { if (::TileY(*to) < ::TileY(tile)) { - p2 |= (TRACK_LEFT << 4); + p2 |= (TRACK_LEFT << 6); } else { - p2 |= (TRACK_LOWER << 4); + p2 |= (TRACK_LOWER << 6); } if (diag_offset == 0) { *to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1); @@ -355,7 +355,7 @@ static uint32 SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) (::TileX(from) == ::TileX(tile) && ::TileX(tile) == ::TileX(to)) || (::TileY(from) == ::TileY(tile) && ::TileY(tile) == ::TileY(to))); - uint32 p2 = SimulateDrag(from, tile, &to) | 1 << 8 | ScriptRail::GetCurrentRailType();; + uint32 p2 = SimulateDrag(from, tile, &to) | 1 << 10 | ScriptRail::GetCurrentRailType();; return ScriptObject::DoCommand(tile, to, p2, CMD_BUILD_RAILROAD_TRACK); } diff --git a/src/script/api/script_station.hpp b/src/script/api/script_station.hpp index 8561cd9bdd..42ea412d08 100644 --- a/src/script/api/script_station.hpp +++ b/src/script/api/script_station.hpp @@ -30,7 +30,7 @@ public: ERR_STATION_BASE = ScriptError::ERR_CAT_STATION << ScriptError::ERR_CAT_BIT_SIZE, /** The station is build too close to another station, airport or dock */ - ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION, // [STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT, STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION, STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK] + ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION, // [STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT, STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK] /** There are too many stations, airports and docks in the game */ ERR_STATION_TOO_MANY_STATIONS, // [STR_ERROR_TOO_MANY_STATIONS_LOADING, STR_ERROR_TOO_MANY_TRUCK_STOPS, STR_ERROR_TOO_MANY_BUS_STOPS] diff --git a/src/script/api/script_stationlist.cpp b/src/script/api/script_stationlist.cpp index ab9503a1b5..51a06b5a74 100644 --- a/src/script/api/script_stationlist.cpp +++ b/src/script/api/script_stationlist.cpp @@ -151,13 +151,13 @@ void CargoCollector::Update(StationID from, StationID via, uint amount) switch (Tselector) { case ScriptStationList_Cargo::CS_VIA_BY_FROM: if (via != this->other_station) return; - /* fall through */ + FALLTHROUGH; case ScriptStationList_Cargo::CS_BY_FROM: key = from; break; case ScriptStationList_Cargo::CS_FROM_BY_VIA: if (from != this->other_station) return; - /* fall through */ + FALLTHROUGH; case ScriptStationList_Cargo::CS_BY_VIA: key = via; break; diff --git a/src/script/api/script_town.cpp b/src/script/api/script_town.cpp index d81704ae38..4cdd6a9d0e 100644 --- a/src/script/api/script_town.cpp +++ b/src/script/api/script_town.cpp @@ -159,24 +159,24 @@ /* static */ bool ScriptTown::SetGrowthRate(TownID town_id, uint32 days_between_town_growth) { EnforcePrecondition(false, IsValidTown(town_id)); - + uint16 growth_rate; switch (days_between_town_growth) { case TOWN_GROWTH_NORMAL: - days_between_town_growth = 0; + growth_rate = 0; break; case TOWN_GROWTH_NONE: - days_between_town_growth = TOWN_GROW_RATE_CUSTOM_NONE; + growth_rate = TOWN_GROWTH_RATE_NONE; break; default: - days_between_town_growth = days_between_town_growth * DAY_TICKS / TOWN_GROWTH_TICKS; - EnforcePrecondition(false, days_between_town_growth < TOWN_GROW_RATE_CUSTOM); - if (days_between_town_growth == 0) days_between_town_growth = 1; // as fast as possible + EnforcePrecondition(false, days_between_town_growth <= MAX_TOWN_GROWTH_TICKS); + /* Don't use growth_rate 0 as it means GROWTH_NORMAL */ + growth_rate = max(days_between_town_growth * DAY_TICKS, 2u) - 1; break; } - return ScriptObject::DoCommand(::Town::Get(town_id)->xy, town_id, days_between_town_growth, CMD_TOWN_GROWTH_RATE); + return ScriptObject::DoCommand(::Town::Get(town_id)->xy, town_id, growth_rate, CMD_TOWN_GROWTH_RATE); } /* static */ int32 ScriptTown::GetGrowthRate(TownID town_id) @@ -185,9 +185,9 @@ const Town *t = ::Town::Get(town_id); - if (t->growth_rate == TOWN_GROW_RATE_CUSTOM_NONE) return TOWN_GROWTH_NONE; + if (t->growth_rate == TOWN_GROWTH_RATE_NONE) return TOWN_GROWTH_NONE; - return ((t->growth_rate & ~TOWN_GROW_RATE_CUSTOM) * TOWN_GROWTH_TICKS + DAY_TICKS) / DAY_TICKS; + return RoundDivSU(t->growth_rate + 1, DAY_TICKS); } /* static */ int32 ScriptTown::GetDistanceManhattanToTile(TownID town_id, TileIndex tile) diff --git a/src/script/api/script_town.hpp b/src/script/api/script_town.hpp index 03868e67a4..7fdf8a6b39 100644 --- a/src/script/api/script_town.hpp +++ b/src/script/api/script_town.hpp @@ -259,7 +259,7 @@ public: * @param town_id The index of the town. * @param days_between_town_growth The amount of days between town growth, TOWN_GROWTH_NONE or TOWN_GROWTH_NORMAL. * @pre IsValidTown(town_id). - * @pre days_between_town_growth <= 30000 || days_between_town_growth == TOWN_GROWTH_NONE || days_between_town_growth == TOWN_GROWTH_NORMAL. + * @pre days_between_town_growth <= 880 || days_between_town_growth == TOWN_GROWTH_NONE || days_between_town_growth == TOWN_GROWTH_NORMAL. * @return True if the action succeeded. * @note Even when setting a growth rate, towns only grow when the conditions for growth (SetCargoCoal) are met, * and the game settings (economy.town_growth_rate) allow town growth at all. diff --git a/src/script/api/script_window.hpp b/src/script/api/script_window.hpp index fbdffb54b7..e11742bafb 100644 --- a/src/script/api/script_window.hpp +++ b/src/script/api/script_window.hpp @@ -32,6 +32,7 @@ #include "../../widgets/engine_widget.h" #include "../../widgets/error_widget.h" #include "../../widgets/fios_widget.h" +#include "../../widgets/framerate_widget.h" #include "../../widgets/genworld_widget.h" #include "../../widgets/goal_widget.h" #include "../../widgets/graph_widget.h" @@ -764,6 +765,18 @@ public: */ WC_SAVE_PRESET = ::WC_SAVE_PRESET, + /** + * Framerate display; %Window numbers: + * - 0 = #FramerateDisplayWidgets + */ + WC_FRAMERATE_DISPLAY = ::WC_FRAMERATE_DISPLAY, + + /** + * Frame time graph; %Window numbers: + * - 0 = #FrametimeGraphWindowWidgets + */ + WC_FRAMETIME_GRAPH = ::WC_FRAMETIME_GRAPH, + WC_INVALID = ::WC_INVALID, ///< Invalid window. }; @@ -988,7 +1001,7 @@ public: }; /* automatically generated from ../../widgets/cheat_widget.h */ - /** Widgets of the #CheatWindow class.. */ + /** Widgets of the #CheatWindow class. */ enum CheatWidgets { WID_C_PANEL = ::WID_C_PANEL, ///< Panel where all cheats are shown in. }; @@ -1259,6 +1272,7 @@ public: WID_SL_CAPTION = ::WID_SL_CAPTION, ///< Caption of the window. WID_SL_SORT_BYNAME = ::WID_SL_SORT_BYNAME, ///< Sort by name button. WID_SL_SORT_BYDATE = ::WID_SL_SORT_BYDATE, ///< Sort by date button. + WID_SL_FILTER = ::WID_SL_FILTER, ///< Filter list of files WID_SL_BACKGROUND = ::WID_SL_BACKGROUND, ///< Background of window. WID_SL_FILE_BACKGROUND = ::WID_SL_FILE_BACKGROUND, ///< Background of file selection. WID_SL_HOME_BUTTON = ::WID_SL_HOME_BUTTON, ///< Home button. @@ -1275,6 +1289,25 @@ public: WID_SL_MISSING_NEWGRFS = ::WID_SL_MISSING_NEWGRFS, ///< Button to find missing NewGRFs online. }; + /* automatically generated from ../../widgets/framerate_widget.h */ + /** Widgets of the #FramerateWindow class. */ + enum FramerateWindowWidgets { + WID_FRW_CAPTION = ::WID_FRW_CAPTION, + WID_FRW_RATE_GAMELOOP = ::WID_FRW_RATE_GAMELOOP, + WID_FRW_RATE_DRAWING = ::WID_FRW_RATE_DRAWING, + WID_FRW_RATE_FACTOR = ::WID_FRW_RATE_FACTOR, + WID_FRW_INFO_DATA_POINTS = ::WID_FRW_INFO_DATA_POINTS, + WID_FRW_TIMES_NAMES = ::WID_FRW_TIMES_NAMES, + WID_FRW_TIMES_CURRENT = ::WID_FRW_TIMES_CURRENT, + WID_FRW_TIMES_AVERAGE = ::WID_FRW_TIMES_AVERAGE, + }; + + /** Widgets of the #FrametimeGraphWindow class. */ + enum FrametimeGraphWindowWidgets { + WID_FGW_CAPTION = ::WID_FGW_CAPTION, + WID_FGW_GRAPH = ::WID_FGW_GRAPH, + }; + /* automatically generated from ../../widgets/genworld_widget.h */ /** Widgets of the #GenerateLandscapeWindow class. */ enum GenerateLandscapeWidgets { @@ -1439,6 +1472,7 @@ public: WID_GL_DELETE_GROUP = ::WID_GL_DELETE_GROUP, ///< Delete group button. WID_GL_RENAME_GROUP = ::WID_GL_RENAME_GROUP, ///< Rename group button. WID_GL_REPLACE_PROTECTION = ::WID_GL_REPLACE_PROTECTION, ///< Replace protection button. + WID_GL_INFO = ::WID_GL_INFO, ///< Group info. }; /* automatically generated from ../../widgets/highscore_widget.h */ @@ -1581,9 +1615,11 @@ public: /* automatically generated from ../../widgets/music_widget.h */ /** Widgets of the #MusicTrackSelectionWindow class. */ enum MusicTrackSelectionWidgets { + WID_MTS_CAPTION = ::WID_MTS_CAPTION, ///< Window caption. WID_MTS_LIST_LEFT = ::WID_MTS_LIST_LEFT, ///< Left button. WID_MTS_PLAYLIST = ::WID_MTS_PLAYLIST, ///< Playlist. WID_MTS_LIST_RIGHT = ::WID_MTS_LIST_RIGHT, ///< Right button. + WID_MTS_MUSICSET = ::WID_MTS_MUSICSET, ///< Music set selection. WID_MTS_ALL = ::WID_MTS_ALL, ///< All button. WID_MTS_OLD = ::WID_MTS_OLD, ///< Old button. WID_MTS_NEW = ::WID_MTS_NEW, ///< New button. @@ -2381,7 +2417,7 @@ public: WID_TN_TRAINS = ::WID_TN_TRAINS, ///< Train menu. WID_TN_ROADVEHS = ::WID_TN_ROADVEHS, ///< Road vehicle menu. WID_TN_SHIPS = ::WID_TN_SHIPS, ///< Ship menu. - WID_TN_AIRCRAFTS = ::WID_TN_AIRCRAFTS, ///< Aircraft menu. + WID_TN_AIRCRAFT = ::WID_TN_AIRCRAFT, ///< Aircraft menu. WID_TN_ZOOM_IN = ::WID_TN_ZOOM_IN, ///< Zoom in the main viewport. WID_TN_ZOOM_OUT = ::WID_TN_ZOOM_OUT, ///< Zoom out the main viewport. WID_TN_BUILDING_TOOLS_START = ::WID_TN_BUILDING_TOOLS_START, ///< Helper for the offset of the building tools diff --git a/src/script/api/template/template_window.hpp.sq b/src/script/api/template/template_window.hpp.sq index a21a75ab89..3077215ec2 100644 --- a/src/script/api/template/template_window.hpp.sq +++ b/src/script/api/template/template_window.hpp.sq @@ -77,6 +77,10 @@ namespace SQConvert { template <> inline int Return(HSQUIRRELVM vm, ScriptWindow::ErrorMessageWidgets res) { sq_pushinteger(vm, (int32)res); return 1; } template <> inline ScriptWindow::SaveLoadWidgets GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptWindow::SaveLoadWidgets)tmp; } template <> inline int Return(HSQUIRRELVM vm, ScriptWindow::SaveLoadWidgets res) { sq_pushinteger(vm, (int32)res); return 1; } + template <> inline ScriptWindow::FramerateWindowWidgets GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptWindow::FramerateWindowWidgets)tmp; } + template <> inline int Return(HSQUIRRELVM vm, ScriptWindow::FramerateWindowWidgets res) { sq_pushinteger(vm, (int32)res); return 1; } + template <> inline ScriptWindow::FrametimeGraphWindowWidgets GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptWindow::FrametimeGraphWindowWidgets)tmp; } + template <> inline int Return(HSQUIRRELVM vm, ScriptWindow::FrametimeGraphWindowWidgets res) { sq_pushinteger(vm, (int32)res); return 1; } template <> inline ScriptWindow::GenerateLandscapeWidgets GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptWindow::GenerateLandscapeWidgets)tmp; } template <> inline int Return(HSQUIRRELVM vm, ScriptWindow::GenerateLandscapeWidgets res) { sq_pushinteger(vm, (int32)res); return 1; } template <> inline ScriptWindow::CreateScenarioWidgets GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptWindow::CreateScenarioWidgets)tmp; } diff --git a/src/script/script_config.cpp b/src/script/script_config.cpp index a6e41476e8..3171e67d4f 100644 --- a/src/script/script_config.cpp +++ b/src/script/script_config.cpp @@ -36,7 +36,7 @@ void ScriptConfig::Change(const char *name, int version, bool force_exact_match, * for the Script that have the random flag to a random value. */ for (ScriptConfigItemList::const_iterator it = this->info->GetConfigList()->begin(); it != this->info->GetConfigList()->end(); it++) { if ((*it).flags & SCRIPTCONFIG_RANDOM) { - this->SetSetting((*it).name, InteractiveRandomRange((*it).max_value - (*it).min_value) + (*it).min_value); + this->SetSetting((*it).name, InteractiveRandomRange((*it).max_value + 1 - (*it).min_value) + (*it).min_value); } } this->AddRandomDeviation(); diff --git a/src/script/script_info_dummy.cpp b/src/script/script_info_dummy.cpp index e11c631512..53860386c1 100644 --- a/src/script/script_info_dummy.cpp +++ b/src/script/script_info_dummy.cpp @@ -92,7 +92,7 @@ void Script_CreateDummy(HSQUIRRELVM vm, StringID string, const char *type) p = newline + 1; } while (newline != NULL); - dp = strecpy(dp, " }\n}\n", lastof(dummy_script)); + strecpy(dp, " }\n}\n", lastof(dummy_script)); /* 3) We translate the error message in the character format that Squirrel wants. * We can use the fact that the wchar string printing also uses %s to print diff --git a/src/script/script_scanner.cpp b/src/script/script_scanner.cpp index 57265669f9..fe6d41cf92 100644 --- a/src/script/script_scanner.cpp +++ b/src/script/script_scanner.cpp @@ -134,7 +134,7 @@ void ScriptScanner::RegisterScript(ScriptInfo *info) if (this->info_list.find(script_name) != this->info_list.end()) { /* This script was already registered */ -#ifdef WIN32 +#ifdef _WIN32 /* Windows doesn't care about the case */ if (strcasecmp(this->info_list[script_name]->GetMainScript(), info->GetMainScript()) == 0) { #else diff --git a/src/script/squirrel.cpp b/src/script/squirrel.cpp index e38067480d..23163f6b34 100644 --- a/src/script/squirrel.cpp +++ b/src/script/squirrel.cpp @@ -432,13 +432,8 @@ static SQInteger _io_file_read(SQUserPointer file, SQUserPointer buf, SQInteger SQRESULT Squirrel::LoadFile(HSQUIRRELVM vm, const char *filename, SQBool printerror) { - size_t size; FILE *file; - SQInteger ret; - unsigned short us; - unsigned char uc; - SQLEXREADFUNC func; - + size_t size; if (strncmp(this->GetAPIName(), "AI", 2) == 0) { file = FioFOpenFile(filename, "rb", AI_DIR, &size); if (file == NULL) file = FioFOpenFile(filename, "rb", AI_LIBRARY_DIR, &size); @@ -449,61 +444,75 @@ SQRESULT Squirrel::LoadFile(HSQUIRRELVM vm, const char *filename, SQBool printer NOT_REACHED(); } - if (file != NULL) { - SQFile f(file, size); - ret = fread(&us, 1, sizeof(us), file); - /* Most likely an empty file */ - if (ret != 2) us = 0; - - switch (us) { - case SQ_BYTECODE_STREAM_TAG: { // BYTECODE - if (fseek(file, -2, SEEK_CUR) < 0) { - FioFCloseFile(file); - return sq_throwerror(vm, "cannot seek the file"); - } - if (SQ_SUCCEEDED(sq_readclosure(vm, _io_file_read, &f))) { - FioFCloseFile(file); - return SQ_OK; - } - FioFCloseFile(file); - return sq_throwerror(vm, "Couldn't read bytecode"); - } - case 0xFFFE: - /* Either this file is encoded as big-endian and we're on a little-endian - * machine, or this file is encoded as little-endian and we're on a big-endian - * machine. Either way, swap the bytes of every word we read. */ - func = _io_file_lexfeed_UCS2_swap; - break; - case 0xFEFF: func = _io_file_lexfeed_UCS2_no_swap; break; - case 0xBBEF: // UTF-8 - case 0xEFBB: // UTF-8 on big-endian machine - if (fread(&uc, 1, sizeof(uc), file) == 0) { - FioFCloseFile(file); - return sq_throwerror(vm, "I/O error"); - } - if (uc != 0xBF) { - FioFCloseFile(file); - return sq_throwerror(vm, "Unrecognized encoding"); - } - func = _io_file_lexfeed_UTF8; - break; - default: // ASCII - func = _io_file_lexfeed_ASCII; - if (fseek(file, -2, SEEK_CUR) < 0) { - FioFCloseFile(file); - return sq_throwerror(vm, "cannot seek the file"); - } - break; - } - - if (SQ_SUCCEEDED(sq_compile(vm, func, &f, filename, printerror))) { - FioFCloseFile(file); - return SQ_OK; - } - FioFCloseFile(file); - return SQ_ERROR; + if (file == NULL) { + return sq_throwerror(vm, "cannot open the file"); } - return sq_throwerror(vm, "cannot open the file"); + unsigned short bom = 0; + if (size >= 2) { + size_t sr = fread(&bom, 1, sizeof(bom), file); + (void)sr; // Inside tar, no point checking return value of fread + } + + SQLEXREADFUNC func; + switch (bom) { + case SQ_BYTECODE_STREAM_TAG: { // BYTECODE + if (fseek(file, -2, SEEK_CUR) < 0) { + FioFCloseFile(file); + return sq_throwerror(vm, "cannot seek the file"); + } + + SQFile f(file, size); + if (SQ_SUCCEEDED(sq_readclosure(vm, _io_file_read, &f))) { + FioFCloseFile(file); + return SQ_OK; + } + FioFCloseFile(file); + return sq_throwerror(vm, "Couldn't read bytecode"); + } + case 0xFFFE: + /* Either this file is encoded as big-endian and we're on a little-endian + * machine, or this file is encoded as little-endian and we're on a big-endian + * machine. Either way, swap the bytes of every word we read. */ + func = _io_file_lexfeed_UCS2_swap; + size -= 2; // Skip BOM + break; + case 0xFEFF: + func = _io_file_lexfeed_UCS2_no_swap; + size -= 2; // Skip BOM + break; + case 0xBBEF: // UTF-8 + case 0xEFBB: { // UTF-8 on big-endian machine + /* Similarly, check the file is actually big enough to finish checking BOM */ + if (size < 3) { + FioFCloseFile(file); + return sq_throwerror(vm, "I/O error"); + } + unsigned char uc; + if (fread(&uc, 1, sizeof(uc), file) != sizeof(uc) || uc != 0xBF) { + FioFCloseFile(file); + return sq_throwerror(vm, "Unrecognized encoding"); + } + func = _io_file_lexfeed_UTF8; + size -= 3; // Skip BOM + break; + } + default: // ASCII + func = _io_file_lexfeed_ASCII; + /* Account for when we might not have fread'd earlier */ + if (size >= 2 && fseek(file, -2, SEEK_CUR) < 0) { + FioFCloseFile(file); + return sq_throwerror(vm, "cannot seek the file"); + } + break; + } + + SQFile f(file, size); + if (SQ_SUCCEEDED(sq_compile(vm, func, &f, filename, printerror))) { + FioFCloseFile(file); + return SQ_OK; + } + FioFCloseFile(file); + return SQ_ERROR; } bool Squirrel::LoadScript(HSQUIRRELVM vm, const char *script, bool in_root) diff --git a/src/sdl.h b/src/sdl.h index ff1092358f..9033899a59 100644 --- a/src/sdl.h +++ b/src/sdl.h @@ -15,7 +15,7 @@ const char *SdlOpen(uint32 x); void SdlClose(uint32 x); -#ifdef WIN32 +#ifdef _WIN32 #define DYNAMICALLY_LOADED_SDL #endif diff --git a/src/settings.cpp b/src/settings.cpp index d819450221..3e61cc87f8 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1459,7 +1459,7 @@ static int DecodeHexNibble(char c) * Parse a sequence of characters (supposedly hex digits) into a sequence of bytes. * After the hex number should be a \c '|' character. * @param pos First character to convert. - * @param dest [out] Output byte array to write the bytes. + * @param[out] dest Output byte array to write the bytes. * @param dest_size Number of bytes in \a dest. * @return Whether reading was successful. */ @@ -1668,9 +1668,9 @@ static void HandleSettingDescs(IniFile *ini, SettingDescProc *proc, SettingDescP { if (basic_settings) { proc(ini, (const SettingDesc*)_misc_settings, "misc", NULL); -#if defined(WIN32) && !defined(DEDICATED) +#if defined(_WIN32) && !defined(DEDICATED) proc(ini, (const SettingDesc*)_win32_settings, "win32", NULL); -#endif /* WIN32 */ +#endif /* _WIN32 */ } if (other_settings) { @@ -1748,7 +1748,7 @@ void SaveToConfig() /** * Get the list of known NewGrf presets. - * @param list[inout] Pointer to list for storing the preset names. + * @param[in,out] list Pointer to list for storing the preset names. */ void GetGRFPresetList(GRFPresetList *list) { diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 0420ba15b3..5ebac02807 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -114,19 +114,24 @@ static int GetCurRes() static void ShowCustCurrency(); template -static DropDownList *BuiltSetDropDownList(int *selected_index) +static DropDownList *BuildSetDropDownList(int *selected_index, bool allow_selection) { int n = T::GetNumSets(); *selected_index = T::GetIndexOfUsedSet(); DropDownList *list = new DropDownList(); for (int i = 0; i < n; i++) { - *list->Append() = new DropDownListCharStringItem(T::GetSet(i)->name, i, (_game_mode == GM_MENU) ? false : (*selected_index != i)); + *list->Append() = new DropDownListCharStringItem(T::GetSet(i)->name, i, !allow_selection && (*selected_index != i)); } return list; } +DropDownList *BuildMusicSetDropDownList(int *selected_index) +{ + return BuildSetDropDownList(selected_index, true); +} + /** Window for displaying the textfile of a BaseSet. */ template struct BaseSetTextfileWindow : public TextfileWindow { @@ -297,15 +302,15 @@ struct GameOptionsWindow : Window { } case WID_GO_BASE_GRF_DROPDOWN: - list = BuiltSetDropDownList(selected_index); + list = BuildSetDropDownList(selected_index, (_game_mode == GM_MENU)); break; case WID_GO_BASE_SFX_DROPDOWN: - list = BuiltSetDropDownList(selected_index); + list = BuildSetDropDownList(selected_index, (_game_mode == GM_MENU)); break; case WID_GO_BASE_MUSIC_DROPDOWN: - list = BuiltSetDropDownList(selected_index); + list = BuildMusicSetDropDownList(selected_index); break; default: @@ -544,7 +549,7 @@ struct GameOptionsWindow : Window { break; case WID_GO_BASE_MUSIC_DROPDOWN: - this->SetMediaSet(index); + ChangeMusicSet(index); break; } } @@ -1508,9 +1513,8 @@ static SettingsContainer &GetSettingsTree() SettingsPage *viewports = interface->Add(new SettingsPage(STR_CONFIG_SETTING_INTERFACE_VIEWPORTS)); { viewports->Add(new SettingEntry("gui.auto_scrolling")); - viewports->Add(new SettingEntry("gui.reverse_scroll")); + viewports->Add(new SettingEntry("gui.scroll_mode")); viewports->Add(new SettingEntry("gui.smooth_scroll")); - viewports->Add(new SettingEntry("gui.left_mouse_btn_scrolling")); /* While the horizontal scrollwheel scrolling is written as general code, only * the cocoa (OSX) driver generates input for it. * Since it's also able to completely disable the scrollwheel will we display it on all platforms anyway */ diff --git a/src/settings_gui.h b/src/settings_gui.h index 05955aa557..23a343219f 100644 --- a/src/settings_gui.h +++ b/src/settings_gui.h @@ -13,6 +13,7 @@ #define SETTING_GUI_H #include "gfx_type.h" +#include "widgets/dropdown_type.h" /** Width of setting buttons */ #define SETTING_BUTTON_WIDTH ((int)NWidgetScrollbar::GetHorizontalDimension().width * 2) @@ -23,5 +24,10 @@ void DrawArrowButtons(int x, int y, Colours button_colour, byte state, bool clic void DrawDropDownButton(int x, int y, Colours button_colour, bool state, bool clickable); void DrawBoolButton(int x, int y, bool state, bool clickable); +DropDownList *BuildMusicSetDropDownList(int *selected_index); + +/* Actually implemented in music_gui.cpp */ +void ChangeMusicSet(int index); + #endif /* SETTING_GUI_H */ diff --git a/src/settings_type.h b/src/settings_type.h index 2dc9ec92ec..690f6d8036 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -71,6 +71,15 @@ struct DifficultySettings { byte town_council_tolerance; ///< minimum required town ratings to be allowed to demolish stuff }; +/** Settings relating to viewport/smallmap scrolling. */ +enum ViewportScrollMode { + VSM_VIEWPORT_RMB_FIXED, ///< Viewport moves with mouse movement on holding right mouse button, cursor position is fixed. + VSM_MAP_RMB_FIXED, ///< Map moves with mouse movement on holding right mouse button, cursor position is fixed. + VSM_MAP_RMB, ///< Map moves with mouse movement on holding right mouse button, cursor moves. + VSM_MAP_LMB, ///< Map moves with mouse movement on holding left mouse button, cursor moves. + VSM_END, ///< Number of scroll mode settings. +}; + /** Settings related to the GUI and other stuff that is not saved in the savegame. */ struct GUISettings { bool sg_full_load_any; ///< new full load calculation, any cargo must be full read from pre v93 savegames @@ -86,11 +95,11 @@ struct GUISettings { uint16 hover_delay_ms; ///< time required to activate a hover event, in milliseconds bool link_terraform_toolbar; ///< display terraform toolbar when displaying rail, road, water and airport toolbars uint8 smallmap_land_colour; ///< colour used for land and heightmap at the smallmap - bool reverse_scroll; ///< right-Click-Scrolling scrolls in the opposite direction + uint8 scroll_mode; ///< viewport scroll mode bool smooth_scroll; ///< smooth scroll viewports bool measure_tooltip; ///< show a permanent tooltip when dragging tools byte liveries; ///< options for displaying company liveries, 0=none, 1=self, 2=all - bool prefer_teamchat; ///< choose the chat message target with , true=all clients, false=your team + bool prefer_teamchat; ///< choose the chat message target with \, true=all clients, false=your team uint8 advanced_vehicle_list; ///< use the "advanced" vehicle list uint8 loading_indicators; ///< show loading indicators uint8 default_rail_type; ///< the default rail type for the rail GUI @@ -105,6 +114,7 @@ struct GUISettings { bool threaded_saves; ///< should we do threaded saves? bool keep_all_autosave; ///< name the autosave in a different way bool autosave_on_exit; ///< save an autosave when you quit the game, but do not ask "Do you really want to quit?" + bool autosave_on_network_disconnect; ///< save an autosave when you get disconnected from a network game with an error? uint8 date_format_in_default_names; ///< should the default savegame/screenshot name use long dates (31th Dec 2008), short dates (31-12-2008) or ISO dates (2008-12-31) byte max_num_autosaves; ///< controls how many autosavegames are made before the game starts to overwrite (names them 0 to max_num_autosaves - 1) bool population_in_label; ///< show the population of a town in his label? @@ -112,7 +122,6 @@ struct GUISettings { uint8 scrollwheel_scrolling; ///< scrolling using the scroll wheel? uint8 scrollwheel_multiplier; ///< how much 'wheel' per incoming event from the OS? bool timetable_arrival_departure; ///< show arrivals and departures in vehicle timetables - bool left_mouse_btn_scrolling; ///< left mouse button scroll bool right_mouse_wnd_close; ///< close window with right click bool pause_on_newgame; ///< whether to start new games paused or not bool enable_signal_gui; ///< show the signal GUI when the signal button is pressed diff --git a/src/settingsgen/settingsgen.cpp b/src/settingsgen/settingsgen.cpp index dd92e2627b..298539417e 100644 --- a/src/settingsgen/settingsgen.cpp +++ b/src/settingsgen/settingsgen.cpp @@ -18,7 +18,7 @@ #include -#if (!defined(WIN32) && !defined(WIN64)) || defined(__CYGWIN__) +#if !defined(_WIN32) || defined(__CYGWIN__) #include #include #endif @@ -205,7 +205,6 @@ static const char *DEFAULTS_GROUP_NAME = "defaults"; ///< Name of the group c /** * Load the INI file. * @param filename Name of the file to load. - * @param subdir The subdirectory to load from. * @return Loaded INI data. */ static IniLoadFile *LoadIniFile(const char *filename) @@ -372,7 +371,10 @@ static bool CompareFiles(const char *n1, const char *n2) if (f2 == NULL) return false; FILE *f1 = fopen(n1, "rb"); - if (f1 == NULL) error("can't open %s", n1); + if (f1 == NULL) { + fclose(f2); + error("can't open %s", n1); + } size_t l1, l2; do { @@ -413,12 +415,12 @@ static const OptionData _opts[] = { * After loading, the [pre-amble] group is copied verbatim if it exists. * * For every group with a name that matches a template name the template is written. - * It starts with a optional '#if' line if an 'if' item exists in the group. The item - * value is used as condition. Similarly, '#ifdef' and '#ifndef' lines are also written. + * It starts with a optional \c \#if line if an 'if' item exists in the group. The item + * value is used as condition. Similarly, \c \#ifdef and \c \#ifndef lines are also written. * Below the macro processor directives, the value of the template is written * at a line with its variables replaced by item values of the group being written. * If the group has no item for the variable, the [defaults] group is tried as fall back. - * Finally, '#endif' lines are written to match the macro processor lines. + * Finally, \c \#endif lines are written to match the macro processor lines. * * Last but not least, the [post-amble] group is copied verbatim. * @@ -510,7 +512,7 @@ int CDECL main(int argc, char *argv[]) unlink(tmp_output); } else { /* Rename tmp2.xxx to output file. */ -#if defined(WIN32) || defined(WIN64) +#if defined(_WIN32) unlink(output_file); #endif if (rename(tmp_output, output_file) == -1) error("rename() failed"); diff --git a/src/ship.h b/src/ship.h index c94cbcddb7..0f396a237d 100644 --- a/src/ship.h +++ b/src/ship.h @@ -30,7 +30,7 @@ struct Ship FINAL : public SpecializedVehicle { virtual ~Ship() { this->PreDestructor(); } void MarkDirty(); - void UpdateDeltaXY(Direction direction); + void UpdateDeltaXY(); ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_SHIP_INC : EXPENSES_SHIP_RUN; } void PlayLeaveStationSound() const; bool IsPrimaryVehicle() const { return true; } diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index 771863a24d..e606afc0ce 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -34,6 +34,7 @@ #include "company_base.h" #include "tunnelbridge_map.h" #include "zoom_func.h" +#include "framerate_type.h" #include "table/strings.h" @@ -296,7 +297,7 @@ TileIndex Ship::GetOrderStationLocation(StationID station) } } -void Ship::UpdateDeltaXY(Direction direction) +void Ship::UpdateDeltaXY() { static const int8 _delta_xy_table[8][4] = { /* y_extent, x_extent, y_offs, x_offs */ @@ -310,7 +311,7 @@ void Ship::UpdateDeltaXY(Direction direction) {32, 6, -16, -3}, // NW }; - const int8 *bb = _delta_xy_table[direction]; + const int8 *bb = _delta_xy_table[this->direction]; this->x_offs = bb[3]; this->y_offs = bb[2]; this->x_extent = bb[1]; @@ -537,6 +538,10 @@ static void ShipController(Ship *v) if (v->current_order.IsType(OT_LEAVESTATION)) { v->current_order.Free(); SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP); + /* Test if continuing forward would lead to a dead-end, moving into the dock. */ + DiagDirection exitdir = VehicleExitDir(v->direction, v->state); + TileIndex tile = TileAddByDiagDir(v->tile, exitdir); + if (TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0, exitdir)) == TRACK_BIT_NONE) goto reverse_direction; } else if (v->dest_tile != 0) { /* We have a target, let's see if we reached it... */ if (v->current_order.IsType(OT_GOTO_WAYPOINT) && @@ -634,6 +639,8 @@ reverse_direction: bool Ship::Tick() { + PerformanceAccumulator framerate(PFE_GL_SHIPS); + if (!(this->vehstatus & VS_STOPPED)) this->running_ticks++; ShipController(this); @@ -647,7 +654,7 @@ bool Ship::Tick() * @param flags type of operation. * @param e the engine to build. * @param data unused. - * @param ret[out] the vehicle that has been built. + * @param[out] ret the vehicle that has been built. * @return the cost of this operation or an error. */ CommandCost CmdBuildShip(TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **ret) @@ -670,7 +677,7 @@ CommandCost CmdBuildShip(TileIndex tile, DoCommandFlag flags, const Engine *e, u v->y_pos = y; v->z_pos = GetSlopePixelZ(x, y); - v->UpdateDeltaXY(v->direction); + v->UpdateDeltaXY(); v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL; v->spritenum = svi->image_index; diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp index 4ea887c066..135d7491c1 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -416,7 +416,7 @@ static const byte _tiletype_importance[] = { /** * Return the colour a tile would be displayed with in the small map in mode "Contour". * @param tile The tile of which we would like to get the colour. - * @param t Effective tile type of the tile (see #GetTileColours). + * @param t Effective tile type of the tile (see #SmallMapWindow::GetTileColours). * @return The colour of tile in the small map in mode "Contour" */ static inline uint32 GetSmallMapContoursPixels(TileIndex tile, TileType t) @@ -429,7 +429,7 @@ static inline uint32 GetSmallMapContoursPixels(TileIndex tile, TileType t) * Return the colour a tile would be displayed with in the small map in mode "Vehicles". * * @param tile The tile of which we would like to get the colour. - * @param t Effective tile type of the tile (see #GetTileColours). + * @param t Effective tile type of the tile (see #SmallMapWindow::GetTileColours). * @return The colour of tile in the small map in mode "Vehicles" */ static inline uint32 GetSmallMapVehiclesPixels(TileIndex tile, TileType t) @@ -442,7 +442,7 @@ static inline uint32 GetSmallMapVehiclesPixels(TileIndex tile, TileType t) * Return the colour a tile would be displayed with in the small map in mode "Industries". * * @param tile The tile of which we would like to get the colour. - * @param t Effective tile type of the tile (see #GetTileColours). + * @param t Effective tile type of the tile (see #SmallMapWindow::GetTileColours). * @return The colour of tile in the small map in mode "Industries" */ static inline uint32 GetSmallMapIndustriesPixels(TileIndex tile, TileType t) @@ -455,7 +455,7 @@ static inline uint32 GetSmallMapIndustriesPixels(TileIndex tile, TileType t) * Return the colour a tile would be displayed with in the small map in mode "Routes". * * @param tile The tile of which we would like to get the colour. - * @param t Effective tile type of the tile (see #GetTileColours). + * @param t Effective tile type of the tile (see #SmallMapWindow::GetTileColours). * @return The colour of tile in the small map in mode "Routes" */ static inline uint32 GetSmallMapRoutesPixels(TileIndex tile, TileType t) @@ -488,7 +488,7 @@ static inline uint32 GetSmallMapRoutesPixels(TileIndex tile, TileType t) * Return the colour a tile would be displayed with in the small map in mode "link stats". * * @param tile The tile of which we would like to get the colour. - * @param t Effective tile type of the tile (see #GetTileColours). + * @param t Effective tile type of the tile (see #SmallMapWindow::GetTileColours). * @return The colour of tile in the small map in mode "link stats" */ static inline uint32 GetSmallMapLinkStatsPixels(TileIndex tile, TileType t) @@ -511,7 +511,7 @@ static const uint32 _vegetation_clear_bits[] = { * Return the colour a tile would be displayed with in the smallmap in mode "Vegetation". * * @param tile The tile of which we would like to get the colour. - * @param t Effective tile type of the tile (see #GetTileColours). + * @param t Effective tile type of the tile (see #SmallMapWindow::GetTileColours). * @return The colour of tile in the smallmap in mode "Vegetation" */ static inline uint32 GetSmallMapVegetationPixels(TileIndex tile, TileType t) @@ -538,7 +538,7 @@ static inline uint32 GetSmallMapVegetationPixels(TileIndex tile, TileType t) * Return the colour a tile would be displayed with in the small map in mode "Owner". * * @param tile The tile of which we would like to get the colour. - * @param t Effective tile type of the tile (see #GetTileColours). + * @param t Effective tile type of the tile (see #SmallMapWindow::GetTileColours). * @return The colour of tile in the small map in mode "Owner" */ static inline uint32 GetSmallMapOwnerPixels(TileIndex tile, TileType t) @@ -611,7 +611,7 @@ inline Point SmallMapWindow::RemapTile(int tile_x, int tile_y) const * that tile for a point in the smallmap. * @param px Horizontal coordinate of the pixel. * @param py Vertical coordinate of the pixel. - * @param sub[out] Pixel position at the tile (0..3). + * @param[out] sub Pixel position at the tile (0..3). * @param add_sub Add current #subscroll to the position. * @return Tile being displayed at the given position relative to #scroll_x and #scroll_y. * @note The #subscroll offset is already accounted for. @@ -641,11 +641,11 @@ inline Point SmallMapWindow::PixelToTile(int px, int py, int *sub, bool add_sub) /** * Compute base parameters of the smallmap such that tile (\a tx, \a ty) starts at pixel (\a x, \a y). - * @param tx Tile x coordinate. - * @param ty Tile y coordinate. - * @param x Non-negative horizontal position in the display where the tile starts. - * @param y Non-negative vertical position in the display where the tile starts. - * @param sub [out] Value of #subscroll needed. + * @param tx Tile x coordinate. + * @param ty Tile y coordinate. + * @param x Non-negative horizontal position in the display where the tile starts. + * @param y Non-negative vertical position in the display where the tile starts. + * @param[out] sub Value of #subscroll needed. * @return #scroll_x, #scroll_y values. */ Point SmallMapWindow::ComputeScroll(int tx, int ty, int x, int y, int *sub) @@ -1351,7 +1351,7 @@ void SmallMapWindow::SelectLegendItem(int click_pos, LegendAndColour *legend, in */ void SmallMapWindow::SetOverlayCargoMask() { - uint32 cargo_mask = 0; + CargoTypes cargo_mask = 0; for (int i = 0; i != _smallmap_cargo_count; ++i) { if (_legend_linkstats[i].show_on_map) SetBit(cargo_mask, _legend_linkstats[i].type); } @@ -1559,7 +1559,7 @@ int SmallMapWindow::GetPositionOnLegend(Point pt) /* virtual */ void SmallMapWindow::OnMouseWheel(int wheel) { - if (_settings_client.gui.scrollwheel_scrolling == 0) { + if (_settings_client.gui.scrollwheel_scrolling != 2) { const NWidgetBase *wid = this->GetWidget(WID_SM_MAP); int cursor_x = _cursor.pos.x - this->left - wid->pos_x; int cursor_y = _cursor.pos.y - this->top - wid->pos_y; @@ -1628,7 +1628,7 @@ void SmallMapWindow::SetNewScroll(int sx, int sy, int sub) /* virtual */ void SmallMapWindow::OnScroll(Point delta) { - _cursor.fix_at = true; + if (_settings_client.gui.scroll_mode == VSM_VIEWPORT_RMB_FIXED || _settings_client.gui.scroll_mode == VSM_MAP_RMB_FIXED) _cursor.fix_at = true; /* While tile is at (delta.x, delta.y)? */ int sub; diff --git a/src/sound/win32_s.h b/src/sound/win32_s.h index 77906c88a3..c6c8e8d149 100644 --- a/src/sound/win32_s.h +++ b/src/sound/win32_s.h @@ -26,7 +26,7 @@ public: /** Factory for the sound driver for Windows. */ class FSoundDriver_Win32 : public DriverFactoryBase { public: - FSoundDriver_Win32() : DriverFactoryBase(Driver::DT_SOUND, 10, "win32", "Win32 WaveOut Sound Driver") {} + FSoundDriver_Win32() : DriverFactoryBase(Driver::DT_SOUND, 9, "win32", "Win32 WaveOut Sound Driver") {} /* virtual */ Driver *CreateInstance() const { return new SoundDriver_Win32(); } }; diff --git a/src/sound/xaudio2_s.cpp b/src/sound/xaudio2_s.cpp new file mode 100644 index 0000000000..60311ced20 --- /dev/null +++ b/src/sound/xaudio2_s.cpp @@ -0,0 +1,273 @@ +/* $Id$ */ + +/* + * 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 . + */ + +/** @file xaudio2_s.cpp XAudio2 sound driver. */ + +#ifdef WITH_XAUDIO2 + +#include "../stdafx.h" +#include "../openttd.h" +#include "../driver.h" +#include "../mixer.h" +#include "../debug.h" +#include "../core/alloc_func.hpp" +#include "../core/bitmath_func.hpp" +#include "../core/math_func.hpp" + +// Windows 8 SDK required for XAudio2 +#undef NTDDI_VERSION +#undef _WIN32_WINNT + +#define NTDDI_VERSION NTDDI_WIN8 +#define _WIN32_WINNT _WIN32_WINNT_WIN8 + +#include "xaudio2_s.h" + +#include +#include +#include +#include + +using Microsoft::WRL::ComPtr; + +#include "../os/windows/win32.h" +#include "../safeguards.h" + +// Definition of the "XAudio2Create" call used to initialise XAudio2 +typedef HRESULT(__stdcall *API_XAudio2Create)(_Outptr_ IXAudio2** ppXAudio2, UINT32 Flags, XAUDIO2_PROCESSOR XAudio2Processor); + +static FSoundDriver_XAudio2 iFSoundDriver_XAudio2; + +/** +* Implementation of the IXAudio2VoiceCallback interface. +* Provides buffered audio to XAudio2 from the OpenTTD mixer. +*/ +class StreamingVoiceContext : public IXAudio2VoiceCallback +{ +private: + int bufferLength; + char *buffer; + +public: + IXAudio2SourceVoice* SourceVoice; + + StreamingVoiceContext(int bufferLength) + { + this->bufferLength = bufferLength; + this->buffer = MallocT(bufferLength); + } + + virtual ~StreamingVoiceContext() + { + free(this->buffer); + } + + HRESULT SubmitBuffer() + { + // Ensure we do have a valid voice + if (this->SourceVoice == nullptr) + { + return E_FAIL; + } + + MxMixSamples(this->buffer, this->bufferLength / 4); + + XAUDIO2_BUFFER buf = { 0 }; + buf.AudioBytes = this->bufferLength; + buf.pAudioData = (const BYTE *) this->buffer; + + return SourceVoice->SubmitSourceBuffer(&buf); + } + + STDMETHOD_(void, OnVoiceProcessingPassStart)(UINT32) override + { + } + + STDMETHOD_(void, OnVoiceProcessingPassEnd)() override + { + } + + STDMETHOD_(void, OnStreamEnd)() override + { + } + + STDMETHOD_(void, OnBufferStart)(void*) override + { + } + + STDMETHOD_(void, OnBufferEnd)(void*) override + { + SubmitBuffer(); + } + + STDMETHOD_(void, OnLoopEnd)(void*) override + { + } + + STDMETHOD_(void, OnVoiceError)(void*, HRESULT) override + { + } +}; + +static HMODULE _xaudio_dll_handle; +static IXAudio2SourceVoice* _source_voice = nullptr; +static IXAudio2MasteringVoice* _mastering_voice = nullptr; +static ComPtr _xaudio2; +static StreamingVoiceContext* _voice_context = nullptr; + +/** +* Initialises the XAudio2 driver. +* +* @param parm Driver parameters. +* @return An error message if unsuccessful, or NULL otherwise. +* +*/ +const char *SoundDriver_XAudio2::Start(const char * const *parm) +{ + HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); + + if (FAILED(hr)) + { + DEBUG(driver, 0, "xaudio2_s: CoInitializeEx failed (%08x)", hr); + return "Failed to initialise COM"; + } + + _xaudio_dll_handle = LoadLibraryA(XAUDIO2_DLL_A); + + if (_xaudio_dll_handle == NULL) + { + CoUninitialize(); + + DEBUG(driver, 0, "xaudio2_s: Unable to load " XAUDIO2_DLL_A); + return "Failed to load XAudio2 DLL"; + } + + API_XAudio2Create xAudio2Create = (API_XAudio2Create) GetProcAddress(_xaudio_dll_handle, "XAudio2Create"); + + if (xAudio2Create == NULL) + { + FreeLibrary(_xaudio_dll_handle); + CoUninitialize(); + + DEBUG(driver, 0, "xaudio2_s: Unable to find XAudio2Create function in DLL"); + return "Failed to load XAudio2 DLL"; + } + + // Create the XAudio engine + UINT32 flags = 0; + hr = xAudio2Create(_xaudio2.GetAddressOf(), flags, XAUDIO2_DEFAULT_PROCESSOR); + + if (FAILED(hr)) + { + FreeLibrary(_xaudio_dll_handle); + CoUninitialize(); + + DEBUG(driver, 0, "xaudio2_s: XAudio2Create failed (%08x)", hr); + return "Failed to inititialise the XAudio2 engine"; + } + + // Create a mastering voice + hr = _xaudio2->CreateMasteringVoice(&_mastering_voice); + + if (FAILED(hr)) + { + _xaudio2.Reset(); + FreeLibrary(_xaudio_dll_handle); + CoUninitialize(); + + DEBUG(driver, 0, "xaudio2_s: CreateMasteringVoice failed (%08x)", hr); + return "Failed to create a mastering voice"; + } + + // Create a source voice to stream our audio + WAVEFORMATEX wfex; + + wfex.wFormatTag = WAVE_FORMAT_PCM; + wfex.nChannels = 2; + wfex.wBitsPerSample = 16; + wfex.nSamplesPerSec = GetDriverParamInt(parm, "hz", 44100); + wfex.nBlockAlign = (wfex.nChannels * wfex.wBitsPerSample) / 8; + wfex.nAvgBytesPerSec = wfex.nSamplesPerSec * wfex.nBlockAlign; + + // Limit buffer size to prevent overflows + int bufsize = GetDriverParamInt(parm, "bufsize", 8192); + bufsize = min(bufsize, UINT16_MAX); + + _voice_context = new StreamingVoiceContext(bufsize * 4); + + if (_voice_context == nullptr) + { + _mastering_voice->DestroyVoice(); + _xaudio2.Reset(); + FreeLibrary(_xaudio_dll_handle); + CoUninitialize(); + + return "Failed to create streaming voice context"; + } + + hr = _xaudio2->CreateSourceVoice(&_source_voice, &wfex, 0, 1.0f, _voice_context); + + if (FAILED(hr)) + { + _mastering_voice->DestroyVoice(); + _xaudio2.Reset(); + FreeLibrary(_xaudio_dll_handle); + CoUninitialize(); + + DEBUG(driver, 0, "xaudio2_s: CreateSourceVoice failed (%08x)", hr); + return "Failed to create a source voice"; + } + + _voice_context->SourceVoice = _source_voice; + hr = _source_voice->Start(0, 0); + + if (FAILED(hr)) + { + DEBUG(driver, 0, "xaudio2_s: _source_voice->Start failed (%08x)", hr); + + Stop(); + return "Failed to start the source voice"; + } + + MxInitialize(wfex.nSamplesPerSec); + + // Submit the first buffer + hr = _voice_context->SubmitBuffer(); + + if (FAILED(hr)) + { + DEBUG(driver, 0, "xaudio2_s: _voice_context->SubmitBuffer failed (%08x)", hr); + + Stop(); + return "Failed to submit the first audio buffer"; + } + + return NULL; +} + +/** +* Terminates the XAudio2 driver. +*/ +void SoundDriver_XAudio2::Stop() +{ + // Clean up XAudio2 + _source_voice->DestroyVoice(); + + delete _voice_context; + _voice_context = nullptr; + + _mastering_voice->DestroyVoice(); + + _xaudio2.Reset(); + + FreeLibrary(_xaudio_dll_handle); + CoUninitialize(); +} + +#endif diff --git a/src/sound/xaudio2_s.h b/src/sound/xaudio2_s.h new file mode 100644 index 0000000000..2385f49ee2 --- /dev/null +++ b/src/sound/xaudio2_s.h @@ -0,0 +1,33 @@ +/* $Id$ */ + +/* + * 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 . + */ + +/** @file xaudio2_s.h Base for XAudio2 sound handling. */ + +#ifndef SOUND_XAUDIO2_H +#define SOUND_XAUDIO2_H + +#include "sound_driver.hpp" + +/** Implementation of the XAudio2 sound driver. */ +class SoundDriver_XAudio2 : public SoundDriver { +public: + /* virtual */ const char *Start(const char * const *param); + + /* virtual */ void Stop(); + /* virtual */ const char *GetName() const { return "xaudio2"; } +}; + +/** Factory for the XAudio2 sound driver. */ +class FSoundDriver_XAudio2 : public DriverFactoryBase { +public: + FSoundDriver_XAudio2() : DriverFactoryBase(Driver::DT_SOUND, 10, "xaudio2", "XAudio2 Sound Driver") {} + /* virtual */ Driver *CreateInstance() const { return new SoundDriver_XAudio2(); } +}; + +#endif /* SOUND_XAUDIO2_H */ diff --git a/src/station_base.h b/src/station_base.h index af4d206ba0..086d4332c5 100644 --- a/src/station_base.h +++ b/src/station_base.h @@ -470,7 +470,7 @@ public: byte last_vehicle_type; std::list loading_vehicles; GoodsEntry goods[NUM_CARGO]; ///< Goods at this station - uint32 always_accepted; ///< Bitmask of always accepted cargo types (by houses, HQs, industry tiles when industry doesn't accept cargo) + CargoTypes always_accepted; ///< Bitmask of always accepted cargo types (by houses, HQs, industry tiles when industry doesn't accept cargo) IndustryVector industries_near; ///< Cached list of industries near the station that can accept cargo, @see DeliverGoodsToIndustry() @@ -516,7 +516,7 @@ private: public: /** * Construct the iterator. - * @param ta Area, i.e. begin point and width/height of to-be-iterated area. + * @param st Station the airport is part of. */ AirportTileIterator(const Station *st) : OrthogonalTileIterator(st->airport), st(st) { diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 5fd865a0db..16f135df25 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -89,25 +89,25 @@ bool IsHangar(TileIndex t) } /** - * Look for a station around the given tile area. + * Look for a station owned by the given company around the given tile area. * @param ta the area to search over - * @param closest_station the closest station found so far + * @param closest_station the closest owned station found so far + * @param company the company whose stations to look for * @param st to 'return' the found station * @return Succeeded command (if zero or one station found) or failed command (for two or more stations found). */ template -CommandCost GetStationAround(TileArea ta, StationID closest_station, T **st) +CommandCost GetStationAround(TileArea ta, StationID closest_station, CompanyID company, T **st) { ta.tile -= TileDiffXY(1, 1); ta.w += 2; ta.h += 2; - /* check around to see if there's any stations there */ + /* check around to see if there are any stations there owned by the company */ TILE_AREA_LOOP(tile_cur, ta) { if (IsTileType(tile_cur, MP_STATION)) { StationID t = GetStationIndex(tile_cur); - if (!T::IsValidID(t)) continue; - + if (!T::IsValidID(t) || Station::Get(t)->owner != company) continue; if (closest_station == INVALID_STATION) { closest_station = t; } else if (closest_station != t) { @@ -440,12 +440,12 @@ void UpdateAllStationVirtCoords() * @param st Station to query * @return the expected mask */ -static uint GetAcceptanceMask(const Station *st) +static CargoTypes GetAcceptanceMask(const Station *st) { - uint mask = 0; + CargoTypes mask = 0; for (CargoID i = 0; i < NUM_CARGO; i++) { - if (HasBit(st->goods[i].status, GoodsEntry::GES_ACCEPTANCE)) mask |= 1 << i; + if (HasBit(st->goods[i].status, GoodsEntry::GES_ACCEPTANCE)) SetBit(mask, i); } return mask; } @@ -524,7 +524,7 @@ CargoArray GetProductionAroundTiles(TileIndex tile, int w, int h, int rad) * @param rad Search radius in addition to given area * @param always_accepted bitmask of cargo accepted by houses and headquarters; can be NULL */ -CargoArray GetAcceptanceAroundTiles(TileIndex tile, int w, int h, int rad, uint32 *always_accepted) +CargoArray GetAcceptanceAroundTiles(TileIndex tile, int w, int h, int rad, CargoTypes *always_accepted) { CargoArray acceptance; if (always_accepted != NULL) *always_accepted = 0; @@ -562,7 +562,7 @@ CargoArray GetAcceptanceAroundTiles(TileIndex tile, int w, int h, int rad, uint3 void UpdateStationAcceptance(Station *st, bool show_msg) { /* old accepted goods types */ - uint old_acc = GetAcceptanceMask(st); + CargoTypes old_acc = GetAcceptanceMask(st); /* And retrieve the acceptance. */ CargoArray acceptance; @@ -595,7 +595,7 @@ void UpdateStationAcceptance(Station *st, bool show_msg) } /* Only show a message in case the acceptance was actually changed. */ - uint new_acc = GetAcceptanceMask(st); + CargoTypes new_acc = GetAcceptanceMask(st); if (old_acc == new_acc) return; /* show a message to report that the acceptance was changed? */ @@ -662,7 +662,7 @@ static void UpdateStationSignCoord(BaseStation *st) /** * Common part of building various station parts and possibly attaching them to an existing one. - * @param [in,out] st Station to attach to + * @param[in,out] st Station to attach to * @param flags Command flags * @param reuse Whether to try to reuse a deleted station (gray sign) if possible * @param area Area occupied by the new part @@ -676,7 +676,7 @@ static CommandCost BuildStationPart(Station **st, DoCommandFlag flags, bool reus if (*st != NULL) { if ((*st)->owner != _current_company) { - return_cmd_error(STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION); + return_cmd_error(CMD_ERROR); } CommandCost ret = (*st)->rect.BeforeAddRect(area.tile, area.w, area.h, StationRect::ADD_TEST); @@ -960,6 +960,8 @@ static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags num_roadbits += CountBits(GetRoadBits(cur_tile, ROADTYPE_ROAD)); } + if (GetDisallowedRoadDirections(cur_tile) != DRD_NONE) return_cmd_error(STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD); + /* There is a tram, check if we can build road+tram stop over it. */ if (HasBit(cur_rts, ROADTYPE_TRAM)) { Owner tram_owner = GetRoadOwner(cur_tile, ROADTYPE_TRAM); @@ -1103,8 +1105,8 @@ CommandCost FindJoiningBaseStation(StationID existing_station, StationID station } if (check_surrounding) { - /* Make sure there are no similar stations around us. */ - CommandCost ret = GetStationAround(ta, existing_station, st); + /* Make sure there is no more than one other station around us that is owned by us. */ + CommandCost ret = GetStationAround(ta, existing_station, _current_company, st); if (ret.Failed()) return ret; } @@ -1171,8 +1173,8 @@ static void RestoreTrainReservation(Train *v) * @param tile_org northern most position of station dragging/placement * @param flags operation to perform * @param p1 various bitstuffed elements - * - p1 = (bit 0- 3) - railtype - * - p1 = (bit 4) - orientation (Axis) + * - p1 = (bit 0- 5) - railtype + * - p1 = (bit 6) - orientation (Axis) * - p1 = (bit 8-15) - number of tracks * - p1 = (bit 16-23) - platform length * - p1 = (bit 24) - allow stations directly adjacent to other stations. @@ -1186,8 +1188,8 @@ static void RestoreTrainReservation(Train *v) CommandCost CmdBuildRailStation(TileIndex tile_org, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { /* Unpack parameters */ - RailType rt = Extract(p1); - Axis axis = Extract(p1); + RailType rt = Extract(p1); + Axis axis = Extract(p1); byte numtracks = GB(p1, 8, 8); byte plat_len = GB(p1, 16, 8); bool adjacent = HasBit(p1, 24); @@ -2622,9 +2624,9 @@ const DrawTileSprites *GetStationTileLayout(StationType st, byte gfx) * Check whether a sprite is a track sprite, which can be replaced by a non-track ground sprite and a rail overlay. * If the ground sprite is suitable, \a ground is replaced with the new non-track ground sprite, and \a overlay_offset * is set to the overlay to draw. - * @param ti Positional info for the tile to decide snowyness etc. May be NULL. - * @param [in,out] ground Groundsprite to draw. - * @param [out] overlay_offset Overlay to draw. + * @param ti Positional info for the tile to decide snowyness etc. May be NULL. + * @param[in,out] ground Groundsprite to draw. + * @param[out] overlay_offset Overlay to draw. * @return true if overlay can be drawn. */ bool SplitGroundSpriteForOverlay(const TileInfo *ti, SpriteID *ground, RailTrackOffset *overlay_offset) @@ -3186,7 +3188,7 @@ static VehicleEnterTileStatus VehicleEnter_Station(Vehicle *v, TileIndex tile, i void TriggerWatchedCargoCallbacks(Station *st) { /* Collect cargoes accepted since the last big tick. */ - uint cargoes = 0; + CargoTypes cargoes = 0; for (CargoID cid = 0; cid < NUM_CARGO; cid++) { if (HasBit(st->goods[cid].status, GoodsEntry::GES_ACCEPTED_BIGTICK)) SetBit(cargoes, cid); } diff --git a/src/station_func.h b/src/station_func.h index f33dbd21fb..9748297f21 100644 --- a/src/station_func.h +++ b/src/station_func.h @@ -28,7 +28,7 @@ void ShowStationViewWindow(StationID station); void UpdateAllStationVirtCoords(); CargoArray GetProductionAroundTiles(TileIndex tile, int w, int h, int rad); -CargoArray GetAcceptanceAroundTiles(TileIndex tile, int w, int h, int rad, uint32 *always_accepted = NULL); +CargoArray GetAcceptanceAroundTiles(TileIndex tile, int w, int h, int rad, CargoTypes *always_accepted = NULL); void UpdateStationAcceptance(Station *st, bool show_msg); diff --git a/src/station_gui.cpp b/src/station_gui.cpp index aa20170180..3f64b139ac 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -56,7 +56,7 @@ int DrawStationCoverageAreaText(int left, int right, int top, StationCoverageType sct, int rad, bool supplies) { TileIndex tile = TileVirtXY(_thd.pos.x, _thd.pos.y); - uint32 cargo_mask = 0; + CargoTypes cargo_mask = 0; if (_thd.drawstyle == HT_RECT && tile < MapSize()) { CargoArray cargoes; if (supplies) { @@ -156,8 +156,8 @@ protected: static Listing last_sorting; static byte facilities; // types of stations of interest static bool include_empty; // whether we should include stations without waiting cargo - static const uint32 cargo_filter_max; - static uint32 cargo_filter; // bitmap of cargo types to include + static const CargoTypes cargo_filter_max; + static CargoTypes cargo_filter; // bitmap of cargo types to include static const Station *last_station; /* Constants for sorting stations */ @@ -654,8 +654,8 @@ public: Listing CompanyStationsWindow::last_sorting = {false, 0}; byte CompanyStationsWindow::facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK; bool CompanyStationsWindow::include_empty = true; -const uint32 CompanyStationsWindow::cargo_filter_max = UINT32_MAX; -uint32 CompanyStationsWindow::cargo_filter = UINT32_MAX; +const CargoTypes CompanyStationsWindow::cargo_filter_max = ALL_CARGOTYPES; +CargoTypes CompanyStationsWindow::cargo_filter = ALL_CARGOTYPES; const Station *CompanyStationsWindow::last_station = NULL; /* Availible station sorting functions */ @@ -802,7 +802,6 @@ static const NWidgetPart _nested_station_view_widgets[] = { * @param left left most coordinate to draw on * @param right right most coordinate to draw on * @param y y coordinate - * @param width the width of the view */ static void DrawCargoIcons(CargoID i, uint waiting, int left, int right, int y) { @@ -1799,7 +1798,7 @@ struct StationViewWindow : public Window { { const Station *st = Station::Get(this->window_number); - uint32 cargo_mask = 0; + CargoTypes cargo_mask = 0; for (CargoID i = 0; i < NUM_CARGO; i++) { if (HasBit(st->goods[i].status, GoodsEntry::GES_ACCEPTANCE)) SetBit(cargo_mask, i); } @@ -2208,7 +2207,7 @@ static const T *FindStationsNearby(TileArea ta, bool distant_join) if (distant_join && min(ta.w, ta.h) >= _settings_game.station.station_spread) return NULL; uint max_dist = distant_join ? _settings_game.station.station_spread - min(ta.w, ta.h) : 1; - TileIndex tile = TILE_ADD(ctx.tile, TileOffsByDir(DIR_N)); + TileIndex tile = TileAddByDir(ctx.tile, DIR_N); CircularTileSearch(&tile, max_dist, ta.w, ta.h, AddNearbyStation, &ctx); return NULL; diff --git a/src/station_map.h b/src/station_map.h index 7ca9bd7204..e591787e3b 100644 --- a/src/station_map.h +++ b/src/station_map.h @@ -542,6 +542,7 @@ static inline void MakeStation(TileIndex t, Owner o, StationID sid, StationType SB(_me[t].m6, 2, 1, 0); SB(_me[t].m6, 3, 3, st); _me[t].m7 = 0; + _me[t].m8 = 0; } /** diff --git a/src/stdafx.h b/src/stdafx.h index a145d645c2..c76cb6c2b2 100644 --- a/src/stdafx.h +++ b/src/stdafx.h @@ -100,12 +100,6 @@ #define strcasecmp stricmp #endif -#if defined(PSP) - #include - #include - #include -#endif - #if defined(SUNOS) || defined(HPUX) #include #endif @@ -134,20 +128,11 @@ #define CLIB_USERGROUP_PROTOS_H #endif /* __MORPHOS__ */ -#if defined(PSP) - /* PSP can only have 10 file-descriptors open at any given time, but this - * switch only limits reads via the Fio system. So keep 2 fds free for things - * like saving a game. */ - #define LIMITED_FDS 8 - #define printf pspDebugScreenPrintf -#endif /* PSP */ - /* Stuff for GCC */ #if defined(__GNUC__) || defined(__clang__) #define NORETURN __attribute__ ((noreturn)) #define CDECL #define __int64 long long - #define GCC_PACK __attribute__((packed)) /* Warn about functions using 'printf' format syntax. First argument determines which parameter * is the format string, second argument is start of values passed to printf. */ #define WARN_FORMAT(string, args) __attribute__ ((format (printf, string, args))) @@ -168,7 +153,6 @@ #if defined(__WATCOMC__) #define NORETURN #define CDECL - #define GCC_PACK #define WARN_FORMAT(string, args) #define FINAL #define FALLTHROUGH @@ -179,7 +163,7 @@ #include // alloca() #endif -#if defined(WIN32) +#if defined(_WIN32) #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #endif @@ -199,9 +183,7 @@ #define NTDDI_VERSION NTDDI_WIN2K // Windows 2000 #define _WIN32_WINNT 0x0500 // Windows 2000 #define _WIN32_WINDOWS 0x400 // Windows 95 - #if !defined(WINCE) - #define WINVER 0x0400 // Windows NT 4.0 / Windows 95 - #endif + #define WINVER 0x0400 // Windows NT 4.0 / Windows 95 #define _WIN32_IE_ 0x0401 // 4.01 (win98 and NT4SP5+) #endif #define NOMINMAX // Disable min/max macros in windows.h. @@ -235,11 +217,7 @@ #define inline __forceinline #endif - #if !defined(WINCE) - #define CDECL _cdecl - #endif - - #define GCC_PACK + #define CDECL _cdecl #define WARN_FORMAT(string, args) #define FINAL sealed @@ -250,39 +228,35 @@ #define FALLTHROUGH #endif - #if defined(WINCE) - int CDECL vsnprintf(char *str, size_t size, const char *format, va_list ap); - #endif - - #if defined(WIN32) && !defined(_WIN64) && !defined(WIN64) +# if defined(_WIN32) && !defined(_WIN64) #if !defined(_W64) #define _W64 #endif typedef _W64 int INT_PTR, *PINT_PTR; typedef _W64 unsigned int UINT_PTR, *PUINT_PTR; - #endif /* WIN32 && !_WIN64 && !WIN64 */ +# endif /* _WIN32 && !_WIN64 */ - #if defined(_WIN64) || defined(WIN64) +# if defined(_WIN64) #define fseek _fseeki64 - #endif /* _WIN64 || WIN64 */ +# endif /* _WIN64 */ - /* This is needed to zlib uses the stdcall calling convention on visual studio */ - #if defined(WITH_ZLIB) || defined(WITH_PNG) - #if !defined(ZLIB_WINAPI) - #define ZLIB_WINAPI - #endif - #endif + /* zlib from vcpkg use cdecl calling convention without enforcing it in the headers */ +# if defined(WITH_ZLIB) +# if !defined(ZEXPORT) +# define ZEXPORT CDECL +# endif +# endif - #if defined(WINCE) - #define strcasecmp _stricmp - #define strncasecmp _strnicmp - #undef DEBUG - #else - #define strcasecmp stricmp - #define strncasecmp strnicmp - #endif + /* freetype from vcpkg use cdecl calling convention without enforcing it in the headers */ +# if defined(WITH_FREETYPE) +# if !defined(FT_EXPORT) +# define FT_EXPORT( x ) extern "C" x CDECL +# endif +# endif + #define strcasecmp stricmp + #define strncasecmp strnicmp #define strtoull _strtoui64 /* MSVC doesn't have these :( */ @@ -300,35 +274,28 @@ #define SIGBUS SIGNOFP #endif -#if defined(WINCE) - #define stredup _stredup -#endif /* WINCE */ - /* NOTE: the string returned by these functions is only valid until the next * call to the same function and is not thread- or reentrancy-safe */ #if !defined(STRGEN) && !defined(SETTINGSGEN) - #if defined(WIN32) || defined(WIN64) +# if defined(_WIN32) char *getcwd(char *buf, size_t size); #include #include - /* XXX - WinCE without MSVCRT doesn't support wfopen, so it seems */ - #if !defined(WINCE) - namespace std { using ::_tfopen; } - #define fopen(file, mode) _tfopen(OTTD2FS(file), _T(mode)) - #define unlink(file) _tunlink(OTTD2FS(file)) - #endif /* WINCE */ + namespace std { using ::_tfopen; } + #define fopen(file, mode) _tfopen(OTTD2FS(file), _T(mode)) + #define unlink(file) _tunlink(OTTD2FS(file)) const char *FS2OTTD(const TCHAR *name); const TCHAR *OTTD2FS(const char *name, bool console_cp = false); - #else +# else #define fopen(file, mode) fopen(OTTD2FS(file), mode) const char *FS2OTTD(const char *name); const char *OTTD2FS(const char *name); - #endif /* WIN32 */ +# endif /* _WIN32 */ #endif /* STRGEN || SETTINGSGEN */ -#if defined(WIN32) || defined(WIN64) || defined(__OS2__) && !defined(__INNOTEK_LIBC__) +#if defined(_WIN32) || defined(__OS2__) && !defined(__INNOTEK_LIBC__) #define PATHSEP "\\" #define PATHSEPCHAR '\\' #else @@ -336,6 +303,16 @@ #define PATHSEPCHAR '/' #endif +#if defined(_MSC_VER) || defined(__WATCOMC__) +# define PACK_N(type_dec, n) __pragma(pack(push, n)) type_dec; __pragma(pack(pop)) +#elif defined(__MINGW32__) +# define PRAGMA(x) _Pragma(#x) +# define PACK_N(type_dec, n) PRAGMA(pack(push, n)) type_dec; PRAGMA(pack(pop)) +#else +# define PACK_N(type_dec, n) type_dec __attribute__((__packed__, aligned(n))) +#endif +#define PACK(type_dec) PACK_N(type_dec, 1) + /* MSVCRT of course has to have a different syntax for long long *sigh* */ #if defined(_MSC_VER) || defined(__MINGW32__) #define OTTD_PRINTF64 "%I64d" diff --git a/src/strgen/strgen.cpp b/src/strgen/strgen.cpp index fa29424658..44cbd127a1 100644 --- a/src/strgen/strgen.cpp +++ b/src/strgen/strgen.cpp @@ -21,14 +21,14 @@ #include #include -#if (!defined(WIN32) && !defined(WIN64)) || defined(__CYGWIN__) +#if !defined(_WIN32) || defined(__CYGWIN__) #include #include #endif -#if defined WIN32 || defined __WATCOMC__ +#if defined(_WIN32) || defined(__WATCOMC__) #include -#endif /* WIN32 || __WATCOMC__ */ +#endif /* _WIN32 || __WATCOMC__ */ #ifdef __MORPHOS__ #ifdef stderr @@ -215,7 +215,10 @@ bool CompareFiles(const char *n1, const char *n2) if (f2 == NULL) return false; FILE *f1 = fopen(n1, "rb"); - if (f1 == NULL) error("can't open %s", n1); + if (f1 == NULL) { + fclose(f2); + error("can't open %s", n1); + } size_t l1, l2; do { @@ -330,9 +333,9 @@ struct HeaderFileWriter : HeaderWriter, FileWriter { unlink(this->filename); } else { /* else rename tmp.xxx into filename */ - #if defined(WIN32) || defined(WIN64) +# if defined(_WIN32) unlink(this->real_filename); - #endif +# endif if (rename(this->filename, this->real_filename) == -1) error("rename() failed"); } } @@ -374,7 +377,7 @@ static inline void ottd_mkdir(const char *directory) { /* Ignore directory creation errors; they'll surface later on, and most * of the time they are 'directory already exists' errors anyhow. */ -#if defined(WIN32) || defined(__WATCOMC__) +#if defined(_WIN32) || defined(__WATCOMC__) mkdir(directory); #else mkdir(directory, 0755); diff --git a/src/strgen/strgen_base.cpp b/src/strgen/strgen_base.cpp index 385ca72b2a..8d46b1b271 100644 --- a/src/strgen/strgen_base.cpp +++ b/src/strgen/strgen_base.cpp @@ -85,7 +85,7 @@ void LangString::FreeTranslation() /** * Create a new string data container. - * @param max_strings The maximum number of strings. + * @param tabs The maximum number of strings. */ StringData::StringData(size_t tabs) : tabs(tabs), max_strings(tabs * TAB_SIZE) { diff --git a/src/string.cpp b/src/string.cpp index 6306e6f75e..ae1b556aff 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -25,6 +25,18 @@ #include // required by vsnprintf implementation for MSVC #endif +#ifdef _WIN32 +#include "os/windows/win32.h" +#endif + +#ifdef WITH_UNISCRIBE +#include "os/windows/string_uniscribe.h" +#endif + +#if defined(WITH_COCOA) +#include "os/macosx/string_osx.h" +#endif + #ifdef WITH_ICU_SORT /* Required by strnatcmp. */ #include @@ -162,7 +174,7 @@ void str_fix_scc_encoded(char *str, const char *last) if ((len == 0 && str + 4 > last) || str + len > last) break; WChar c; - len = Utf8Decode(&c, str); + Utf8Decode(&c, str); if (c == '\0') break; if (c == 0xE028 || c == 0xE02A) { @@ -343,12 +355,11 @@ bool IsValidChar(WChar key, CharSetFilter afilter) case CS_NUMERAL_SPACE: return (key >= '0' && key <= '9') || key == ' '; case CS_ALPHA: return IsPrintable(key) && !(key >= '0' && key <= '9'); case CS_HEXADECIMAL: return (key >= '0' && key <= '9') || (key >= 'a' && key <= 'f') || (key >= 'A' && key <= 'F'); + default: NOT_REACHED(); } - - return false; } -#ifdef WIN32 +#ifdef _WIN32 #if defined(_MSC_VER) && _MSC_VER < 1900 /** * Almost POSIX compliant implementation of \c vsnprintf for VC compiler. @@ -384,7 +395,7 @@ int CDECL vsnprintf(char *str, size_t size, const char *format, va_list ap) } #endif /* _MSC_VER */ -#endif /* WIN32 */ +#endif /* _WIN32 */ /** * Safer implementation of snprintf; same as snprintf except: @@ -572,20 +583,37 @@ int strnatcmp(const char *s1, const char *s2, bool ignore_garbage_at_front) s1 = SkipGarbage(s1); s2 = SkipGarbage(s2); } + #ifdef WITH_ICU_SORT if (_current_collator != NULL) { UErrorCode status = U_ZERO_ERROR; int result = _current_collator->compareUTF8(s1, s2, status); if (U_SUCCESS(status)) return result; } - #endif /* WITH_ICU_SORT */ +#if defined(_WIN32) && !defined(STRGEN) && !defined(SETTINGSGEN) + int res = OTTDStringCompare(s1, s2); + if (res != 0) return res - 2; // Convert to normal C return values. +#endif + +#if defined(WITH_COCOA) && !defined(STRGEN) && !defined(SETTINGSGEN) + int res = MacOSStringCompare(s1, s2); + if (res != 0) return res - 2; // Convert to normal C return values. +#endif + /* Do a normal comparison if ICU is missing or if we cannot create a collator. */ return strcasecmp(s1, s2); } -#ifdef WITH_ICU_SORT +#ifdef WITH_UNISCRIBE + +/* static */ StringIterator *StringIterator::Create() +{ + return new UniscribeStringIterator(); +} + +#elif defined(WITH_ICU_SORT) #include #include @@ -846,9 +874,19 @@ public: } }; +#if defined(WITH_COCOA) && !defined(STRGEN) && !defined(SETTINGSGEN) +/* static */ StringIterator *StringIterator::Create() +{ + StringIterator *i = OSXStringIterator::Create(); + if (i != NULL) return i; + + return new DefaultStringIterator(); +} +#else /* static */ StringIterator *StringIterator::Create() { return new DefaultStringIterator(); } +#endif /* defined(WITH_COCOA) && !defined(STRGEN) && !defined(SETTINGSGEN) */ #endif diff --git a/src/string_base.h b/src/string_base.h index e1eaed3496..02856cf1c6 100644 --- a/src/string_base.h +++ b/src/string_base.h @@ -41,9 +41,9 @@ public: /** * Change the current string cursor. - * @param p New cursor position. + * @param pos New cursor position. * @return Actual new cursor position at the next valid character boundary. - * @pre p has to be inside the current string. + * @pre pos has to be inside the current string. */ virtual size_t SetCurPosition(size_t pos) = 0; diff --git a/src/strings.cpp b/src/strings.cpp index e1e352f5df..2cc3a23be2 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -56,7 +56,7 @@ icu::Collator *_current_collator = NULL; ///< Collator for the language #endif /* WITH_ICU_SORT */ static uint64 _global_string_params_data[20]; ///< Global array of string parameters. To access, use #SetDParam. -static WChar _global_string_params_type[20]; ///< Type of parameters stored in #_decode_parameters +static WChar _global_string_params_type[20]; ///< Type of parameters stored in #_global_string_params StringParameters _global_string_params(_global_string_params_data, 20, _global_string_params_type); /** Reset the type array. */ @@ -760,11 +760,10 @@ uint ConvertDisplaySpeedToKmhishSpeed(uint speed) } /** * Parse most format codes within a string and write the result to a buffer. - * @param buff The buffer to write the final string to. - * @param str The original string with format codes. - * @param args Pointer to extra arguments used by various string codes. - * @param case_index - * @param last Pointer to just past the end of the buff array. + * @param buff The buffer to write the final string to. + * @param str_arg The original string with format codes. + * @param args Pointer to extra arguments used by various string codes. + * @param last Pointer to just past the end of the buff array. * @param dry_run True when the argt array is not yet initialized. */ static char *FormatString(char *buff, const char *str_arg, StringParameters *args, const char *last, uint case_index, bool game_script, bool dry_run) @@ -819,7 +818,6 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg sub_args.ClearTypeInformation(); memset(sub_args_need_free, 0, sizeof(sub_args_need_free)); - const char *s = str; char *p; uint32 stringid = strtoul(str, &p, 16); if (*p != ':' && *p != '\0') { @@ -838,7 +836,7 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg int i = 0; while (*p != '\0' && i < 20) { uint64 param; - s = ++p; + const char *s = ++p; /* Find the next value */ bool instring = false; @@ -1147,7 +1145,7 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg } case SCC_CARGO_LIST: { // {CARGO_LIST} - uint32 cmask = args->GetInt32(SCC_CARGO_LIST); + CargoTypes cmask = args->GetInt64(SCC_CARGO_LIST); bool first = true; const CargoSpec *cs; @@ -1788,6 +1786,16 @@ bool ReadLanguagePack(const LanguageMetadata *lang) strecpy(_config_language_file, c_file, lastof(_config_language_file)); SetCurrentGrfLangID(_current_language->newgrflangid); +#ifdef _WIN32 + extern void Win32SetCurrentLocaleName(const char *iso_code); + Win32SetCurrentLocaleName(_current_language->isocode); +#endif + +#ifdef WITH_COCOA + extern void MacOSSetCurrentLocaleName(const char *iso_code); + MacOSSetCurrentLocaleName(_current_language->isocode); +#endif + #ifdef WITH_ICU_SORT /* Delete previous collator. */ if (_current_collator != NULL) { @@ -1829,7 +1837,7 @@ bool ReadLanguagePack(const LanguageMetadata *lang) /* Win32 implementation in win32.cpp. * OS X implementation in os/macosx/macos.mm. */ -#if !(defined(WIN32) || defined(__APPLE__)) +#if !(defined(_WIN32) || defined(__APPLE__)) /** * Determine the current charset based on the environment * First check some default values, after this one we passed ourselves @@ -1857,7 +1865,7 @@ const char *GetCurrentLocale(const char *param) } #else const char *GetCurrentLocale(const char *param); -#endif /* !(defined(WIN32) || defined(__APPLE__)) */ +#endif /* !(defined(_WIN32) || defined(__APPLE__)) */ int CDECL StringIDSorter(const StringID *a, const StringID *b) { @@ -1998,7 +2006,7 @@ const char *GetCurrentLanguageIsoCode() /** * Check whether there are glyphs missing in the current language. - * @param Pointer to an address for storing the text pointer. + * @param[out] str Pointer to an address for storing the text pointer. * @return If glyphs are missing, return \c true, else return \c false. * @post If \c true is returned and str is not NULL, *str points to a string that is found to contain at least one missing glyph. */ @@ -2130,7 +2138,7 @@ void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher) /* Update the font with cache */ LoadStringWidthTable(searcher->Monospace()); -#if !defined(WITH_ICU_LAYOUT) +#if !defined(WITH_ICU_LAYOUT) && !defined(WITH_UNISCRIBE) && !defined(WITH_COCOA) /* * For right-to-left languages we need the ICU library. If * we do not have support for that library we warn the user diff --git a/src/subsidy.cpp b/src/subsidy.cpp index 62b463ced3..d1fda0f0ac 100644 --- a/src/subsidy.cpp +++ b/src/subsidy.cpp @@ -334,7 +334,7 @@ bool FindSubsidyTownCargoRoute() /* Select a random town. */ const Town *src_town = Town::GetRandom(); - uint32 town_cargo_produced = src_town->cargo_produced; + CargoTypes town_cargo_produced = src_town->cargo_produced; /* Passenger subsidies are not handled here. */ ClrBit(town_cargo_produced, CT_PASSENGERS); @@ -383,15 +383,21 @@ bool FindSubsidyIndustryCargoRoute() CargoID cid; /* Randomize cargo type */ - if (src_ind->produced_cargo[1] != CT_INVALID && HasBit(Random(), 0)) { - cid = src_ind->produced_cargo[1]; - trans = src_ind->last_month_pct_transported[1]; - total = src_ind->last_month_production[1]; - } else { - cid = src_ind->produced_cargo[0]; - trans = src_ind->last_month_pct_transported[0]; - total = src_ind->last_month_production[0]; + int num_cargos = 0; + uint cargo_index; + for (cargo_index = 0; cargo_index < lengthof(src_ind->produced_cargo); cargo_index++) { + if (src_ind->produced_cargo[cargo_index] != CT_INVALID) num_cargos++; } + if (num_cargos == 0) return false; // industry produces nothing + int cargo_num = RandomRange(num_cargos) + 1; + for (cargo_index = 0; cargo_index < lengthof(src_ind->produced_cargo); cargo_index++) { + if (src_ind->produced_cargo[cargo_index] != CT_INVALID) cargo_num--; + if (cargo_num == 0) break; + } + assert(cargo_num == 0); // indicates loop didn't break as intended + cid = src_ind->produced_cargo[cargo_index]; + trans = src_ind->last_month_pct_transported[cargo_index]; + total = src_ind->last_month_production[cargo_index]; /* Quit if no production in this industry * or if the pct transported is already large enough @@ -435,14 +441,11 @@ bool FindSubsidyCargoDestination(CargoID cid, SourceType src_type, SourceID src) case ST_INDUSTRY: { /* Select a random industry. */ const Industry *dst_ind = Industry::GetRandom(); + if (dst_ind == NULL) return false; /* The industry must accept the cargo */ - if (dst_ind == NULL || - (cid != dst_ind->accepts_cargo[0] && - cid != dst_ind->accepts_cargo[1] && - cid != dst_ind->accepts_cargo[2])) { - return false; - } + bool valid = std::find(dst_ind->accepts_cargo, endof(dst_ind->accepts_cargo), cid) != endof(dst_ind->accepts_cargo); + if (!valid) return false; dst = dst_ind->index; break; diff --git a/src/table/build_industry.h b/src/table/build_industry.h index 5ae93bc7ed..62264eb6f8 100644 --- a/src/table/build_industry.h +++ b/src/table/build_industry.h @@ -293,6 +293,19 @@ static const IndustryTileTable _tile_table_oil_rig_0[] = { MK(-2, -4, 255), MK(-3, -4, 255), MK(2, 0, 255), + MK(2, -1, 255), + MK(1, -1, 255), + MK(0, -1, 255), + MK(-1, -1, 255), + MK(-1, 0, 255), + MK(-1, 1, 255), + MK(-1, 2, 255), + MK(-1, 3, 255), + MK(0, 3, 255), + MK(1, 3, 255), + MK(2, 3, 255), + MK(2, 2, 255), + MK(2, 1, 255), MKEND }; @@ -1182,8 +1195,12 @@ enum IndustryTypes { #define MI(tbl, sndc, snd, d, pc, ai1, ai2, ai3, ai4, ag1, ag2, ag3, ag4, col, \ c1, c2, c3, proc, p1, r1, p2, r2, m, a1, im1, a2, im2, a3, im3, pr, clim, bev, in, intx, s1, s2, s3) \ - {tbl, lengthof(tbl), d, 0, pc, {c1, c2, c3}, proc, {p1, p2}, {r1, r2}, m, \ - {a1, a2, a3}, {{im1, 0}, {im2, 0}, {im3, 0}}, pr, clim, bev, col, in, intx, s1, s2, s3, STR_UNDEFINED, {ai1, ai2, ai3, ai4}, {ag1, ag2, ag3, ag4}, \ + {tbl, lengthof(tbl), d, 0, pc, {c1, c2, c3}, proc, \ + {p1, p2, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID}, \ + {r1, r2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, m, \ + {a1, a2, a3, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID}, \ + {{im1, 0}, {im2, 0}, {im3, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, \ + pr, clim, bev, col, in, intx, s1, s2, s3, STR_UNDEFINED, {ai1, ai2, ai3, ai4}, {ag1, ag2, ag3, ag4}, \ sndc, snd, 0, 0, true, GRFFileProps(INVALID_INDUSTRYTYPE)} /* Format: tile table count and sounds table @@ -1581,7 +1598,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { * @param a2 next frame of animation * @param a3 chooses between animation or construction state */ -#define MT(ca1, c1, ca2, c2, ca3, c3, sl, a1, a2, a3) {{c1, c2, c3}, {ca1, ca2, ca3}, sl, a1, a2, a3, 0, {0, ANIM_STATUS_NO_ANIMATION, 2, 0}, INDTILE_SPECIAL_NONE, true, GRFFileProps(INVALID_INDUSTRYTILE)} +#define MT(ca1, c1, ca2, c2, ca3, c3, sl, a1, a2, a3) {{c1, c2, c3, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID}, {ca1, ca2, ca3}, sl, a1, a2, a3, 0, {0, ANIM_STATUS_NO_ANIMATION, 2, 0}, INDTILE_SPECIAL_NONE, true, GRFFileProps(INVALID_INDUSTRYTILE)} static const IndustryTileSpec _origin_industry_tile_specs[NEW_INDUSTRYTILEOFFSET] = { /* Coal Mine */ MT(0, CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, SLOPE_STEEP, INDUSTRYTILE_NOANIM, INDUSTRYTILE_NOANIM, false), diff --git a/src/table/newgrf_debug_data.h b/src/table/newgrf_debug_data.h index afe19bbedb..19b411fed0 100644 --- a/src/table/newgrf_debug_data.h +++ b/src/table/newgrf_debug_data.h @@ -272,11 +272,38 @@ static const NIFeature _nif_industrytile = { /*** NewGRF industries ***/ static const NIProperty _nip_industries[] = { - NIP(0x10, Industry, produced_cargo[0], NIT_CARGO, "produced cargo 0"), - NIP(0x10, Industry, produced_cargo[1], NIT_CARGO, "produced cargo 1"), - NIP(0x11, Industry, accepts_cargo[0], NIT_CARGO, "accepted cargo 0"), - NIP(0x11, Industry, accepts_cargo[1], NIT_CARGO, "accepted cargo 1"), - NIP(0x11, Industry, accepts_cargo[2], NIT_CARGO, "accepted cargo 2"), + NIP(0x25, Industry, produced_cargo[ 0], NIT_CARGO, "produced cargo 0"), + NIP(0x25, Industry, produced_cargo[ 1], NIT_CARGO, "produced cargo 1"), + NIP(0x25, Industry, produced_cargo[ 2], NIT_CARGO, "produced cargo 2"), + NIP(0x25, Industry, produced_cargo[ 3], NIT_CARGO, "produced cargo 3"), + NIP(0x25, Industry, produced_cargo[ 4], NIT_CARGO, "produced cargo 4"), + NIP(0x25, Industry, produced_cargo[ 5], NIT_CARGO, "produced cargo 5"), + NIP(0x25, Industry, produced_cargo[ 6], NIT_CARGO, "produced cargo 6"), + NIP(0x25, Industry, produced_cargo[ 7], NIT_CARGO, "produced cargo 7"), + NIP(0x25, Industry, produced_cargo[ 8], NIT_CARGO, "produced cargo 8"), + NIP(0x25, Industry, produced_cargo[ 9], NIT_CARGO, "produced cargo 9"), + NIP(0x25, Industry, produced_cargo[10], NIT_CARGO, "produced cargo 10"), + NIP(0x25, Industry, produced_cargo[11], NIT_CARGO, "produced cargo 11"), + NIP(0x25, Industry, produced_cargo[12], NIT_CARGO, "produced cargo 12"), + NIP(0x25, Industry, produced_cargo[13], NIT_CARGO, "produced cargo 13"), + NIP(0x25, Industry, produced_cargo[14], NIT_CARGO, "produced cargo 14"), + NIP(0x25, Industry, produced_cargo[15], NIT_CARGO, "produced cargo 15"), + NIP(0x26, Industry, accepts_cargo[ 0], NIT_CARGO, "accepted cargo 0"), + NIP(0x26, Industry, accepts_cargo[ 1], NIT_CARGO, "accepted cargo 1"), + NIP(0x26, Industry, accepts_cargo[ 2], NIT_CARGO, "accepted cargo 2"), + NIP(0x26, Industry, accepts_cargo[ 3], NIT_CARGO, "accepted cargo 3"), + NIP(0x26, Industry, accepts_cargo[ 4], NIT_CARGO, "accepted cargo 4"), + NIP(0x26, Industry, accepts_cargo[ 5], NIT_CARGO, "accepted cargo 5"), + NIP(0x26, Industry, accepts_cargo[ 6], NIT_CARGO, "accepted cargo 6"), + NIP(0x26, Industry, accepts_cargo[ 7], NIT_CARGO, "accepted cargo 7"), + NIP(0x26, Industry, accepts_cargo[ 8], NIT_CARGO, "accepted cargo 8"), + NIP(0x26, Industry, accepts_cargo[ 9], NIT_CARGO, "accepted cargo 9"), + NIP(0x26, Industry, accepts_cargo[10], NIT_CARGO, "accepted cargo 10"), + NIP(0x26, Industry, accepts_cargo[11], NIT_CARGO, "accepted cargo 11"), + NIP(0x26, Industry, accepts_cargo[12], NIT_CARGO, "accepted cargo 12"), + NIP(0x26, Industry, accepts_cargo[13], NIT_CARGO, "accepted cargo 13"), + NIP(0x26, Industry, accepts_cargo[14], NIT_CARGO, "accepted cargo 14"), + NIP(0x26, Industry, accepts_cargo[15], NIT_CARGO, "accepted cargo 15"), NIP_END() }; diff --git a/src/table/settings.h.preamble b/src/table/settings.h.preamble index 33345bb713..f475e305bc 100644 --- a/src/table/settings.h.preamble +++ b/src/table/settings.h.preamble @@ -74,7 +74,7 @@ static size_t ConvertLandscape(const char *value); SDTG_GENERAL(name, SDT_INTLIST, SL_ARR, type, flags, guiflags, var, length, def, 0, 0, 0, NULL, str, strhelp, strval, proc, from, to, cat) #define SDTG_STR(name, type, flags, guiflags, var, def, str, strhelp, strval, proc, from, to, cat)\ - SDTG_GENERAL(name, SDT_STRING, SL_STR, type, flags, guiflags, var, lengthof(var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, from, to, cat) + SDTG_GENERAL(name, SDT_STRING, SL_STR, type, flags, guiflags, var, sizeof(var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, from, to, cat) #define SDTG_OMANY(name, type, flags, guiflags, var, def, max, full, str, strhelp, strval, proc, from, to, cat)\ SDTG_GENERAL(name, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, var, 0, def, 0, max, 0, full, str, strhelp, strval, proc, from, to, cat) @@ -102,7 +102,7 @@ static size_t ConvertLandscape(const char *value); SDT_GENERAL(#var, SDT_INTLIST, SL_ARR, type, flags, guiflags, base, var, lengthof(((base*)8)->var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, NULL, from, to, cat) #define SDT_STR(base, var, type, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat)\ - SDT_GENERAL(#var, SDT_STRING, SL_STR, type, flags, guiflags, base, var, lengthof(((base*)8)->var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, NULL, from, to, cat) + SDT_GENERAL(#var, SDT_STRING, SL_STR, type, flags, guiflags, base, var, sizeof(((base*)8)->var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, NULL, from, to, cat) #define SDT_CHR(base, var, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat)\ SDT_GENERAL(#var, SDT_STRING, SL_VAR, SLE_CHAR, flags, guiflags, base, var, 1, def, 0, 0, 0, NULL, str, strhelp, strval, proc, NULL, from, to, cat) @@ -127,7 +127,7 @@ static size_t ConvertLandscape(const char *value); SDTG_GENERAL(#var, SDT_INTLIST, SL_ARR, type, flags, guiflags, _settings_client.var, lengthof(_settings_client.var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, from, to, cat) #define SDTC_STR(var, type, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat)\ - SDTG_GENERAL(#var, SDT_STRING, SL_STR, type, flags, guiflags, _settings_client.var, lengthof(_settings_client.var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, from, to, cat) + SDTG_GENERAL(#var, SDT_STRING, SL_STR, type, flags, guiflags, _settings_client.var, sizeof(_settings_client.var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, from, to, cat) #define SDTC_OMANY(var, type, flags, guiflags, def, max, full, str, strhelp, strval, proc, from, to, cat)\ SDTG_GENERAL(#var, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, _settings_client.var, 1, def, 0, max, 0, full, str, strhelp, strval, proc, from, to, cat) diff --git a/src/table/settings.ini b/src/table/settings.ini index 2554a2ece5..c061c394f0 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -2560,13 +2560,17 @@ strhelp = STR_CONFIG_SETTING_AUTOSCROLL_HELPTEXT strval = STR_CONFIG_SETTING_AUTOSCROLL_DISABLED cat = SC_BASIC -[SDTC_BOOL] -var = gui.reverse_scroll +[SDTC_VAR] +var = gui.scroll_mode +type = SLE_UINT8 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC -def = false -str = STR_CONFIG_SETTING_REVERSE_SCROLLING -strhelp = STR_CONFIG_SETTING_REVERSE_SCROLLING_HELPTEXT -cat = SC_BASIC +guiflags = SGF_MULTISTRING +def = 0 +min = 0 +max = 3 +str = STR_CONFIG_SETTING_SCROLLMODE +strhelp = STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT +strval = STR_CONFIG_SETTING_SCROLLMODE_DEFAULT [SDTC_BOOL] var = gui.smooth_scroll @@ -2575,14 +2579,6 @@ def = false str = STR_CONFIG_SETTING_SMOOTH_SCROLLING strhelp = STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT -[SDTC_BOOL] -var = gui.left_mouse_btn_scrolling -flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC -def = false -str = STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING -strhelp = STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING_HELPTEXT -cat = SC_BASIC - [SDTC_BOOL] var = gui.right_mouse_wnd_close flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -2991,6 +2987,12 @@ flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC def = false cat = SC_BASIC +[SDTC_BOOL] +var = gui.autosave_on_network_disconnect +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +def = true +cat = SC_EXPERT + [SDTC_VAR] var = gui.max_num_autosaves type = SLE_UINT8 diff --git a/src/table/win32_settings.ini b/src/table/win32_settings.ini index 1e0c9ad023..70c18a424e 100644 --- a/src/table/win32_settings.ini +++ b/src/table/win32_settings.ini @@ -8,14 +8,14 @@ [pre-amble] /* win32_v.cpp only settings */ -#if defined(WIN32) && !defined(DEDICATED) +#if defined(_WIN32) && !defined(DEDICATED) extern bool _force_full_redraw, _window_maximize; extern uint _display_hz; static const SettingDescGlobVarList _win32_settings[] = { [post-amble] }; -#endif /* WIN32 */ +#endif /* _WIN32 */ [templates] SDTG_BOOL = SDTG_BOOL($name, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat), SDTG_VAR = SDTG_VAR($name, $type, $flags, $guiflags, $var, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat), diff --git a/src/textbuf.cpp b/src/textbuf.cpp index 3d219e916d..61e449d3ae 100644 --- a/src/textbuf.cpp +++ b/src/textbuf.cpp @@ -367,7 +367,6 @@ bool Textbuf::MovePos(uint16 keycode) /** * Initialize the textbuffer by supplying it the buffer to write into * and the maximum length of this buffer - * @param buf the buffer that will be holding the data for input * @param max_bytes maximum size in bytes, including terminating '\0' * @param max_chars maximum size in chars, including terminating '\0' */ diff --git a/src/tile_cmd.h b/src/tile_cmd.h index 6b8d6c69f4..ce70232a02 100644 --- a/src/tile_cmd.h +++ b/src/tile_cmd.h @@ -81,7 +81,7 @@ typedef CommandCost ClearTileProc(TileIndex tile, DoCommandFlag flags); * @param acceptance Storage destination of the cargo acceptance in 1/8 * @param always_accepted Bitmask of always accepted cargo types */ -typedef void AddAcceptedCargoProc(TileIndex tile, CargoArray &acceptance, uint32 *always_accepted); +typedef void AddAcceptedCargoProc(TileIndex tile, CargoArray &acceptance, CargoTypes *always_accepted); /** * Tile callback function signature for obtaining a tile description @@ -165,11 +165,11 @@ VehicleEnterTileStatus VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y void ChangeTileOwner(TileIndex tile, Owner old_owner, Owner new_owner); void GetTileDesc(TileIndex tile, TileDesc *td); -static inline void AddAcceptedCargo(TileIndex tile, CargoArray &acceptance, uint32 *always_accepted) +static inline void AddAcceptedCargo(TileIndex tile, CargoArray &acceptance, CargoTypes *always_accepted) { AddAcceptedCargoProc *proc = _tile_type_procs[GetTileType(tile)]->add_accepted_cargo_proc; if (proc == NULL) return; - uint32 dummy = 0; // use dummy bitmask so there don't need to be several 'always_accepted != NULL' checks + CargoTypes dummy = 0; // use dummy bitmask so there don't need to be several 'always_accepted != NULL' checks proc(tile, acceptance, always_accepted == NULL ? &dummy : always_accepted); } diff --git a/src/tile_map.cpp b/src/tile_map.cpp index c566ad02cd..d73beeb886 100644 --- a/src/tile_map.cpp +++ b/src/tile_map.cpp @@ -70,11 +70,11 @@ uint TileHeightOutsideMap(int x, int y) /** * Get a tile's slope given the heigh of its four corners. - * @param hnorth The height at the northern corner in the same unit as TileHeight. - * @param hwest The height at the western corner in the same unit as TileHeight. - * @param heast The height at the eastern corner in the same unit as TileHeight. - * @param hsouth The height at the southern corner in the same unit as TileHeight. - * @param [out] h The lowest height of the four corners. + * @param hnorth The height at the northern corner in the same unit as TileHeight. + * @param hwest The height at the western corner in the same unit as TileHeight. + * @param heast The height at the eastern corner in the same unit as TileHeight. + * @param hsouth The height at the southern corner in the same unit as TileHeight. + * @param[out] h The lowest height of the four corners. * @return The slope. */ static Slope GetTileSlopeGivenHeight(int hnorth, int hwest, int heast, int hsouth, int *h) @@ -134,7 +134,8 @@ Slope GetTileSlope(TileIndex tile, int *h) /** * Return the slope of a given tile outside the map. * - * @param tile Tile outside the map to compute slope of. + * @param x X-coordinate of the tile outside to compute height of. + * @param y Y-coordinate of the tile outside to compute height of. * @param h If not \c NULL, pointer to storage of z height. * @return Slope of the tile outside map, except for the HALFTILE part. */ @@ -194,7 +195,8 @@ int GetTileZ(TileIndex tile) /** * Get bottom height of the tile outside map. * - * @param tile Tile outside the map to compute height of. + * @param x X-coordinate of the tile outside to compute height of. + * @param y Y-coordinate of the tile outside to compute height of. * @return Minimum height of the tile outside the map. */ int GetTilePixelZOutsideMap(int x, int y) @@ -229,7 +231,8 @@ int GetTileMaxZ(TileIndex t) * * @see Detailed description in header. * - * @param tile Tile outside to compute height of. + * @param x X-coordinate of the tile outside to compute height of. + * @param y Y-coordinate of the tile outside to compute height of. * @return Maximum height of the tile. */ int GetTileMaxPixelZOutsideMap(int x, int y) diff --git a/src/tile_map.h b/src/tile_map.h index 66726df610..7ee5727bea 100644 --- a/src/tile_map.h +++ b/src/tile_map.h @@ -293,7 +293,7 @@ int GetTilePixelZOutsideMap(int x, int y); /** * Get top height of the tile - * @param t Tile to compute height of + * @param tile Tile to compute height of * @return Maximum height of the tile */ static inline int GetTileMaxPixelZ(TileIndex tile) diff --git a/src/tilematrix_type.hpp b/src/tilematrix_type.hpp index 56f2541438..f9c7392b24 100644 --- a/src/tilematrix_type.hpp +++ b/src/tilematrix_type.hpp @@ -87,7 +87,7 @@ public: /** * Get the area of the matrix square that contains a specific tile. - * @param The tile to get the map area for. + * @param tile The tile to get the map area for. * @param extend Extend the area by this many squares on all sides. * @return Tile area containing the tile. */ diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index 664dc80347..5dd45561f3 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -139,7 +139,7 @@ static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID /** * Callback for when a time has been chosen to start the time table - * @param window the window related to the setting of the date + * @param w the window related to the setting of the date * @param date the actually chosen date */ static void ChangeTimetableStartCallback(const Window *w, Date date) diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index f253be8b3a..40ac3634f1 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -47,6 +47,7 @@ #include "goal_base.h" #include "story_base.h" #include "toolbar_gui.h" +#include "framerate_type.h" #include "widgets/toolbar_widget.h" @@ -1045,7 +1046,7 @@ static CallBackFunction PlaceLandBlockInfo() static CallBackFunction ToolbarHelpClick(Window *w) { - PopupMainToolbMenu(w, WID_TN_HELP, STR_ABOUT_MENU_LAND_BLOCK_INFO, _settings_client.gui.newgrf_developer_tools ? 12 : 9); + PopupMainToolbMenu(w, WID_TN_HELP, STR_ABOUT_MENU_LAND_BLOCK_INFO, _settings_client.gui.newgrf_developer_tools ? 13 : 10); return CBF_NONE; } @@ -1147,10 +1148,11 @@ static CallBackFunction MenuClickHelp(int index) case 5: MenuClickLargeWorldScreenshot(SC_ZOOMEDIN); break; case 6: MenuClickLargeWorldScreenshot(SC_DEFAULTZOOM); break; case 7: MenuClickLargeWorldScreenshot(SC_WORLD); break; - case 8: ShowAboutWindow(); break; - case 9: ShowSpriteAlignerWindow(); break; - case 10: ToggleBoundingBoxes(); break; - case 11: ToggleDirtyBlocks(); break; + case 8: ShowFramerateWindow(); break; + case 9: ShowAboutWindow(); break; + case 10: ShowSpriteAlignerWindow(); break; + case 11: ToggleBoundingBoxes(); break; + case 12: ToggleDirtyBlocks(); break; } return CBF_NONE; } @@ -1482,7 +1484,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer { WID_TN_TRAINS, WID_TN_ROADVEHS, WID_TN_SHIPS, - WID_TN_AIRCRAFTS, + WID_TN_AIRCRAFT, WID_TN_ZOOM_IN, WID_TN_ZOOM_OUT, WID_TN_RAILS, @@ -1514,7 +1516,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer { WID_TN_TRAINS, WID_TN_ROADVEHS, WID_TN_SHIPS, - WID_TN_AIRCRAFTS, + WID_TN_AIRCRAFT, WID_TN_RAILS, WID_TN_ROADS, WID_TN_WATER, @@ -1548,7 +1550,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer { WID_TN_TRAINS, WID_TN_ROADVEHS, WID_TN_SHIPS, - WID_TN_AIRCRAFTS, + WID_TN_AIRCRAFT, WID_TN_RAILS, WID_TN_ROADS, WID_TN_WATER, @@ -1584,7 +1586,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer { WID_TN_TRAINS, WID_TN_ROADVEHS, WID_TN_SHIPS, - WID_TN_AIRCRAFTS, + WID_TN_AIRCRAFT, WID_TN_RAILS, WID_TN_ROADS, WID_TN_WATER, @@ -1643,7 +1645,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer { WID_TN_TRAINS, WID_TN_ROADVEHS, WID_TN_SHIPS, - WID_TN_AIRCRAFTS, + WID_TN_AIRCRAFT, WID_TN_MUSIC_SOUND, WID_TN_MESSAGES, WID_TN_HELP, @@ -1661,7 +1663,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer { WID_TN_TRAINS, WID_TN_ROADVEHS, WID_TN_SHIPS, - WID_TN_AIRCRAFTS, + WID_TN_AIRCRAFT, WID_TN_RAILS, WID_TN_ROADS, WID_TN_WATER, @@ -1702,7 +1704,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer { WID_TN_TRAINS, WID_TN_ROADVEHS, WID_TN_SHIPS, - WID_TN_AIRCRAFTS, + WID_TN_AIRCRAFT, WID_TN_RAILS, WID_TN_ROADS, WID_TN_WATER, @@ -1754,7 +1756,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer { WID_TN_TRAINS, WID_TN_ROADVEHS, WID_TN_SHIPS, - WID_TN_AIRCRAFTS, + WID_TN_AIRCRAFT, WID_TN_ZOOM_IN, WID_TN_ZOOM_OUT, WID_TN_RAILS, @@ -2000,7 +2002,7 @@ struct MainToolbarWindow : Window { * Since enabled state is the default, just disable when needed */ this->SetWidgetsDisabledState(_local_company == COMPANY_SPECTATOR, WID_TN_RAILS, WID_TN_ROADS, WID_TN_WATER, WID_TN_AIR, WID_TN_LANDSCAPE, WIDGET_LIST_END); /* disable company list drop downs, if there are no companies */ - this->SetWidgetsDisabledState(Company::GetNumItems() == 0, WID_TN_STATIONS, WID_TN_FINANCES, WID_TN_TRAINS, WID_TN_ROADVEHS, WID_TN_SHIPS, WID_TN_AIRCRAFTS, WIDGET_LIST_END); + this->SetWidgetsDisabledState(Company::GetNumItems() == 0, WID_TN_STATIONS, WID_TN_FINANCES, WID_TN_TRAINS, WID_TN_ROADVEHS, WID_TN_SHIPS, WID_TN_AIRCRAFT, WIDGET_LIST_END); this->SetWidgetDisabledState(WID_TN_GOAL, Goal::GetNumItems() == 0); this->SetWidgetDisabledState(WID_TN_STORY, StoryPage::GetNumItems() == 0); diff --git a/src/town.h b/src/town.h index 010c7c2168..19a4118bad 100644 --- a/src/town.h +++ b/src/town.h @@ -26,7 +26,7 @@ struct BuildingCounts { T class_count[HOUSE_CLASS_MAX]; }; -typedef TileMatrix AcceptanceMatrix; +typedef TileMatrix AcceptanceMatrix; static const uint CUSTOM_TOWN_NUMBER_DIFFICULTY = 4; ///< value for custom town number in difficulty settings static const uint CUSTOM_TOWN_MAX_NUMBER = 5000; ///< this is the maximum number of towns a user can specify in customisation @@ -35,8 +35,8 @@ static const uint INVALID_TOWN = 0xFFFF; static const uint TOWN_GROWTH_WINTER = 0xFFFFFFFE; ///< The town only needs this cargo in the winter (any amount) static const uint TOWN_GROWTH_DESERT = 0xFFFFFFFF; ///< The town needs the cargo for growth when on desert (any amount) -static const uint16 TOWN_GROW_RATE_CUSTOM = 0x8000; ///< If this mask is applied to Town::growth_rate, the grow_counter will not be calculated by the system (but assumed to be set by scripts) -static const uint16 TOWN_GROW_RATE_CUSTOM_NONE = 0xFFFF; ///< Special value for Town::growth_rate to disable town growth. +static const uint16 TOWN_GROWTH_RATE_NONE = 0xFFFF; ///< Special value for Town::growth_rate to disable town growth. +static const uint16 MAX_TOWN_GROWTH_TICKS = 930; ///< Max amount of original town ticks that still fit into uint16, about equal to UINT16_MAX / TOWN_GROWTH_TICKS but sligtly less to simplify calculations typedef Pool TownPool; extern TownPool _town_pool; @@ -85,9 +85,9 @@ struct Town : TownPool::PoolItem<&_town_pool> { inline byte GetPercentTransported(CargoID cid) const { return this->supplied[cid].old_act * 256 / (this->supplied[cid].old_max + 1); } /* Cargo production and acceptance stats. */ - uint32 cargo_produced; ///< Bitmap of all cargoes produced by houses in this town. + CargoTypes cargo_produced; ///< Bitmap of all cargoes produced by houses in this town. AcceptanceMatrix cargo_accepted; ///< Bitmap of cargoes accepted by houses for each 4*4 map square of the town. - uint32 cargo_accepted_total; ///< NOSAVE: Bitmap of all cargoes accepted by houses in this town. + CargoTypes cargo_accepted_total; ///< NOSAVE: Bitmap of all cargoes accepted by houses in this town. uint16 time_until_rebuild; ///< time until we rebuild a house @@ -165,6 +165,7 @@ enum TownFlags { TOWN_IS_GROWING = 0, ///< Conditions for town growth are met. Grow according to Town::growth_rate. TOWN_HAS_CHURCH = 1, ///< There can be only one church by town. TOWN_HAS_STADIUM = 2, ///< There can be only one stadium by town. + TOWN_CUSTOM_GROWTH = 3, ///< Growth rate is controlled by GS. }; CommandCost CheckforTownRating(DoCommandFlag flags, Town *t, TownRatingCheckType type); @@ -194,7 +195,6 @@ uint GetMaskOfTownActions(int *nump, CompanyID cid, const Town *t); bool GenerateTowns(TownLayout layout); const CargoSpec *FindFirstCargoWithTownEffect(TownEffect effect); - /** Town actions of a company. */ enum TownActions { TACT_NONE = 0x00, ///< Empty action set. @@ -284,6 +284,15 @@ void MakeDefaultName(T *obj) obj->town_cn = (uint16)next; // set index... } -extern uint32 _town_cargoes_accepted; +/* + * Converts original town ticks counters to plain game ticks. Note that + * tick 0 is a valid tick so actual amount is one more than the counter value. + */ +static inline uint16 TownTicksToGameTicks(uint16 ticks) { + return (min(ticks, MAX_TOWN_GROWTH_TICKS) + 1) * TOWN_GROWTH_TICKS - 1; +} + + +extern CargoTypes _town_cargoes_accepted; #endif /* TOWN_H */ diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index daaad7e8d0..927651864f 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -53,7 +53,7 @@ #include "safeguards.h" TownID _new_town_id; -uint32 _town_cargoes_accepted; ///< Bitmap of all cargoes accepted by houses. +CargoTypes _town_cargoes_accepted; ///< Bitmap of all cargoes accepted by houses. /* Initialize the town-pool */ TownPool _town_pool("Town"); @@ -601,14 +601,14 @@ static void AddProducedCargo_Town(TileIndex tile, CargoArray &produced) } } -static inline void AddAcceptedCargoSetMask(CargoID cargo, uint amount, CargoArray &acceptance, uint32 *always_accepted) +static inline void AddAcceptedCargoSetMask(CargoID cargo, uint amount, CargoArray &acceptance, CargoTypes *always_accepted) { if (cargo == CT_INVALID || amount == 0) return; acceptance[cargo] += amount; SetBit(*always_accepted, cargo); } -static void AddAcceptedCargo_Town(TileIndex tile, CargoArray &acceptance, uint32 *always_accepted) +static void AddAcceptedCargo_Town(TileIndex tile, CargoArray &acceptance, CargoTypes *always_accepted) { const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile)); CargoID accepts[3]; @@ -719,7 +719,7 @@ void UpdateTownCargoTotal(Town *t) static void UpdateTownCargoes(Town *t, TileIndex start, bool update_total = true) { CargoArray accepted, produced; - uint32 dummy; + CargoTypes dummy = 0; /* Gather acceptance for all houses in an area around the start tile. * The area is composed of the square the tile is in, extended one square in all @@ -733,7 +733,7 @@ static void UpdateTownCargoes(Town *t, TileIndex start, bool update_total = true } /* Create bitmap of produced and accepted cargoes. */ - uint32 acc = 0; + CargoTypes acc = 0; for (uint cid = 0; cid < NUM_CARGO; cid++) { if (accepted[cid] >= 8) SetBit(acc, cid); if (produced[cid] > 0) SetBit(t->cargo_produced, cid); @@ -780,12 +780,13 @@ static bool GrowTown(Town *t); static void TownTickHandler(Town *t) { if (HasBit(t->flags, TOWN_IS_GROWING)) { - int i = t->grow_counter - 1; + int i = (int)t->grow_counter - 1; if (i < 0) { if (GrowTown(t)) { - i = t->growth_rate & (~TOWN_GROW_RATE_CUSTOM); + i = t->growth_rate; } else { - i = 0; + /* If growth failed wait a bit before retrying */ + i = min(t->growth_rate, TOWN_GROWTH_TICKS - 1); } } t->grow_counter = i; @@ -798,10 +799,7 @@ void OnTick_Town() Town *t; FOR_ALL_TOWNS(t) { - /* Run town tick at regular intervals, but not all at once. */ - if ((_tick_counter + t->index) % TOWN_GROWTH_TICKS == 0) { - TownTickHandler(t); - } + TownTickHandler(t); } } @@ -1228,17 +1226,48 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t /* Possibly extend the road in a direction. * Randomize a direction and if it has a road, bail out. */ target_dir = RandomDiagDir(); - if (cur_rb & DiagDirToRoadBits(target_dir)) return; + RoadBits target_rb = DiagDirToRoadBits(target_dir); + TileIndex house_tile; // position of a possible house - /* This is the tile we will reach if we extend to this direction. */ - TileIndex house_tile = TileAddByDiagDir(tile, target_dir); // position of a possible house + if (cur_rb & target_rb) { + /* If it's a road turn possibly build a house in a corner. + * Use intersection with straight road as an indicator + * that we randomed corner house position. + * A turn (and we check for that later) always has only + * one common bit with a straight road so it has the same + * chance to be chosen as the house on the side of a road. + */ + if ((cur_rb & ROAD_X) != target_rb) return; + + /* Check whether it is a turn and if so determine + * position of the corner tile */ + switch (cur_rb) { + case ROAD_N: + house_tile = TileAddByDir(tile, DIR_S); + break; + case ROAD_S: + house_tile = TileAddByDir(tile, DIR_N); + break; + case ROAD_E: + house_tile = TileAddByDir(tile, DIR_W); + break; + case ROAD_W: + house_tile = TileAddByDir(tile, DIR_E); + break; + default: + return; // not a turn + } + target_dir = DIAGDIR_END; + } else { + house_tile = TileAddByDiagDir(tile, target_dir); + } /* Don't walk into water. */ if (HasTileWaterGround(house_tile)) return; if (!IsValidTile(house_tile)) return; - if (_settings_game.economy.allow_town_roads || _generating_world) { + if (target_dir != DIAGDIR_END && (_settings_game.economy.allow_town_roads || _generating_world)) { switch (t1->layout) { default: NOT_REACHED(); @@ -1248,7 +1277,7 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t case TL_2X2_GRID: rcmd = GetTownRoadGridElement(t1, tile, target_dir); - allow_house = (rcmd & DiagDirToRoadBits(target_dir)) == ROAD_NONE; + allow_house = (rcmd & target_rb) == ROAD_NONE; break; case TL_BETTER_ROADS: // Use original afterwards! @@ -1258,7 +1287,7 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t case TL_ORIGINAL: /* Allow a house at the edge. 60% chance or * always ok if no road allowed. */ - rcmd = DiagDirToRoadBits(target_dir); + rcmd = target_rb; allow_house = (!IsRoadAllowedHere(t1, house_tile, target_dir) || Chance16(6, 10)); break; } @@ -1546,6 +1575,9 @@ void UpdateTownMaxPass(Town *t) t->supplied[CT_MAIL].old_max = t->cache.population >> 4; } +static void UpdateTownGrowthRate(Town *t); +static void UpdateTownGrowth(Town *t); + /** * Does the actual town creation. * @@ -1565,8 +1597,10 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSize UpdateTownRadius(t); t->flags = 0; t->cache.population = 0; - t->grow_counter = 0; - t->growth_rate = 250; + /* Spread growth across ticks so even if there are many + * similar towns they're unlikely to grow all in one tick */ + t->grow_counter = t->index % TOWN_GROWTH_TICKS; + t->growth_rate = TownTicksToGameTicks(250); /* Set the default cargo requirement for town growth */ switch (_settings_game.game_creation.landscape) { @@ -1623,6 +1657,7 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSize t->cache.num_houses -= x; UpdateTownRadius(t); + UpdateTownGrowthRate(t); UpdateTownMaxPass(t); UpdateAirportsNoise(); } @@ -1763,15 +1798,21 @@ CommandCost CmdFoundTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 if (_game_mode != GM_EDITOR) { /* 't' can't be NULL since 'random' is false outside scenedit */ assert(!random); - char company_name[MAX_LENGTH_COMPANY_NAME_CHARS * MAX_CHAR_LENGTH]; - SetDParam(0, _current_company); - GetString(company_name, STR_COMPANY_NAME, lastof(company_name)); - char *cn = stredup(company_name); - SetDParamStr(0, cn); - SetDParam(1, t->index); + if (_current_company == OWNER_DEITY) { + SetDParam(0, t->index); + AddTileNewsItem(STR_NEWS_NEW_TOWN_UNSPONSORED, NT_INDUSTRY_OPEN, tile); + } else { + char company_name[MAX_LENGTH_COMPANY_NAME_CHARS * MAX_CHAR_LENGTH]; + SetDParam(0, _current_company); + GetString(company_name, STR_COMPANY_NAME, lastof(company_name)); - AddTileNewsItem(STR_NEWS_NEW_TOWN, NT_INDUSTRY_OPEN, tile, cn); + char *cn = stredup(company_name); + SetDParamStr(0, cn); + SetDParam(1, t->index); + + AddTileNewsItem(STR_NEWS_NEW_TOWN, NT_INDUSTRY_OPEN, tile, cn); + } AI::BroadcastNewEvent(new ScriptEventTownFounded(t->index)); Game::NewEvent(new ScriptEventTownFounded(t->index)); } @@ -2381,6 +2422,7 @@ static bool BuildTownHouse(Town *t, TileIndex tile) MakeTownHouse(tile, t, construction_counter, construction_stage, house, random_bits); UpdateTownRadius(t); + UpdateTownGrowthRate(t); UpdateTownCargoes(t, tile); return true; @@ -2516,8 +2558,6 @@ const CargoSpec *FindFirstCargoWithTownEffect(TownEffect effect) return NULL; } -static void UpdateTownGrowRate(Town *t); - /** * Change the cargo goal of a town. * @param tile Unused. @@ -2546,7 +2586,7 @@ CommandCost CmdTownCargoGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uin if (flags & DC_EXEC) { t->goal[te] = p2; - UpdateTownGrowRate(t); + UpdateTownGrowth(t); InvalidateWindowData(WC_TOWN_VIEW, index); } @@ -2582,14 +2622,13 @@ CommandCost CmdTownSetText(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 * @param tile Unused. * @param flags Type of operation. * @param p1 Town ID to cargo game of. - * @param p2 Amount of days between growth, or TOWN_GROW_RATE_CUSTOM_NONE, or 0 to reset custom growth rate. + * @param p2 Amount of days between growth, or TOWN_GROWTH_RATE_NONE, or 0 to reset custom growth rate. * @param text Unused. * @return Empty cost or an error. */ CommandCost CmdTownGrowthRate(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; - if ((p2 & TOWN_GROW_RATE_CUSTOM) != 0 && p2 != TOWN_GROW_RATE_CUSTOM_NONE) return CMD_ERROR; if (GB(p2, 16, 16) != 0) return CMD_ERROR; Town *t = Town::GetIfValid(p1); @@ -2597,10 +2636,10 @@ CommandCost CmdTownGrowthRate(TileIndex tile, DoCommandFlag flags, uint32 p1, ui if (flags & DC_EXEC) { if (p2 == 0) { - /* Clear TOWN_GROW_RATE_CUSTOM, UpdateTownGrowRate will determine a proper value */ - t->growth_rate = 0; + /* Just clear the flag, UpdateTownGrowth will determine a proper growth rate */ + ClrBit(t->flags, TOWN_CUSTOM_GROWTH); } else { - uint old_rate = t->growth_rate & ~TOWN_GROW_RATE_CUSTOM; + uint old_rate = t->growth_rate; if (t->grow_counter >= old_rate) { /* This also catches old_rate == 0 */ t->grow_counter = p2; @@ -2608,9 +2647,10 @@ CommandCost CmdTownGrowthRate(TileIndex tile, DoCommandFlag flags, uint32 p1, ui /* Scale grow_counter, so half finished houses stay half finished */ t->grow_counter = t->grow_counter * p2 / old_rate; } - t->growth_rate = p2 | TOWN_GROW_RATE_CUSTOM; + t->growth_rate = p2; + SetBit(t->flags, TOWN_CUSTOM_GROWTH); } - UpdateTownGrowRate(t); + UpdateTownGrowth(t); InvalidateWindowData(WC_TOWN_VIEW, p1); } @@ -2893,13 +2933,21 @@ static CommandCost TownActionFundBuildings(Town *t, DoCommandFlag flags) if (!_settings_game.economy.fund_buildings) return CMD_ERROR; if (flags & DC_EXEC) { - /* Build next tick */ - t->grow_counter = 1; /* And grow for 3 months */ t->fund_buildings_months = 3; /* Enable growth (also checking GameScript's opinion) */ - UpdateTownGrowRate(t); + UpdateTownGrowth(t); + + /* Build a new house, but add a small delay to make sure + * that spamming funding doesn't let town grow any faster + * than 1 house per 2 * TOWN_GROWTH_TICKS ticks. + * Also emulate original behaviour when town was only growing in + * TOWN_GROWTH_TICKS intervals, to make sure that it's not too + * tick-perfect and gives player some time window where he can + * spam funding with the exact same effeciency. + */ + t->grow_counter = min(t->grow_counter, 2 * TOWN_GROWTH_TICKS - (t->growth_rate - t->grow_counter) % TOWN_GROWTH_TICKS); SetWindowDirty(WC_TOWN_VIEW, t->index); } @@ -3093,8 +3141,87 @@ static void UpdateTownRating(Town *t) SetWindowDirty(WC_TOWN_AUTHORITY, t->index); } -static void UpdateTownGrowRate(Town *t) + +/** + * Updates town grow counter after growth rate change. + * Preserves relative house builting progress whenever it can. + * @param t The town to calculate grow counter for + * @param prev_growth_rate Town growth rate before it changed (one that was used with grow counter to be updated) + */ +static void UpdateTownGrowCounter(Town *t, uint16 prev_growth_rate) { + if (t->growth_rate == TOWN_GROWTH_RATE_NONE) return; + if (prev_growth_rate == TOWN_GROWTH_RATE_NONE) { + t->grow_counter = min(t->growth_rate, t->grow_counter); + return; + } + t->grow_counter = RoundDivSU((uint32)t->grow_counter * (t->growth_rate + 1), prev_growth_rate + 1); +} + +/** + * Calculates amount of active stations in the range of town (HZB_TOWN_EDGE). + * @param t The town to calculate stations for + * @returns Amount of active stations + */ +static int CountActiveStations(Town *t) +{ + int n = 0; + const Station *st; + FOR_ALL_STATIONS(st) { + if (DistanceSquare(st->xy, t->xy) <= t->cache.squared_town_zone_radius[0]) { + if (st->time_since_load <= 20 || st->time_since_unload <= 20) { + n++; + } + } + } + return n; +} + +/** + * Calculates town growth rate in normal conditions (custom growth rate not set). + * If town growth speed is set to None(0) returns the same rate as if it was Normal(2). + * @param t The town to calculate growth rate for + * @returns Calculated growth rate + */ +static uint GetNormalGrowthRate(Town *t) +{ + static const uint16 _grow_count_values[2][6] = { + { 120, 120, 120, 100, 80, 60 }, // Fund new buildings has been activated + { 320, 420, 300, 220, 160, 100 } // Normal values + }; + + int n = CountActiveStations(t); + uint16 m = _grow_count_values[t->fund_buildings_months != 0 ? 0 : 1][min(n, 5)]; + + uint growth_multiplier = _settings_game.economy.town_growth_rate != 0 ? _settings_game.economy.town_growth_rate - 1 : 1; + + m >>= growth_multiplier; + if (t->larger_town) m /= 2; + + return TownTicksToGameTicks(m / (t->cache.num_houses / 50 + 1)); +} + +/** + * Updates town growth rate. + * @param t The town to update growth rate for + */ +static void UpdateTownGrowthRate(Town *t) +{ + if (HasBit(t->flags, TOWN_CUSTOM_GROWTH)) return; + uint old_rate = t->growth_rate; + t->growth_rate = GetNormalGrowthRate(t); + UpdateTownGrowCounter(t, old_rate); + SetWindowDirty(WC_TOWN_VIEW, t->index); +} + +/** + * Updates town growth state (whether it is growing or not). + * @param t The town to update growth for + */ +static void UpdateTownGrowth(Town *t) +{ + UpdateTownGrowthRate(t); + ClrBit(t->flags, TOWN_IS_GROWING); SetWindowDirty(WC_TOWN_VIEW, t->index); @@ -3117,50 +3244,13 @@ static void UpdateTownGrowRate(Town *t) } } - if ((t->growth_rate & TOWN_GROW_RATE_CUSTOM) != 0) { - if (t->growth_rate != TOWN_GROW_RATE_CUSTOM_NONE) SetBit(t->flags, TOWN_IS_GROWING); + if (HasBit(t->flags, TOWN_CUSTOM_GROWTH)) { + if (t->growth_rate != TOWN_GROWTH_RATE_NONE) SetBit(t->flags, TOWN_IS_GROWING); SetWindowDirty(WC_TOWN_VIEW, t->index); return; } - /** - * Towns are processed every TOWN_GROWTH_TICKS ticks, and this is the - * number of times towns are processed before a new building is built. - */ - static const uint16 _grow_count_values[2][6] = { - { 120, 120, 120, 100, 80, 60 }, // Fund new buildings has been activated - { 320, 420, 300, 220, 160, 100 } // Normal values - }; - - int n = 0; - - const Station *st; - FOR_ALL_STATIONS(st) { - if (DistanceSquare(st->xy, t->xy) <= t->cache.squared_town_zone_radius[0]) { - if (st->time_since_load <= 20 || st->time_since_unload <= 20) { - n++; - } - } - } - - uint16 m; - - if (t->fund_buildings_months != 0) { - m = _grow_count_values[0][min(n, 5)]; - } else { - m = _grow_count_values[1][min(n, 5)]; - if (n == 0 && !Chance16(1, 12)) return; - } - - /* Use the normal growth rate values if new buildings have been funded in - * this town and the growth rate is set to none. */ - uint growth_multiplier = _settings_game.economy.town_growth_rate != 0 ? _settings_game.economy.town_growth_rate - 1 : 1; - - m >>= growth_multiplier; - if (t->larger_town) m /= 2; - - t->growth_rate = m / (t->cache.num_houses / 50 + 1); - t->grow_counter = min(t->growth_rate, t->grow_counter); + if (t->fund_buildings_months == 0 && CountActiveStations(t) == 0 && !Chance16(1, 12)) return; SetBit(t->flags, TOWN_IS_GROWING); SetWindowDirty(WC_TOWN_VIEW, t->index); @@ -3394,8 +3484,8 @@ void TownsMonthlyLoop() } UpdateTownAmounts(t); + UpdateTownGrowth(t); UpdateTownRating(t); - UpdateTownGrowRate(t); UpdateTownUnwanted(t); UpdateTownCargoes(t); } diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 696b71afd2..17449854d6 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -269,8 +269,8 @@ public: } /* When double-clicking, continue */ if (click_count == 1 || y < 0) break; + FALLTHROUGH; } - FALLTHROUGH; case WID_TA_EXECUTE: DoCommandP(this->town->xy, this->window_number, this->sel_index, CMD_DO_TOWN_ACTION | CMD_MSG(STR_ERROR_CAN_T_DO_THIS)); @@ -337,13 +337,15 @@ public: SetDParam(1, this->town->cache.num_houses); DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y, STR_TOWN_VIEW_POPULATION_HOUSES); - SetDParam(0, this->town->supplied[CT_PASSENGERS].old_act); - SetDParam(1, this->town->supplied[CT_PASSENGERS].old_max); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX); + SetDParam(0, 1 << CT_PASSENGERS); + SetDParam(1, this->town->supplied[CT_PASSENGERS].old_act); + SetDParam(2, this->town->supplied[CT_PASSENGERS].old_max); + DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX); - SetDParam(0, this->town->supplied[CT_MAIL].old_act); - SetDParam(1, this->town->supplied[CT_MAIL].old_max); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX); + SetDParam(0, 1 << CT_MAIL); + SetDParam(1, this->town->supplied[CT_MAIL].old_act); + SetDParam(2, this->town->supplied[CT_MAIL].old_max); + DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX); bool first = true; for (int i = TE_BEGIN; i < TE_END; i++) { @@ -392,7 +394,7 @@ public: } if (HasBit(this->town->flags, TOWN_IS_GROWING)) { - SetDParam(0, ((this->town->growth_rate & (~TOWN_GROW_RATE_CUSTOM)) * TOWN_GROWTH_TICKS + DAY_TICKS) / DAY_TICKS); + SetDParam(0, RoundDivSU(this->town->growth_rate + 1, DAY_TICKS)); DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, this->town->fund_buildings_months == 0 ? STR_TOWN_VIEW_TOWN_GROWS_EVERY : STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED); } else { DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_TOWN_GROW_STOPPED); @@ -745,6 +747,16 @@ public: } } + /** + * Get the string to draw the town name. + * @param t Town to draw. + * @return The string to use. + */ + static StringID GetTownString(const Town *t) + { + return t->larger_town ? STR_TOWN_DIRECTORY_CITY : STR_TOWN_DIRECTORY_TOWN; + } + virtual void DrawWidget(const Rect &r, int widget) const { switch (widget) { @@ -783,7 +795,7 @@ public: SetDParam(0, t->index); SetDParam(1, t->cache.population); - DrawString(text_left, text_right, y + (this->resize.step_height - FONT_HEIGHT_NORMAL) / 2, STR_TOWN_DIRECTORY_TOWN); + DrawString(text_left, text_right, y + (this->resize.step_height - FONT_HEIGHT_NORMAL) / 2, GetTownString(t)); y += this->resize.step_height; if (++n == this->vscroll->GetCapacity()) break; // max number of towns in 1 window @@ -822,7 +834,7 @@ public: SetDParam(0, t->index); SetDParamMaxDigits(1, 8); - d = maxdim(d, GetStringBoundingBox(STR_TOWN_DIRECTORY_TOWN)); + d = maxdim(d, GetStringBoundingBox(GetTownString(t))); } Dimension icon_size = GetSpriteSize(SPR_TOWN_RATING_GOOD); d.width += icon_size.width + 2; diff --git a/src/track_func.h b/src/track_func.h index 68de827ef1..a55d6d8f20 100644 --- a/src/track_func.h +++ b/src/track_func.h @@ -61,7 +61,7 @@ static inline bool IsValidTrackdirForRoadVehicle(Trackdir trackdir) */ static inline bool IsValidTrackdir(Trackdir trackdir) { - return (1 << trackdir & TRACKDIR_BIT_MASK) != 0; + return trackdir != INVALID_TRACKDIR && ((1 << trackdir & TRACKDIR_BIT_MASK) != TRACKDIR_BIT_NONE); } /** @@ -331,6 +331,28 @@ static inline TrackdirBits TrackBitsToTrackdirBits(TrackBits bits) return (TrackdirBits)(bits * 0x101); } +/** + * Checks whether a TrackBits has a given Track. + * @param tracks The track bits. + * @param track The track to check. + */ +static inline bool HasTrack(TrackBits tracks, Track track) +{ + assert(IsValidTrack(track)); + return HasBit(tracks, track); +} + +/** + * Checks whether a TrackdirBits has a given Trackdir. + * @param trackdirs The trackdir bits. + * @param trackdir The trackdir to check. + */ +static inline bool HasTrackdir(TrackdirBits trackdirs, Trackdir trackdir) +{ + assert(IsValidTrackdir(trackdir)); + return HasBit(trackdirs, trackdir); +} + /** * Returns the present-trackdir-information of a TrackStatus. * @@ -692,4 +714,25 @@ static inline bool IsUphillTrackdir(Slope slope, Trackdir dir) return HasBit(_uphill_trackdirs[RemoveHalftileSlope(slope)], dir); } +/** + * Determine the side in which the vehicle will leave the tile + * + * @param direction vehicle direction + * @param track vehicle track bits + * @return side of tile the vehicle will leave + */ +static inline DiagDirection VehicleExitDir(Direction direction, TrackBits track) +{ + static const TrackBits state_dir_table[DIAGDIR_END] = { TRACK_BIT_RIGHT, TRACK_BIT_LOWER, TRACK_BIT_LEFT, TRACK_BIT_UPPER }; + + DiagDirection diagdir = DirToDiagDir(direction); + + /* Determine the diagonal direction in which we will exit this tile */ + if (!HasBit(direction, 0) && track != state_dir_table[diagdir]) { + diagdir = ChangeDiagDir(diagdir, DIAGDIRDIFF_90LEFT); + } + + return diagdir; +} + #endif /* TRACK_FUNC_H */ diff --git a/src/train.h b/src/train.h index c40ab75560..5958cde1a0 100644 --- a/src/train.h +++ b/src/train.h @@ -110,7 +110,7 @@ struct Train FINAL : public GroundVehicle { friend struct GroundVehicle; // GroundVehicle needs to use the acceleration functions defined at Train. void MarkDirty(); - void UpdateDeltaXY(Direction direction); + void UpdateDeltaXY(); ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_TRAIN_INC : EXPENSES_TRAIN_RUN; } void PlayLeaveStationSound() const; bool IsPrimaryVehicle() const { return this->IsFrontEngine(); } diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index fb1d2b1ee4..0672ac2093 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -35,6 +35,7 @@ #include "order_backup.h" #include "zoom_func.h" #include "newgrf_debug.h" +#include "framerate_type.h" #include "table/strings.h" #include "table/train_cmd.h" @@ -57,27 +58,6 @@ bool IsValidImageIndex(uint8 image_index) return image_index < lengthof(_engine_sprite_base); } -/** - * Determine the side in which the train will leave the tile - * - * @param direction vehicle direction - * @param track vehicle track bits - * @return side of tile the train will leave - */ -static inline DiagDirection TrainExitDir(Direction direction, TrackBits track) -{ - static const TrackBits state_dir_table[DIAGDIR_END] = { TRACK_BIT_RIGHT, TRACK_BIT_LOWER, TRACK_BIT_LEFT, TRACK_BIT_UPPER }; - - DiagDirection diagdir = DirToDiagDir(direction); - - /* Determine the diagonal direction in which we will exit this tile */ - if (!HasBit(direction, 0) && track != state_dir_table[diagdir]) { - diagdir = ChangeDiagDir(diagdir, DIAGDIRDIFF_90LEFT); - } - - return diagdir; -} - /** * Return the cargo weight multiplier to use for a rail vehicle @@ -601,7 +581,7 @@ void GetTrainSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, * @param tile tile of the depot where rail-vehicle is built. * @param flags type of operation. * @param e the engine to build. - * @param ret[out] the vehicle that has been built. + * @param[out] ret the vehicle that has been built. * @return the cost of this operation or an error. */ static CommandCost CmdBuildRailWagon(TileIndex tile, DoCommandFlag flags, const Engine *e, Vehicle **ret) @@ -733,7 +713,7 @@ static void AddRearEngineToMultiheadedTrain(Train *v) * @param flags type of operation. * @param e the engine to build. * @param data bit 0 prevents any free cars from being added to the train. - * @param ret[out] the vehicle that has been built. + * @param[out] ret the vehicle that has been built. * @return the cost of this operation or an error. */ CommandCost CmdBuildRailVehicle(TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **ret) @@ -894,7 +874,7 @@ static void RemoveFromConsist(Train *part, bool chain = false) static void InsertInConsist(Train *dst, Train *chain) { /* We do not want to add something in the middle of an articulated part. */ - assert(dst->Next() == NULL || !dst->Next()->IsArticulatedPart()); + assert(dst != NULL && (dst->Next() == NULL || !dst->Next()->IsArticulatedPart())); chain->Last()->SetNext(dst->Next()); dst->SetNext(chain); @@ -955,8 +935,8 @@ static void NormaliseSubtypes(Train *chain) * @note All vehicles are/were 'heads' of their chains. * @param original_dst The original destination chain. * @param dst The destination chain after constructing the train. - * @param original_dst The original source chain. - * @param dst The source chain after constructing the train. + * @param original_src The original source chain. + * @param src The source chain after constructing the train. * @return possible error of this command. */ static CommandCost CheckNewTrain(Train *original_dst, Train *dst, Train *original_src, Train *src) @@ -1074,8 +1054,8 @@ static CommandCost CheckTrainAttachment(Train *t) * @note All vehicles are/were 'heads' of their chains. * @param original_dst The original destination chain. * @param dst The destination chain after constructing the train. - * @param original_dst The original source chain. - * @param dst The source chain after constructing the train. + * @param original_src The original source chain. + * @param src The source chain after constructing the train. * @param check_limit Whether to check the vehicle limit. * @return possible error of this command. */ @@ -1442,7 +1422,7 @@ CommandCost CmdSellRailWagon(DoCommandFlag flags, Vehicle *t, uint16 data, uint3 return cost; } -void Train::UpdateDeltaXY(Direction direction) +void Train::UpdateDeltaXY() { /* Set common defaults. */ this->x_offs = -1; @@ -1453,7 +1433,7 @@ void Train::UpdateDeltaXY(Direction direction) this->x_bb_offs = 0; this->y_bb_offs = 0; - if (!IsDiagonalDirection(direction)) { + if (!IsDiagonalDirection(this->direction)) { static const int _sign_table[] = { /* x, y */ @@ -1466,12 +1446,12 @@ void Train::UpdateDeltaXY(Direction direction) int half_shorten = (VEHICLE_LENGTH - this->gcache.cached_veh_length) / 2; /* For all straight directions, move the bound box to the centre of the vehicle, but keep the size. */ - this->x_offs -= half_shorten * _sign_table[direction]; - this->y_offs -= half_shorten * _sign_table[direction + 1]; + this->x_offs -= half_shorten * _sign_table[this->direction]; + this->y_offs -= half_shorten * _sign_table[this->direction + 1]; this->x_extent += this->x_bb_offs = half_shorten * _sign_table[direction]; this->y_extent += this->y_bb_offs = half_shorten * _sign_table[direction + 1]; } else { - switch (direction) { + switch (this->direction) { /* Shorten southern corner of the bounding box according the vehicle length * and center the bounding box on the vehicle. */ case DIR_NE: @@ -1531,8 +1511,8 @@ static void MarkTrainAsStuck(Train *v) * Swap the two up/down flags in two ways: * - Swap values of \a swap_flag1 and \a swap_flag2, and * - If going up previously (#GVF_GOINGUP_BIT set), the #GVF_GOINGDOWN_BIT is set, and vice versa. - * @param swap_flag1 [inout] First train flag. - * @param swap_flag2 [inout] Second train flag. + * @param[in,out] swap_flag1 First train flag. + * @param[in,out] swap_flag2 Second train flag. */ static void SwapTrainFlags(uint16 *swap_flag1, uint16 *swap_flag2) { @@ -1872,9 +1852,9 @@ void ReverseTrainDirection(Train *v) return; } - /* TrainExitDir does not always produce the desired dir for depots and + /* VehicleExitDir does not always produce the desired dir for depots and * tunnels/bridges that is needed for UpdateSignalsOnSegment. */ - DiagDirection dir = TrainExitDir(v->direction, v->track); + DiagDirection dir = VehicleExitDir(v->direction, v->track); if (IsRailDepotTile(v->tile) || IsTileType(v->tile, MP_TUNNELBRIDGE)) dir = INVALID_DIAGDIR; if (UpdateSignalsOnSegment(v->tile, dir, v->owner) == SIGSEG_PBS || _settings_game.pf.reserve_paths) { @@ -2034,9 +2014,9 @@ static FindDepotData FindClosestTrainDepot(Train *v, int max_distance) /** * Locate the closest depot for this consist, and return the information to the caller. - * @param location [out] If not \c NULL and a depot is found, store its location in the given address. - * @param destination [out] If not \c NULL and a depot is found, store its index in the given address. - * @param reverse [out] If not \c NULL and a depot is found, store reversal information in the given address. + * @param[out] location If not \c NULL and a depot is found, store its location in the given address. + * @param[out] destination If not \c NULL and a depot is found, store its index in the given address. + * @param[out] reverse If not \c NULL and a depot is found, store reversal information in the given address. * @return A depot has been found. */ bool Train::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) @@ -2327,9 +2307,9 @@ static const byte _initial_tile_subcoord[6][4][3] = { * @param tile The tile the train is about to enter * @param enterdir Diagonal direction the train is coming from * @param tracks Usable tracks on the new tile - * @param path_found [out] Whether a path has been found or not. + * @param[out] path_found Whether a path has been found or not. * @param do_track_reservation Path reservation is requested - * @param dest [out] State and destination of the requested path + * @param[out] dest State and destination of the requested path * @return The best track the train should follow */ static Track DoTrainPathfind(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool do_track_reservation, PBSTileInfo *dest) @@ -2439,11 +2419,11 @@ static PBSTileInfo ExtendTrainReservation(const Train *v, TrackBits *new_tracks, * @param override_railtype Whether all physically compatible railtypes should be followed. * @return True if a path to a safe stopping tile could be reserved. */ -static bool TryReserveSafeTrack(const Train *v, TileIndex tile, Trackdir td, bool override_tailtype) +static bool TryReserveSafeTrack(const Train *v, TileIndex tile, Trackdir td, bool override_railtype) { switch (_settings_game.pf.pathfinder_for_trains) { - case VPF_NPF: return NPFTrainFindNearestSafeTile(v, tile, td, override_tailtype); - case VPF_YAPF: return YapfTrainFindNearestSafeTile(v, tile, td, override_tailtype); + case VPF_NPF: return NPFTrainFindNearestSafeTile(v, tile, td, override_railtype); + case VPF_YAPF: return YapfTrainFindNearestSafeTile(v, tile, td, override_railtype); default: NOT_REACHED(); } @@ -3098,7 +3078,7 @@ static Vehicle *CheckTrainAtSignal(Vehicle *v, void *data) /* not front engine of a train, inside wormhole or depot, crashed */ if (!t->IsFrontEngine() || !(t->track & TRACK_BIT_MASK)) return NULL; - if (t->cur_speed > 5 || TrainExitDir(t->direction, t->track) != exitdir) return NULL; + if (t->cur_speed > 5 || VehicleExitDir(t->direction, t->track) != exitdir) return NULL; return t; } @@ -3361,7 +3341,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse) } /* update image of train, as well as delta XY */ - v->UpdateDeltaXY(v->direction); + v->UpdateDeltaXY(); v->x_pos = gp.x; v->y_pos = gp.y; @@ -3681,7 +3661,7 @@ static TileIndex TrainApproachingCrossingTile(const Train *v) if (!TrainCanLeaveTile(v)) return INVALID_TILE; - DiagDirection dir = TrainExitDir(v->direction, v->track); + DiagDirection dir = VehicleExitDir(v->direction, v->track); TileIndex tile = v->tile + TileOffsByDiagDir(dir); /* not a crossing || wrong axis || unusable rail (wrong type or owner) */ @@ -3718,7 +3698,7 @@ static bool TrainCheckIfLineEnds(Train *v, bool reverse) if (!TrainCanLeaveTile(v)) return true; /* Determine the non-diagonal direction in which we will exit this tile */ - DiagDirection dir = TrainExitDir(v->direction, v->track); + DiagDirection dir = VehicleExitDir(v->direction, v->track); /* Calculate next tile */ TileIndex tile = v->tile + TileOffsByDiagDir(dir); @@ -3786,7 +3766,7 @@ static bool TrainLocoHandler(Train *v, bool mode) /* Try to reserve a path when leaving the station as we * might not be marked as wanting a reservation, e.g. * when an overlength train gets turned around in a station. */ - DiagDirection dir = TrainExitDir(v->direction, v->track); + DiagDirection dir = VehicleExitDir(v->direction, v->track); if (IsRailDepotTile(v->tile) || IsTileType(v->tile, MP_TUNNELBRIDGE)) dir = INVALID_DIAGDIR; if (UpdateSignalsOnSegment(v->tile, dir, v->owner) == SIGSEG_PBS || _settings_game.pf.reserve_paths) { @@ -3923,6 +3903,8 @@ Money Train::GetRunningCost() const */ bool Train::Tick() { + PerformanceAccumulator framerate(PFE_GL_TRAINS); + this->tick_counter++; if (this->IsFrontEngine()) { diff --git a/src/tunnel_map.h b/src/tunnel_map.h index e200a1275e..d6f475d05c 100644 --- a/src/tunnel_map.h +++ b/src/tunnel_map.h @@ -58,6 +58,7 @@ static inline void MakeRoadTunnel(TileIndex t, Owner o, DiagDirection d, RoadTyp _m[t].m5 = TRANSPORT_ROAD << 2 | d; SB(_me[t].m6, 2, 4, 0); _me[t].m7 = 0; + _me[t].m8 = 0; SetRoadOwner(t, ROADTYPE_ROAD, o); if (o != OWNER_TOWN) SetRoadOwner(t, ROADTYPE_TRAM, o); SetRoadTypes(t, r); @@ -75,11 +76,12 @@ static inline void MakeRailTunnel(TileIndex t, Owner o, DiagDirection d, RailTyp SetTileType(t, MP_TUNNELBRIDGE); SetTileOwner(t, o); _m[t].m2 = 0; - _m[t].m3 = r; + _m[t].m3 = 0; _m[t].m4 = 0; _m[t].m5 = TRANSPORT_RAIL << 2 | d; SB(_me[t].m6, 2, 4, 0); _me[t].m7 = 0; + _me[t].m8 = r; } #endif /* TUNNEL_MAP_H */ diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 9ba9b26e31..06dc24e84f 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -159,40 +159,27 @@ static inline const PalSpriteID *GetBridgeSpriteTable(int index, BridgePieces ta /** - * Determines the foundation for the north bridge head, and tests if the resulting slope is valid. + * Determines the foundation for the bridge head, and tests if the resulting slope is valid. * + * @param bridge_piece Direction of the bridge head. * @param axis Axis of the bridge * @param tileh Slope of the tile under the north bridge head; returns slope on top of foundation * @param z TileZ corresponding to tileh, gets modified as well * @return Error or cost for bridge foundation */ -static CommandCost CheckBridgeSlopeNorth(Axis axis, Slope *tileh, int *z) +static CommandCost CheckBridgeSlope(BridgePieces bridge_piece, Axis axis, Slope *tileh, int *z) { + assert(bridge_piece == BRIDGE_PIECE_NORTH || bridge_piece == BRIDGE_PIECE_SOUTH); + Foundation f = GetBridgeFoundation(*tileh, axis); *z += ApplyFoundationToSlope(f, tileh); - Slope valid_inclined = (axis == AXIS_X ? SLOPE_NE : SLOPE_NW); - if ((*tileh != SLOPE_FLAT) && (*tileh != valid_inclined)) return CMD_ERROR; - - if (f == FOUNDATION_NONE) return CommandCost(); - - return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]); -} - -/** - * Determines the foundation for the south bridge head, and tests if the resulting slope is valid. - * - * @param axis Axis of the bridge - * @param tileh Slope of the tile under the south bridge head; returns slope on top of foundation - * @param z TileZ corresponding to tileh, gets modified as well - * @return Error or cost for bridge foundation - */ -static CommandCost CheckBridgeSlopeSouth(Axis axis, Slope *tileh, int *z) -{ - Foundation f = GetBridgeFoundation(*tileh, axis); - *z += ApplyFoundationToSlope(f, tileh); - - Slope valid_inclined = (axis == AXIS_X ? SLOPE_SW : SLOPE_SE); + Slope valid_inclined; + if (bridge_piece == BRIDGE_PIECE_NORTH) { + valid_inclined = (axis == AXIS_X ? SLOPE_NE : SLOPE_NW); + } else { + valid_inclined = (axis == AXIS_X ? SLOPE_SW : SLOPE_SE); + } if ((*tileh != SLOPE_FLAT) && (*tileh != valid_inclined)) return CMD_ERROR; if (f == FOUNDATION_NONE) return CommandCost(); @@ -204,6 +191,7 @@ static CommandCost CheckBridgeSlopeSouth(Axis axis, Slope *tileh, int *z) * Is a bridge of the specified type and length available? * @param bridge_type Wanted type of bridge. * @param bridge_len Wanted length of the bridge. + * @param flags Type of operation. * @return A succeeded (the requested bridge is available) or failed (it cannot be built) command. */ CommandCost CheckBridgeAvailability(BridgeType bridge_type, uint bridge_len, DoCommandFlag flags) @@ -232,7 +220,7 @@ CommandCost CheckBridgeAvailability(BridgeType bridge_type, uint bridge_len, DoC * @param p1 packed start tile coords (~ dx) * @param p2 various bitstuffed elements * - p2 = (bit 0- 7) - bridge type (hi bh) - * - p2 = (bit 8-11) - rail type or road types. + * - p2 = (bit 8-13) - rail type or road types. * - p2 = (bit 15-16) - transport type. * @param text unused * @return the cost of this operation or an error @@ -259,7 +247,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u break; case TRANSPORT_RAIL: - railtype = Extract(p2); + railtype = Extract(p2); if (!ValParamRailtype(railtype)) return CMD_ERROR; break; @@ -315,8 +303,8 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u Slope tileh_end = GetTileSlope(tile_end, &z_end); bool pbs_reservation = false; - CommandCost terraform_cost_north = CheckBridgeSlopeNorth(direction, &tileh_start, &z_start); - CommandCost terraform_cost_south = CheckBridgeSlopeSouth(direction, &tileh_end, &z_end); + CommandCost terraform_cost_north = CheckBridgeSlope(BRIDGE_PIECE_NORTH, direction, &tileh_start, &z_start); + CommandCost terraform_cost_south = CheckBridgeSlope(BRIDGE_PIECE_SOUTH, direction, &tileh_end, &z_end); /* Aqueducts can't be built of flat land. */ if (transport_type == TRANSPORT_WATER && (tileh_start == SLOPE_FLAT || tileh_end == SLOPE_FLAT)) return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION); @@ -574,7 +562,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u * Build Tunnel. * @param start_tile start tile of tunnel * @param flags type of operation - * @param p1 bit 0-3 railtype or roadtypes + * @param p1 bit 0-5 railtype or roadtypes * bit 8-9 transport type * @param p2 unused * @param text unused @@ -591,7 +579,7 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, _build_tunnel_endtile = 0; switch (transport_type) { case TRANSPORT_RAIL: - railtype = Extract(p1); + railtype = Extract(p1); if (!ValParamRailtype(railtype)) return CMD_ERROR; break; @@ -701,8 +689,23 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, /* Hide the tile from the terraforming command */ TileIndex old_first_tile = coa->first_tile; coa->first_tile = INVALID_TILE; + + /* CMD_TERRAFORM_LAND may append further items to _cleared_object_areas, + * however it will never erase or re-order existing items. + * _cleared_object_areas is a value-type SmallVector, therefore appending items + * may result in a backing-store re-allocation, which would invalidate the coa pointer. + * The index of the coa pointer into the _cleared_object_areas vector remains valid, + * and can be used safely after the CMD_TERRAFORM_LAND operation. + * Deliberately clear the coa pointer to avoid leaving dangling pointers which could + * inadvertently be dereferenced. + */ + assert(coa >= _cleared_object_areas.Begin() && coa < _cleared_object_areas.End()); + size_t coa_index = coa - _cleared_object_areas.Begin(); + assert(coa_index < UINT_MAX); // more than 2**32 cleared areas would be a bug in itself + coa = NULL; + ret = DoCommand(end_tile, end_tileh & start_tileh, 0, flags, CMD_TERRAFORM_LAND); - coa->first_tile = old_first_tile; + _cleared_object_areas[(uint)coa_index].first_tile = old_first_tile; if (ret.Failed()) return_cmd_error(STR_ERROR_UNABLE_TO_EXCAVATE_LAND); cost.AddCost(ret); } @@ -1885,11 +1888,11 @@ static CommandCost TerraformTile_TunnelBridge(TileIndex tile, DoCommandFlag flag /* Check if new slope is valid for bridges in general (so we can safely call GetBridgeFoundation()) */ if ((direction == DIAGDIR_NW) || (direction == DIAGDIR_NE)) { - CheckBridgeSlopeSouth(axis, &tileh_old, &z_old); - res = CheckBridgeSlopeSouth(axis, &tileh_new, &z_new); + CheckBridgeSlope(BRIDGE_PIECE_SOUTH, axis, &tileh_old, &z_old); + res = CheckBridgeSlope(BRIDGE_PIECE_SOUTH, axis, &tileh_new, &z_new); } else { - CheckBridgeSlopeNorth(axis, &tileh_old, &z_old); - res = CheckBridgeSlopeNorth(axis, &tileh_new, &z_new); + CheckBridgeSlope(BRIDGE_PIECE_NORTH, axis, &tileh_old, &z_old); + res = CheckBridgeSlope(BRIDGE_PIECE_NORTH, axis, &tileh_new, &z_new); } /* Surface slope is valid and remains unchanged? */ diff --git a/src/vehicle.cpp b/src/vehicle.cpp index be11e05be3..9015396a8b 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -52,6 +52,7 @@ #include "gamelog.h" #include "linkgraph/linkgraph.h" #include "linkgraph/refresh.h" +#include "framerate_type.h" #include "table/strings.h" @@ -94,7 +95,7 @@ INSTANTIATE_POOL_METHODS(Vehicle) /** * Determine shared bounds of all sprites. - * @param [out] bounds Shared bounds. + * @param[out] bounds Shared bounds. */ void VehicleSpriteSeq::GetBounds(Rect *bounds) const { @@ -219,7 +220,7 @@ bool Vehicle::NeedsServicing() const if (replace_when_old && !v->NeedsAutorenewing(c, false)) continue; /* Check refittability */ - uint32 available_cargo_types, union_mask; + CargoTypes available_cargo_types, union_mask; GetArticulatedRefitMasks(new_engine, true, &union_mask, &available_cargo_types); /* Is there anything to refit? */ if (union_mask != 0) { @@ -945,8 +946,15 @@ void CallVehicleTicks() RunVehicleDayProc(); - Station *st; - FOR_ALL_STATIONS(st) LoadUnloadStation(st); + { + PerformanceMeasurer framerate(PFE_GL_ECONOMY); + Station *st; + FOR_ALL_STATIONS(st) LoadUnloadStation(st); + } + PerformanceAccumulator::Reset(PFE_GL_TRAINS); + PerformanceAccumulator::Reset(PFE_GL_ROADVEHS); + PerformanceAccumulator::Reset(PFE_GL_SHIPS); + PerformanceAccumulator::Reset(PFE_GL_AIRCRAFT); Vehicle *v; FOR_ALL_VEHICLES(v) { @@ -2851,7 +2859,7 @@ const uint16 &Vehicle::GetGroundVehicleFlags() const /** * Calculates the set of vehicles that will be affected by a given selection. - * @param set [inout] Set of affected vehicles. + * @param[in,out] set Set of affected vehicles. * @param v First vehicle of the selection. * @param num_vehicles Number of vehicles in the selection (not counting articulated parts). * @pre \a set must be empty. diff --git a/src/vehicle_base.h b/src/vehicle_base.h index fc40f22a62..b2a2a5d7a4 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -324,7 +324,7 @@ public: uint16 load_unload_ticks; ///< Ticks to wait before starting next cycle. GroupID group_id; ///< Index of group Pool array - byte subtype; ///< subtype (Filled with values from #EffectVehicles/#TrainSubTypes/#AircraftSubTypes) + byte subtype; ///< subtype (Filled with values from #AircraftSubType/#DisasterSubType/#EffectVehicleType/#GroundVehicleSubtypeFlags) NewGRFCache grf_cache; ///< Cache of often used calculated NewGRF values VehicleCache vcache; ///< Cache of often used vehicle values. @@ -366,9 +366,8 @@ public: /** * Updates the x and y offsets and the size of the sprite used * for this vehicle. - * @param direction the direction the vehicle is facing */ - virtual void UpdateDeltaXY(Direction direction) {} + virtual void UpdateDeltaXY() {} /** * Determines the effective direction-specific vehicle movement speed. @@ -438,7 +437,7 @@ public: /** * Gets the sprite to show for the given direction * @param direction the direction the vehicle is facing - * @param [out] result Vehicle sprite sequence. + * @param[out] result Vehicle sprite sequence. */ virtual void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const { result->Clear(); } @@ -1139,7 +1138,7 @@ struct SpecializedVehicle : public Vehicle { /* Explicitly choose method to call to prevent vtable dereference - * it gives ~3% runtime improvements in games with many vehicles */ - if (update_delta) ((T *)this)->T::UpdateDeltaXY(this->direction); + if (update_delta) ((T *)this)->T::UpdateDeltaXY(); VehicleSpriteSeq seq; ((T *)this)->T::GetImage(this->direction, EIT_ON_MAP, &seq); if (force_update || this->sprite_seq != seq) { diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index 9670fa05d0..9231ad689d 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -206,7 +206,7 @@ CommandCost CmdSellVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 * @param engine_type Which engine to refit * @param new_cid Cargo type we are refitting to. * @param new_subtype New cargo subtype. - * @param [out] auto_refit_allowed The refit is allowed as an auto-refit. + * @param[out] auto_refit_allowed The refit is allowed as an auto-refit. * @return Price for refitting */ static int GetRefitCostFactor(const Vehicle *v, EngineID engine_type, CargoID new_cid, byte new_subtype, bool *auto_refit_allowed) @@ -238,7 +238,7 @@ static int GetRefitCostFactor(const Vehicle *v, EngineID engine_type, CargoID ne * @param engine_type Which engine to refit * @param new_cid Cargo type we are refitting to. * @param new_subtype New cargo subtype. - * @param [out] auto_refit_allowed The refit is allowed as an auto-refit. + * @param[out] auto_refit_allowed The refit is allowed as an auto-refit. * @return Price for refitting */ static CommandCost GetRefitCost(const Vehicle *v, EngineID engine_type, CargoID new_cid, byte new_subtype, bool *auto_refit_allowed) @@ -464,7 +464,7 @@ CommandCost CmdRefitVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint byte new_subtype = GB(p2, 8, 8); if (new_cid >= NUM_CARGO) return CMD_ERROR; - /* For ships and aircrafts there is always only one. */ + /* For ships and aircraft there is always only one. */ bool only_this = HasBit(p2, 7) || front->type == VEH_SHIP || front->type == VEH_AIRCRAFT; uint8 num_vehicles = GB(p2, 16, 8); @@ -542,7 +542,8 @@ CommandCost CmdStartStopVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, case VEH_AIRCRAFT: { Aircraft *a = Aircraft::From(v); /* cannot stop airplane when in flight, or when taking off / landing */ - if (!(v->vehstatus & VS_CRASHED) && a->state >= STARTTAKEOFF && a->state < TERM7) return_cmd_error(STR_ERROR_AIRCRAFT_IS_IN_FLIGHT); + if (a->state >= STARTTAKEOFF && a->state < TERM7) return_cmd_error(STR_ERROR_AIRCRAFT_IS_IN_FLIGHT); + if (HasBit(a->flags, VAF_HELI_DIRECT_DESCENT)) return_cmd_error(STR_ERROR_AIRCRAFT_IS_IN_FLIGHT); break; } diff --git a/src/vehicle_func.h b/src/vehicle_func.h index 9eb6b91219..17ec9e28da 100644 --- a/src/vehicle_func.h +++ b/src/vehicle_func.h @@ -31,7 +31,7 @@ static const Money VEHICLE_PROFIT_THRESHOLD = 10000; ///< Threshold for a /** * Helper to check whether an image index is valid for a particular vehicle. - * @param The type of vehicle. + * @tparam T The type of vehicle. * @param image_index The image index to check. * @return True iff the image index is valid. */ diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 8ebd73a8af..4926f7a4fc 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -416,7 +416,7 @@ struct RefitWindow : public Window { do { if (v->type == VEH_TRAIN && !vehicles_to_refit.Contains(v->index)) continue; const Engine *e = v->GetEngine(); - uint32 cmask = e->info.refit_mask; + CargoTypes cmask = e->info.refit_mask; byte callback_mask = e->info.callback_mask; /* Skip this engine if it does not carry anything */ @@ -681,7 +681,7 @@ struct RefitWindow : public Window { /** * Gets the #StringID to use for displaying capacity. - * @param Cargo and cargo subtype to check for capacity. + * @param option Cargo and cargo subtype to check for capacity. * @return INVALID_STRING_ID if there is no capacity. StringID to use in any other case. * @post String parameters have been set. */ @@ -817,8 +817,8 @@ struct RefitWindow : public Window { Vehicle *v = Vehicle::Get(this->window_number); this->selected_vehicle = v->index; this->num_vehicles = UINT8_MAX; + FALLTHROUGH; } - FALLTHROUGH; case 2: { // The vehicle selection has changed; rebuild the entire list. if (!gui_scope) break; @@ -843,8 +843,8 @@ struct RefitWindow : public Window { this->information_width = max_width; this->ReInit(); } + FALLTHROUGH; } - FALLTHROUGH; case 1: // A new cargo has been selected. if (!gui_scope) break; @@ -905,8 +905,8 @@ struct RefitWindow : public Window { if (_ctrl_pressed) this->num_vehicles = UINT8_MAX; break; } + FALLTHROUGH; } - FALLTHROUGH; default: /* Clear the selection. */ @@ -940,8 +940,8 @@ struct RefitWindow : public Window { this->InvalidateData(1); if (click_count == 1) break; + FALLTHROUGH; } - FALLTHROUGH; case WID_VR_REFIT: // refit button if (this->cargo != NULL) { @@ -1043,9 +1043,9 @@ void ShowVehicleRefitWindow(const Vehicle *v, VehicleOrderID order, Window *pare uint ShowRefitOptionsList(int left, int right, int y, EngineID engine) { /* List of cargo types of this engine */ - uint32 cmask = GetUnionOfArticulatedRefitMasks(engine, false); + CargoTypes cmask = GetUnionOfArticulatedRefitMasks(engine, false); /* List of cargo types available in this climate */ - uint32 lmask = _cargo_mask; + CargoTypes lmask = _cargo_mask; /* Draw nothing if the engine is not refittable */ if (HasAtMostOneBit(cmask)) return y; @@ -2370,7 +2370,7 @@ static const uint32 _vehicle_command_translation_table[][4] = { CMD_REVERSE_TRAIN_DIRECTION | CMD_MSG(STR_ERROR_CAN_T_REVERSE_DIRECTION_TRAIN), CMD_TURN_ROADVEH | CMD_MSG(STR_ERROR_CAN_T_MAKE_ROAD_VEHICLE_TURN), 0xffffffff, // invalid for ships - 0xffffffff // invalid for aircrafts + 0xffffffff // invalid for aircraft }, }; diff --git a/src/vehicle_type.h b/src/vehicle_type.h index 0921b39e36..f3e7d535fd 100644 --- a/src/vehicle_type.h +++ b/src/vehicle_type.h @@ -17,6 +17,8 @@ /** The type all our vehicle IDs have. */ typedef uint32 VehicleID; +static const int GROUND_ACCELERATION = 9800; ///< Acceleration due to gravity, 9.8 m/s^2 + /** Available vehicle types. */ enum VehicleType { VEH_BEGIN, diff --git a/src/video/allegro_v.cpp b/src/video/allegro_v.cpp index 01628f99cd..960d7fb7c8 100644 --- a/src/video/allegro_v.cpp +++ b/src/video/allegro_v.cpp @@ -24,6 +24,7 @@ #include "../network/network.h" #include "../core/random_func.hpp" #include "../core/math_func.hpp" +#include "../framerate_type.h" #include "allegro_v.h" #include @@ -56,6 +57,8 @@ void VideoDriver_Allegro::MakeDirty(int left, int top, int width, int height) static void DrawSurfaceToScreen() { + PerformanceMeasurer framerate(PFE_VIDEO); + int n = _num_dirty_rects; if (n == 0) return; @@ -458,7 +461,7 @@ void VideoDriver_Allegro::Stop() if (--_allegro_instance_count == 0) allegro_exit(); } -#if defined(UNIX) || defined(__OS2__) || defined(PSP) || defined(DOS) +#if defined(UNIX) || defined(__OS2__) || defined(DOS) # include /* gettimeofday */ static uint32 GetTime() diff --git a/src/video/cocoa/cocoa_v.mm b/src/video/cocoa/cocoa_v.mm index f8412e3877..d165610245 100644 --- a/src/video/cocoa/cocoa_v.mm +++ b/src/video/cocoa/cocoa_v.mm @@ -214,6 +214,12 @@ static void setupApplication() } #endif + /* Disable the system-wide tab feature as we only have one window. */ + if ([ NSWindow respondsToSelector:@selector(setAllowsAutomaticWindowTabbing:) ]) { + /* We use nil instead of NO as withObject requires an id. */ + [ NSWindow performSelector:@selector(setAllowsAutomaticWindowTabbing:) withObject:nil]; + } + /* Become the front process, important when start from the command line. */ [ [ NSApplication sharedApplication ] activateIgnoringOtherApps:YES ]; diff --git a/src/video/cocoa/event.mm b/src/video/cocoa/event.mm index f4a7c2b421..30b6563b68 100644 --- a/src/video/cocoa/event.mm +++ b/src/video/cocoa/event.mm @@ -587,12 +587,12 @@ static bool QZ_PollEvent() while (_current_magnification >= 1.0f) { _current_magnification -= 1.0f; - _cursor.wheel++; + _cursor.wheel--; HandleMouseEvents(); } while (_current_magnification <= -1.0f) { _current_magnification += 1.0f; - _cursor.wheel--; + _cursor.wheel++; HandleMouseEvents(); } break; diff --git a/src/video/cocoa/wnd_quartz.mm b/src/video/cocoa/wnd_quartz.mm index d42749bac5..4245a3c183 100644 --- a/src/video/cocoa/wnd_quartz.mm +++ b/src/video/cocoa/wnd_quartz.mm @@ -33,6 +33,7 @@ #include "cocoa_v.h" #include "../../core/math_func.hpp" #include "../../gfx_func.h" +#include "../../framerate_type.h" /* On some old versions of MAC OS this may not be defined. * Those versions generally only produce code for PPC. So it should be safe to @@ -431,6 +432,8 @@ WindowQuartzSubdriver::~WindowQuartzSubdriver() void WindowQuartzSubdriver::Draw(bool force_update) { + PerformanceMeasurer framerate(PFE_VIDEO); + /* Check if we need to do anything */ if (this->num_dirty_rects == 0 || [ this->window isMiniaturized ]) return; @@ -544,7 +547,7 @@ NSPoint WindowQuartzSubdriver::GetMouseLocation(NSEvent *event) if ( [ event window ] == nil) { #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 - if ([ this->cocoaview respondsToSelector:@selector(convertRectFromScreen:) ]) { + if ([ [ this->cocoaview window ] respondsToSelector:@selector(convertRectFromScreen:) ]) { pt = [ this->cocoaview convertPoint:[ [ this->cocoaview window ] convertRectFromScreen:NSMakeRect([ event locationInWindow ].x, [ event locationInWindow ].y, 0, 0) ].origin fromView:nil ]; } else diff --git a/src/video/cocoa/wnd_quickdraw.mm b/src/video/cocoa/wnd_quickdraw.mm index df10d87739..8475efb0fd 100644 --- a/src/video/cocoa/wnd_quickdraw.mm +++ b/src/video/cocoa/wnd_quickdraw.mm @@ -32,6 +32,7 @@ #include "cocoa_v.h" #include "../../core/math_func.hpp" #include "../../gfx_func.h" +#include "../../framerate_type.h" /** * Important notice regarding all modifications!!!!!!! @@ -361,6 +362,8 @@ WindowQuickdrawSubdriver::~WindowQuickdrawSubdriver() void WindowQuickdrawSubdriver::Draw(bool force_update) { + PerformanceMeasurer framerate(PFE_VIDEO); + /* Check if we need to do anything */ if (this->num_dirty_rects == 0 || [ this->window isMiniaturized ]) return; diff --git a/src/video/dedicated_v.cpp b/src/video/dedicated_v.cpp index 5e2be481c9..47fa64231a 100644 --- a/src/video/dedicated_v.cpp +++ b/src/video/dedicated_v.cpp @@ -57,16 +57,12 @@ static void OS2_SwitchToConsoleMode() } #endif -#if defined(UNIX) || defined(PSP) +#if defined(UNIX) # include /* gettimeofday */ # include # include # include # define STDIN 0 /* file descriptor for standard input */ -# if defined(PSP) -# include -# include -# endif /* PSP */ /* Signal handlers */ static void DedicatedSignalHandler(int sig) @@ -77,11 +73,9 @@ static void DedicatedSignalHandler(int sig) } #endif -#if defined(WIN32) +#if defined(_WIN32) # include /* GetTickCount */ -# if !defined(WINCE) -# include -# endif +# include # include # include # include "../os/windows/win32.h" @@ -92,10 +86,6 @@ static char _win_console_thread_buffer[200]; /* Windows Console thread. Just loop and signal when input has been received */ static void WINAPI CheckForConsoleInput() { -#if defined(WINCE) - /* WinCE doesn't support console stuff */ - return; -#else SetWin32ThreadName(-1, "ottd:win-console"); DWORD nb; @@ -110,7 +100,6 @@ static void WINAPI CheckForConsoleInput() SetEvent(_hInputReady); WaitForSingleObject(_hWaitForInputHandling, INFINITE); } -#endif } static void CreateWindowsConsoleThread() @@ -161,9 +150,7 @@ const char *VideoDriver_Dedicated::Start(const char * const *parm) ScreenSizeChanged(); BlitterFactory::GetCurrentBlitter()->PostResize(); -#if defined(WINCE) - /* WinCE doesn't support console stuff */ -#elif defined(WIN32) +#if defined(_WIN32) /* For win32 we need to allocate a console (debug mode does the same) */ CreateConsole(); CreateWindowsConsoleThread(); @@ -186,7 +173,7 @@ const char *VideoDriver_Dedicated::Start(const char * const *parm) void VideoDriver_Dedicated::Stop() { -#ifdef WIN32 +#ifdef _WIN32 CloseWindowsConsoleThread(); #endif free(_dedicated_video_mem); @@ -196,7 +183,7 @@ void VideoDriver_Dedicated::MakeDirty(int left, int top, int width, int height) bool VideoDriver_Dedicated::ChangeResolution(int w, int h) { return false; } bool VideoDriver_Dedicated::ToggleFullscreen(bool fs) { return false; } -#if defined(UNIX) || defined(__OS2__) || defined(PSP) +#if defined(UNIX) || defined(__OS2__) static bool InputWaiting() { struct timeval tv; @@ -242,7 +229,7 @@ static void DedicatedHandleKeyInput() if (_exit_game) return; -#if defined(UNIX) || defined(__OS2__) || defined(PSP) +#if defined(UNIX) || defined(__OS2__) if (fgets(input_line, lengthof(input_line), stdin) == NULL) return; #else /* Handle console input, and signal console thread, it can accept input again */ @@ -269,7 +256,7 @@ void VideoDriver_Dedicated::MainLoop() uint32 next_tick = cur_ticks + MILLISECONDS_PER_TICK; /* Signal handlers */ -#if defined(UNIX) || defined(PSP) +#if defined(UNIX) signal(SIGTERM, DedicatedSignalHandler); signal(SIGINT, DedicatedSignalHandler); signal(SIGQUIT, DedicatedSignalHandler); diff --git a/src/video/sdl_v.cpp b/src/video/sdl_v.cpp index 3668f86020..e96decb451 100644 --- a/src/video/sdl_v.cpp +++ b/src/video/sdl_v.cpp @@ -23,6 +23,7 @@ #include "../core/random_func.hpp" #include "../core/math_func.hpp" #include "../fileio_func.h" +#include "../framerate_type.h" #include "sdl_v.h" #include @@ -148,6 +149,8 @@ static void CheckPaletteAnim() static void DrawSurfaceToScreen() { + PerformanceMeasurer framerate(PFE_VIDEO); + int n = _num_dirty_rects; if (n == 0) return; @@ -261,7 +264,7 @@ static void GetAvailableVideoMode(uint *w, uint *h) *h = _resolutions[best].height; } -#ifdef WIN32 +#ifdef _WIN32 /* Let's redefine the LoadBMP macro with because we are dynamically * loading SDL and need to 'SDL_CALL' all functions */ #undef SDL_LoadBMP @@ -323,7 +326,7 @@ bool VideoDriver_SDL::CreateMainSurface(uint w, uint h) want_hwpalette = _use_hwpalette; } - if (want_hwpalette) DEBUG(driver, 1, "SDL: requesting hardware palete"); + if (want_hwpalette) DEBUG(driver, 1, "SDL: requesting hardware palette"); /* Free any previously allocated shadow surface */ if (_sdl_screen != NULL && _sdl_screen != _sdl_realscreen) SDL_CALL SDL_FreeSurface(_sdl_screen); @@ -497,7 +500,7 @@ static uint ConvertSdlKeyIntoMy(SDL_keysym *sym, WChar *character) } /* check scancode for BACKQUOTE key, because we want the key left of "1", not anything else (on non-US keyboards) */ -#if defined(WIN32) || defined(__OS2__) +#if defined(_WIN32) || defined(__OS2__) if (sym->scancode == 41) key = WKC_BACKQUOTE; #elif defined(__APPLE__) if (sym->scancode == 10) key = WKC_BACKQUOTE; diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp index 4534b87bec..0655065a6c 100644 --- a/src/video/win32_v.cpp +++ b/src/video/win32_v.cpp @@ -23,6 +23,7 @@ #include "../progress.h" #include "../window_gui.h" #include "../window_func.h" +#include "../framerate_type.h" #include "win32_v.h" #include #include @@ -60,9 +61,7 @@ bool _force_full_redraw; bool _window_maximize; uint _display_hz; static Dimension _bck_resolution; -#if !defined(WINCE) || _WIN32_WCE >= 0x400 DWORD _imm_props; -#endif /** Whether the drawing is/may be done in a separate thread. */ static bool _draw_threaded; @@ -272,9 +271,6 @@ bool VideoDriver_Win32::MakeWindow(bool full_screen) _wnd.main_wnd = 0; } -#if defined(WINCE) - /* WinCE is always fullscreen */ -#else if (full_screen) { DEVMODE settings; @@ -318,7 +314,6 @@ bool VideoDriver_Win32::MakeWindow(bool full_screen) _wnd.width = _bck_resolution.width; _wnd.height = _bck_resolution.height; } -#endif { RECT r; @@ -337,22 +332,20 @@ bool VideoDriver_Win32::MakeWindow(bool full_screen) SetRect(&r, 0, 0, _wnd.width, _wnd.height); } -#if !defined(WINCE) AdjustWindowRect(&r, style, FALSE); -#endif w = r.right - r.left; h = r.bottom - r.top; if (_wnd.main_wnd != NULL) { if (!_window_maximize) SetWindowPos(_wnd.main_wnd, 0, 0, 0, w, h, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE); } else { - TCHAR Windowtitle[50]; int x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2; int y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2; - _sntprintf(Windowtitle, lengthof(Windowtitle), _T("OpenTTD %s"), MB_TO_WIDE(_openttd_revision)); + char window_title[64]; + seprintf(window_title, lastof(window_title), "OpenTTD %s", _openttd_revision); - _wnd.main_wnd = CreateWindow(_T("OTTD"), Windowtitle, style, x, y, w, h, 0, 0, GetModuleHandle(NULL), 0); + _wnd.main_wnd = CreateWindow(_T("OTTD"), MB_TO_WIDE(window_title), style, x, y, w, h, 0, 0, GetModuleHandle(NULL), 0); if (_wnd.main_wnd == NULL) usererror("CreateWindow failed"); ShowWindow(_wnd.main_wnd, showstyle); } @@ -367,6 +360,8 @@ bool VideoDriver_Win32::MakeWindow(bool full_screen) /** Do palette animation and blit to the window. */ static void PaintWindow(HDC dc) { + PerformanceMeasurer framerate(PFE_VIDEO); + HDC dc2 = CreateCompatibleDC(dc); HBITMAP old_bmp = (HBITMAP)SelectObject(dc2, _wnd.dib_sect); HPALETTE old_palette = SelectPalette(dc, _wnd.gdi_palette, FALSE); @@ -497,7 +492,6 @@ static LRESULT HandleCharMsg(uint keycode, WChar charcode) return 0; } -#if !defined(WINCE) || _WIN32_WCE >= 0x400 /** Should we draw the composition string ourself, i.e is this a normal IME? */ static bool DrawIMECompositionString() { @@ -634,15 +628,6 @@ static void CancelIMEComposition(HWND hwnd) HandleTextInput(NULL, true); } -#else - -static bool DrawIMECompositionString() { return false; } -static void SetCompositionPos(HWND hwnd) {} -static void SetCandidatePos(HWND hwnd) {} -static void CancelIMEComposition(HWND hwnd) {} - -#endif /* !defined(WINCE) || _WIN32_WCE >= 0x400 */ - static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static uint32 keycode = 0; @@ -653,9 +638,7 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP case WM_CREATE: SetTimer(hwnd, TID_POLLMOUSE, MOUSE_POLL_DELAY, (TIMERPROC)TrackMouseTimerProc); SetCompositionPos(hwnd); -#if !defined(WINCE) || _WIN32_WCE >= 0x400 _imm_props = ImmGetProperty(GetKeyboardLayout(0), IGP_PROPERTY); -#endif break; case WM_ENTERSIZEMOVE: @@ -784,7 +767,6 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP return 0; } -#if !defined(WINCE) || _WIN32_WCE >= 0x400 case WM_INPUTLANGCHANGE: _imm_props = ImmGetProperty(GetKeyboardLayout(0), IGP_PROPERTY); break; @@ -820,7 +802,6 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP } HandleCharMsg(0, GB(wParam, 0, 8)); return 0; -#endif #endif case WM_DEADCHAR: @@ -914,7 +895,6 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP } return 0; -#if !defined(WINCE) case WM_SIZING: { RECT *r = (RECT*)lParam; RECT r2; @@ -972,7 +952,6 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP } return TRUE; } -#endif /* needed for wheel */ #if !defined(WM_MOUSEWHEEL) @@ -1003,7 +982,6 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP _wnd.has_focus = false; break; -#if !defined(WINCE) case WM_ACTIVATE: { /* Don't do anything if we are closing openttd */ if (_exit_game) break; @@ -1023,7 +1001,6 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP } break; } -#endif } return DefWindowProc(hwnd, msg, wParam, lParam); @@ -1112,10 +1089,6 @@ static const Dimension default_resolutions[] = { static void FindResolutions() { uint n = 0; -#if defined(WINCE) - /* EnumDisplaySettingsW is only supported in CE 4.2+ - * XXX -- One might argue that we assume 4.2+ on every system. Then we can use this function safely */ -#else uint i; DEVMODEA dm; @@ -1145,7 +1118,6 @@ static void FindResolutions() } } } -#endif /* We have found no resolutions, show the default list */ if (n == 0) { @@ -1191,9 +1163,7 @@ void VideoDriver_Win32::Stop() DeleteObject(_wnd.dib_sect); DestroyWindow(_wnd.main_wnd); -#if !defined(WINCE) if (_wnd.fullscreen) ChangeDisplaySettings(NULL, 0); -#endif MyShowCursor(true); } @@ -1295,10 +1265,8 @@ void VideoDriver_Win32::MainLoop() if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged(); -#if !defined(WINCE) /* Flush GDI buffer to ensure we don't conflict with the drawing thread. */ GdiFlush(); -#endif /* The game loop is the part that can run asynchronously. * The rest except sleeping can't. */ @@ -1311,10 +1279,8 @@ void VideoDriver_Win32::MainLoop() UpdateWindows(); CheckPaletteAnim(); } else { -#if !defined(WINCE) /* Flush GDI buffer to ensure we don't conflict with the drawing thread. */ GdiFlush(); -#endif /* Release the thread while sleeping */ if (_draw_threaded) _draw_mutex->EndCritical(); diff --git a/src/viewport.cpp b/src/viewport.cpp index 6de827b4ee..350bb92381 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -87,6 +87,7 @@ #include "company_base.h" #include "command_func.h" #include "network/network_func.h" +#include "framerate_type.h" #include @@ -1654,6 +1655,8 @@ static inline void ViewportDraw(const ViewPort *vp, int left, int top, int right */ void Window::DrawViewport() const { + PerformanceAccumulator framerate(PFE_DRAWWORLD); + DrawPixelInfo *dpi = _cur_dpi; dpi->left += this->left; @@ -2428,7 +2431,6 @@ void UpdateTileSelection() break; default: NOT_REACHED(); - break; } _thd.new_pos.x = x1 & ~TILE_UNIT_MASK; _thd.new_pos.y = y1 & ~TILE_UNIT_MASK; @@ -2636,8 +2638,8 @@ static int CalcHeightdiff(HighLightStyle style, uint distance, TileIndex start_t byte style_t = (byte)(TileX(end_tile) > TileX(start_tile)); start_tile = TILE_ADD(start_tile, ToTileIndexDiff(heightdiff_area_by_dir[style_t])); end_tile = TILE_ADD(end_tile, ToTileIndexDiff(heightdiff_area_by_dir[2 + style_t])); + FALLTHROUGH; } - FALLTHROUGH; case HT_POINT: h0 = TileHeight(start_tile); diff --git a/src/viewport_gui.cpp b/src/viewport_gui.cpp index cbd300dec7..9c89a85f84 100644 --- a/src/viewport_gui.cpp +++ b/src/viewport_gui.cpp @@ -138,7 +138,7 @@ public: virtual void OnMouseWheel(int wheel) { - if (_settings_client.gui.scrollwheel_scrolling == 0) { + if (_settings_client.gui.scrollwheel_scrolling != 2) { ZoomInOrOutToCursorWindow(wheel < 0, this); } } diff --git a/src/viewport_sprite_sorter_sse4.cpp b/src/viewport_sprite_sorter_sse4.cpp index 05a7f8aa1c..fb78c51c86 100644 --- a/src/viewport_sprite_sorter_sse4.cpp +++ b/src/viewport_sprite_sorter_sse4.cpp @@ -7,7 +7,7 @@ * 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 . */ -/** @file viewport_sprite_sorter_sse.cpp Sprite sorter that uses SSE4.1. */ +/** @file viewport_sprite_sorter_sse4.cpp Sprite sorter that uses SSE4.1. */ #ifdef WITH_SSE diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 07b6a95507..31dafe57fa 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -895,7 +895,7 @@ static void GetTileDesc_Water(TileIndex tile, TileDesc *td) case WATER_CLASS_SEA: td->str = STR_LAI_WATER_DESCRIPTION_WATER; break; case WATER_CLASS_CANAL: td->str = STR_LAI_WATER_DESCRIPTION_CANAL; break; case WATER_CLASS_RIVER: td->str = STR_LAI_WATER_DESCRIPTION_RIVER; break; - default: NOT_REACHED(); break; + default: NOT_REACHED(); } break; case WATER_TILE_COAST: td->str = STR_LAI_WATER_DESCRIPTION_COAST_OR_RIVERBANK; break; @@ -904,7 +904,7 @@ static void GetTileDesc_Water(TileIndex tile, TileDesc *td) td->str = STR_LAI_WATER_DESCRIPTION_SHIP_DEPOT; td->build_date = Depot::GetByTile(tile)->build_date; break; - default: NOT_REACHED(); break; + default: NOT_REACHED(); } td->owner[0] = GetTileOwner(tile); @@ -1218,7 +1218,7 @@ void ConvertGroundTilesIntoWaterTiles() default: uint dir; FOR_EACH_SET_BIT(dir, _flood_from_dirs[slope & ~SLOPE_STEEP]) { - TileIndex dest = TILE_ADD(tile, TileOffsByDir((Direction)dir)); + TileIndex dest = TileAddByDir(tile, (Direction)dir); Slope slope_dest = GetTileSlope(dest) & ~SLOPE_STEEP; if (slope_dest == SLOPE_FLAT || IsSlopeWithOneCornerRaised(slope_dest)) { MakeShore(tile); diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index 54489fa457..639dce13bc 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -148,7 +148,8 @@ extern CommandCost CanExpandRailStation(const BaseStation *st, TileArea &new_ta, * @param start_tile northern most tile where waypoint will be built * @param flags type of operation * @param p1 various bitstuffed elements - * - p1 = (bit 4) - orientation (Axis) + * - p1 = (bit 0- 5) - railtype (not used) + * - p1 = (bit 6) - orientation (Axis) * - p1 = (bit 8-15) - width of waypoint * - p1 = (bit 16-23) - height of waypoint * - p1 = (bit 24) - allow waypoints directly adjacent to other waypoints. @@ -161,7 +162,7 @@ extern CommandCost CanExpandRailStation(const BaseStation *st, TileArea &new_ta, CommandCost CmdBuildRailWaypoint(TileIndex start_tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { /* Unpack parameters */ - Axis axis = Extract(p1); + Axis axis = Extract(p1); byte width = GB(p1, 8, 8); byte height = GB(p1, 16, 8); bool adjacent = HasBit(p1, 24); diff --git a/src/widget.cpp b/src/widget.cpp index 4e411ada23..73190f5e67 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -755,7 +755,7 @@ NWidgetBase::NWidgetBase(WidgetType tp) : ZeroedMemoryAllocator() */ /** - * @fn void FillNestedArray(NWidgetBase **array, uint length) + * @fn void NWidgetBase::FillNestedArray(NWidgetBase **array, uint length) * Fill the Window::nested_array array with pointers to nested widgets in the tree. * @param array Base pointer of the array. * @param length Length of the array. @@ -1673,10 +1673,10 @@ NWidgetCore *NWidgetMatrix::GetWidgetFromPos(int x, int y) /** * Get the different offsets that are influenced by scrolling. - * @param [out] start_x The start position in columns (index of the left-most column, swapped in RTL). - * @param [out] start_y The start position in rows. - * @param [out] base_offs_x The base horizontal offset in pixels (X position of the column \a start_x). - * @param [out] base_offs_y The base vertical offset in pixels (Y position of the column \a start_y). + * @param[out] start_x The start position in columns (index of the left-most column, swapped in RTL). + * @param[out] start_y The start position in rows. + * @param[out] base_offs_x The base horizontal offset in pixels (X position of the column \a start_x). + * @param[out] base_offs_y The base vertical offset in pixels (Y position of the column \a start_y). */ void NWidgetMatrix::GetScrollOffsets(int &start_x, int &start_y, int &base_offs_x, int &base_offs_y) { @@ -2805,7 +2805,7 @@ NWidgetContainer *MakeNWidgets(const NWidgetPart *parts, int count, int *biggest * @param parts Array with parts of the widgets. * @param count Length of the \a parts array. * @param biggest_index Pointer to biggest nested widget index collected in the tree. - * @param [out] shade_select Pointer to the inserted shade selection widget (\c NULL if not unserted). + * @param[out] shade_select Pointer to the inserted shade selection widget (\c NULL if not unserted). * @return Root of the nested widget tree, a vertical container containing the entire GUI. * @ingroup NestedWidgetParts * @pre \c biggest_index != NULL diff --git a/src/widget_type.h b/src/widget_type.h index 163d45800e..33fb8bce08 100644 --- a/src/widget_type.h +++ b/src/widget_type.h @@ -257,7 +257,7 @@ enum NWidgetDisplay { NDB_SHADE_GREY = 3, ///< Shade viewport to grey-scale. NDB_SHADE_DIMMED = 4, ///< Display dimmed colours in the viewport. /* Button dropdown widget. */ - NDB_DROPDOWN_ACTIVE = 5, ///< Dropdown menu of the button dropdown widget is active. @see #NWID_BUTTON_DRPDOWN + NDB_DROPDOWN_ACTIVE = 5, ///< Dropdown menu of the button dropdown widget is active. @see #NWID_BUTTON_DROPDOWN /* Scrollbar widget. */ NDB_SCROLLBAR_UP = 6, ///< Up-button is lowered bit. NDB_SCROLLBAR_DOWN = 7, ///< Down-button is lowered bit. @@ -400,7 +400,7 @@ enum StackedZeroSizePlanes { * There are also a number of special planes (defined in #StackedZeroSizePlanes) that have zero size in one direction (and are stretchable in * the other direction) or have zero size in both directions. They are used to make all child planes of the widget disappear. * Unlike switching between the regular display planes (that all have the same size), switching from or to one of the zero-sized planes means that - * a #Windows::ReInit() is needed to re-initialize the window since its size changes. + * a #Window::ReInit() is needed to re-initialize the window since its size changes. */ class NWidgetStacked : public NWidgetContainer { public: @@ -567,7 +567,7 @@ private: * Nested widget to display a viewport in a window. * After initializing the nested widget tree, call #InitializeViewport(). After changing the window size, * call #UpdateViewportCoordinates() eg from Window::OnResize(). - * If the #display_flags field contains the #ND_NO_TRANSPARENCY bit, the viewport will disable transparency. + * If the #disp_flags field contains the #ND_NO_TRANSPARENCY bit, the viewport will disable transparency. * Shading to grey-scale is controlled with the #ND_SHADE_GREY bit (used for B&W news papers), the #ND_SHADE_DIMMED gives dimmed colours (for colour news papers). * @todo Class derives from #NWidgetCore, but does not use #colour, #widget_data, or #tool_tip. * @ingroup NestedWidgets @@ -1124,8 +1124,8 @@ static inline NWidgetPart NWidget(WidgetType tp, Colours col, int16 idx = -1) /** * Widget part function for starting a new horizontal container, vertical container, or spacer widget. - * @param tp Type of the new nested widget, #NWID_HORIZONTAL(_LTR), #NWID_VERTICAL, #NWID_SPACER, #NWID_SELECTION, and #NWID_MATRIX. - * @param cont_flags Flags for the containers (#NWID_HORIZONTAL(_LTR) and #NWID_VERTICAL). + * @param tp Type of the new nested widget, #NWID_HORIZONTAL, #NWID_VERTICAL, #NWID_SPACER, #NWID_SELECTION, and #NWID_MATRIX. + * @param cont_flags Flags for the containers (#NWID_HORIZONTAL and #NWID_VERTICAL). * @ingroup NestedWidgetParts */ static inline NWidgetPart NWidget(WidgetType tp, NWidContainerFlags cont_flags = NC_NONE) diff --git a/src/widgets/cheat_widget.h b/src/widgets/cheat_widget.h index 78758f7b11..3209cae239 100644 --- a/src/widgets/cheat_widget.h +++ b/src/widgets/cheat_widget.h @@ -12,7 +12,7 @@ #ifndef WIDGETS_CHEAT_WIDGET_H #define WIDGETS_CHEAT_WIDGET_H -/** Widgets of the #CheatWindow class.. */ +/** Widgets of the #CheatWindow class. */ enum CheatWidgets { WID_C_PANEL, ///< Panel where all cheats are shown in. }; diff --git a/src/widgets/dropdown.cpp b/src/widgets/dropdown.cpp index d4c229cb1f..f8ddf55695 100644 --- a/src/widgets/dropdown.cpp +++ b/src/widgets/dropdown.cpp @@ -111,7 +111,6 @@ struct DropdownWindow : Window { * @param size Size of the dropdown menu window. * @param wi_colour Colour of the parent widget. * @param scroll Dropdown menu has a scrollbar. - * @param widget Widgets of the dropdown menu window. */ DropdownWindow(Window *parent, const DropDownList *list, int selected, int button, bool instant_close, const Point &position, const Dimension &size, Colours wi_colour, bool scroll) : Window(&_dropdown_desc) @@ -182,7 +181,7 @@ struct DropdownWindow : Window { /** * Find the dropdown item under the cursor. - * @param value [out] Selected item, if function returns \c true. + * @param[out] value Selected item, if function returns \c true. * @return Cursor points to a dropdown item. */ bool GetDropDownItem(int &value) diff --git a/src/widgets/fios_widget.h b/src/widgets/fios_widget.h index c94655d767..2351f8035e 100644 --- a/src/widgets/fios_widget.h +++ b/src/widgets/fios_widget.h @@ -17,6 +17,7 @@ enum SaveLoadWidgets { WID_SL_CAPTION, ///< Caption of the window. WID_SL_SORT_BYNAME, ///< Sort by name button. WID_SL_SORT_BYDATE, ///< Sort by date button. + WID_SL_FILTER, ///< Filter list of files WID_SL_BACKGROUND, ///< Background of window. WID_SL_FILE_BACKGROUND, ///< Background of file selection. WID_SL_HOME_BUTTON, ///< Home button. diff --git a/src/widgets/framerate_widget.h b/src/widgets/framerate_widget.h new file mode 100644 index 0000000000..388599537c --- /dev/null +++ b/src/widgets/framerate_widget.h @@ -0,0 +1,33 @@ +/* $Id$ */ + +/* + * 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 . + */ + +/** @file framerate_widget.h Types related to the framerate windows widgets. */ + +#ifndef WIDGETS_FRAMERATE_WIDGET_H +#define WIDGETS_FRAMERATE_WIDGET_H + +/** Widgets of the #FramerateWindow class. */ +enum FramerateWindowWidgets { + WID_FRW_CAPTION, + WID_FRW_RATE_GAMELOOP, + WID_FRW_RATE_DRAWING, + WID_FRW_RATE_FACTOR, + WID_FRW_INFO_DATA_POINTS, + WID_FRW_TIMES_NAMES, + WID_FRW_TIMES_CURRENT, + WID_FRW_TIMES_AVERAGE, +}; + +/** Widgets of the #FrametimeGraphWindow class. */ +enum FrametimeGraphWindowWidgets { + WID_FGW_CAPTION, + WID_FGW_GRAPH, +}; + +#endif /* WIDGETS_FRAMERATE_WIDGET_H */ diff --git a/src/widgets/music_widget.h b/src/widgets/music_widget.h index 3a99bc6150..c8e6a98186 100644 --- a/src/widgets/music_widget.h +++ b/src/widgets/music_widget.h @@ -14,9 +14,11 @@ /** Widgets of the #MusicTrackSelectionWindow class. */ enum MusicTrackSelectionWidgets { + WID_MTS_CAPTION, ///< Window caption. WID_MTS_LIST_LEFT, ///< Left button. WID_MTS_PLAYLIST, ///< Playlist. WID_MTS_LIST_RIGHT, ///< Right button. + WID_MTS_MUSICSET, ///< Music set selection. WID_MTS_ALL, ///< All button. WID_MTS_OLD, ///< Old button. WID_MTS_NEW, ///< New button. diff --git a/src/widgets/toolbar_widget.h b/src/widgets/toolbar_widget.h index 434a238acc..c317fc9574 100644 --- a/src/widgets/toolbar_widget.h +++ b/src/widgets/toolbar_widget.h @@ -33,7 +33,7 @@ enum ToolbarNormalWidgets { WID_TN_TRAINS = WID_TN_VEHICLE_START, ///< Train menu. WID_TN_ROADVEHS, ///< Road vehicle menu. WID_TN_SHIPS, ///< Ship menu. - WID_TN_AIRCRAFTS, ///< Aircraft menu. + WID_TN_AIRCRAFT, ///< Aircraft menu. WID_TN_ZOOM_IN, ///< Zoom in the main viewport. WID_TN_ZOOM_OUT, ///< Zoom out the main viewport. WID_TN_BUILDING_TOOLS_START, ///< Helper for the offset of the building tools diff --git a/src/window.cpp b/src/window.cpp index f4b7a1ca18..22084c200e 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -36,6 +36,7 @@ #include "error.h" #include "game/game.hpp" #include "video/video_driver.hpp" +#include "framerate_type.h" #include "safeguards.h" @@ -48,7 +49,7 @@ enum ViewportAutoscrolling { }; static Point _drag_delta; ///< delta between mouse cursor and upper left corner of dragged window -static Window *_mouseover_last_w = NULL; ///< Window of the last #MOUSEOVER event. +static Window *_mouseover_last_w = NULL; ///< Window of the last OnMouseOver event. static Window *_last_scroll_window = NULL; ///< Window of the last scroll event. /** List of windows opened at the screen sorted from the front. */ @@ -937,6 +938,8 @@ static void DrawOverlappedWindow(Window *w, int left, int top, int right, int bo void DrawOverlappedWindowForAll(int left, int top, int right, int bottom) { Window *w; + + DrawPixelInfo *old_dpi = _cur_dpi; DrawPixelInfo bk; _cur_dpi = &bk; @@ -950,6 +953,7 @@ void DrawOverlappedWindowForAll(int left, int top, int right, int bottom) DrawOverlappedWindow(w, max(left, w->left), max(top, w->top), min(right, w->left + w->width), min(bottom, w->top + w->height)); } } + _cur_dpi = old_dpi; } /** @@ -1114,7 +1118,7 @@ Window *FindWindowById(WindowClass cls, WindowNumber number) /** * Find any window by its class. Useful when searching for a window that uses - * the window number as a #WindowType, like #WC_SEND_NETWORK_MSG. + * the window number as a #WindowClass, like #WC_SEND_NETWORK_MSG. * @param cls Window class * @return Pointer to the found window, or \c NULL if not available */ @@ -1429,7 +1433,6 @@ static void BringWindowToFront(Window *w) /** * Initializes the data (except the position and initial size) of a new Window. - * @param desc Window description. * @param window_number Number being assigned to the new window * @return Window pointer of the newly created window * @pre If nested widgets are used (\a widget is \c NULL), #nested_root and #nested_array_size must be initialized. @@ -1738,7 +1741,7 @@ static Point LocalGetWindowPlacement(const WindowDesc *desc, int16 sm_width, int int16 default_width = max(desc->GetDefaultWidth(), sm_width); int16 default_height = max(desc->GetDefaultHeight(), sm_height); - if (desc->parent_cls != 0 /* WC_MAIN_WINDOW */ && (w = FindWindowById(desc->parent_cls, window_number)) != NULL) { + if (desc->parent_cls != WC_NONE && (w = FindWindowById(desc->parent_cls, window_number)) != NULL) { bool rtl = _current_text_dir == TD_RTL; if (desc->parent_cls == WC_BUILD_TOOLBAR || desc->parent_cls == WC_SCEN_LAND_GEN) { pt.x = w->left + (rtl ? w->width - default_width : 0); @@ -1999,7 +2002,7 @@ static void HandleMouseOver() { Window *w = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y); - /* We changed window, put a MOUSEOVER event to the last window */ + /* We changed window, put an OnMouseOver event to the last window */ if (_mouseover_last_w != NULL && _mouseover_last_w != w) { /* Reset mouse-over coordinates of previous window */ Point pt = { -1, -1 }; @@ -2442,7 +2445,7 @@ static EventState HandleViewportScroll() * outside of the window and should not left-mouse scroll anymore. */ if (_last_scroll_window == NULL) _last_scroll_window = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y); - if (_last_scroll_window == NULL || !(_right_button_down || scrollwheel_scrolling || (_settings_client.gui.left_mouse_btn_scrolling && _left_button_down))) { + if (_last_scroll_window == NULL || !((_settings_client.gui.scroll_mode != VSM_MAP_LMB && _right_button_down) || scrollwheel_scrolling || (_settings_client.gui.scroll_mode == VSM_MAP_LMB && _left_button_down))) { _cursor.fix_at = false; _scrolling_viewport = false; _last_scroll_window = NULL; @@ -2457,20 +2460,20 @@ static EventState HandleViewportScroll() } Point delta; - if (_settings_client.gui.reverse_scroll || (_settings_client.gui.left_mouse_btn_scrolling && _left_button_down)) { - delta.x = -_cursor.delta.x; - delta.y = -_cursor.delta.y; - } else { - delta.x = _cursor.delta.x; - delta.y = _cursor.delta.y; - } - if (scrollwheel_scrolling) { /* We are using scrollwheels for scrolling */ delta.x = _cursor.h_wheel; delta.y = _cursor.v_wheel; _cursor.v_wheel = 0; _cursor.h_wheel = 0; + } else { + if (_settings_client.gui.scroll_mode != VSM_VIEWPORT_RMB_FIXED) { + delta.x = -_cursor.delta.x; + delta.y = -_cursor.delta.y; + } else { + delta.x = _cursor.delta.x; + delta.y = _cursor.delta.y; + } } /* Create a scroll-event and send it to the window */ @@ -2748,18 +2751,17 @@ static void HandleAutoscroll() y -= vp->top; /* here allows scrolling in both x and y axis */ -#define scrollspeed 3 + static const int SCROLLSPEED = 3; if (x - 15 < 0) { - w->viewport->dest_scrollpos_x += ScaleByZoom((x - 15) * scrollspeed, vp->zoom); + w->viewport->dest_scrollpos_x += ScaleByZoom((x - 15) * SCROLLSPEED, vp->zoom); } else if (15 - (vp->width - x) > 0) { - w->viewport->dest_scrollpos_x += ScaleByZoom((15 - (vp->width - x)) * scrollspeed, vp->zoom); + w->viewport->dest_scrollpos_x += ScaleByZoom((15 - (vp->width - x)) * SCROLLSPEED, vp->zoom); } if (y - 15 < 0) { - w->viewport->dest_scrollpos_y += ScaleByZoom((y - 15) * scrollspeed, vp->zoom); + w->viewport->dest_scrollpos_y += ScaleByZoom((y - 15) * SCROLLSPEED, vp->zoom); } else if (15 - (vp->height - y) > 0) { - w->viewport->dest_scrollpos_y += ScaleByZoom((15 - (vp->height - y)) * scrollspeed, vp->zoom); + w->viewport->dest_scrollpos_y += ScaleByZoom((15 - (vp->height - y)) * SCROLLSPEED, vp->zoom); } -#undef scrollspeed } enum MouseClick { @@ -2858,21 +2860,26 @@ static void MouseLoop(MouseClick click, int mousewheel) if (vp != NULL && (_game_mode == GM_MENU || HasModalProgress())) return; if (mousewheel != 0) { - /* Send mousewheel event to window */ - w->OnMouseWheel(mousewheel); + /* Send mousewheel event to window, unless we're scrolling a viewport or the map */ + if (!scrollwheel_scrolling || (vp == NULL && w->window_class != WC_SMALLMAP)) w->OnMouseWheel(mousewheel); /* Dispatch a MouseWheelEvent for widgets if it is not a viewport */ if (vp == NULL) DispatchMouseWheelEvent(w, w->nested_root->GetWidgetFromPos(x - w->left, y - w->top), mousewheel); } if (vp != NULL) { - if (scrollwheel_scrolling) click = MC_RIGHT; // we are using the scrollwheel in a viewport, so we emulate right mouse button + if (scrollwheel_scrolling && !(w->flags & WF_DISABLE_VP_SCROLL)) { + _scrolling_viewport = true; + _cursor.fix_at = true; + return; + } + switch (click) { case MC_DOUBLE_LEFT: case MC_LEFT: if (HandleViewportClicked(vp, x, y)) return; if (!(w->flags & WF_DISABLE_VP_SCROLL) && - _settings_client.gui.left_mouse_btn_scrolling) { + _settings_client.gui.scroll_mode == VSM_MAP_LMB) { _scrolling_viewport = true; _cursor.fix_at = false; return; @@ -2880,13 +2887,11 @@ static void MouseLoop(MouseClick click, int mousewheel) break; case MC_RIGHT: - if (!(w->flags & WF_DISABLE_VP_SCROLL)) { + if (!(w->flags & WF_DISABLE_VP_SCROLL) && + _settings_client.gui.scroll_mode != VSM_MAP_LMB) { _scrolling_viewport = true; - _cursor.fix_at = true; - - /* clear 2D scrolling caches before we start a 2D scroll */ - _cursor.h_wheel = 0; - _cursor.v_wheel = 0; + _cursor.fix_at = (_settings_client.gui.scroll_mode == VSM_VIEWPORT_RMB_FIXED || + _settings_client.gui.scroll_mode == VSM_MAP_RMB_FIXED); return; } break; @@ -2901,7 +2906,7 @@ static void MouseLoop(MouseClick click, int mousewheel) case MC_LEFT: case MC_DOUBLE_LEFT: DispatchLeftClickEvent(w, x - w->left, y - w->top, click == MC_DOUBLE_LEFT ? 2 : 1); - break; + return; default: if (!scrollwheel_scrolling || w == NULL || w->window_class != WC_SMALLMAP) break; @@ -2909,11 +2914,19 @@ static void MouseLoop(MouseClick click, int mousewheel) * Simulate a right button click so we can get started. */ FALLTHROUGH; - case MC_RIGHT: DispatchRightClickEvent(w, x - w->left, y - w->top); break; + case MC_RIGHT: + DispatchRightClickEvent(w, x - w->left, y - w->top); + return; - case MC_HOVER: DispatchHoverEvent(w, x - w->left, y - w->top); break; + case MC_HOVER: + DispatchHoverEvent(w, x - w->left, y - w->top); + break; } } + + /* We're not doing anything with 2D scrolling, so reset the value. */ + _cursor.h_wheel = 0; + _cursor.v_wheel = 0; } /** @@ -3066,6 +3079,9 @@ void InputLoop() */ void UpdateWindows() { + PerformanceMeasurer framerate(PFE_DRAWING); + PerformanceAccumulator::Reset(PFE_DRAWWORLD); + Window *w; static int highlight_timer = 1; diff --git a/src/window_type.h b/src/window_type.h index 809e81d485..7185bfcb4f 100644 --- a/src/window_type.h +++ b/src/window_type.h @@ -681,6 +681,18 @@ enum WindowClass { */ WC_SAVE_PRESET, + /** + * Framerate display; %Window numbers: + * - 0 = #FramerateDisplayWidgets + */ + WC_FRAMERATE_DISPLAY, + + /** + * Frame time graph; %Window numbers: + * - 0 = #FrametimeGraphWindowWidgets + */ + WC_FRAMETIME_GRAPH, + WC_INVALID = 0xFFFF, ///< Invalid window. };