Merge branch 'master' into jgrpp

# Conflicts:
#	src/os/windows/crashlog_win.cpp
#	src/os/windows/font_win32.cpp
#	src/os/windows/win32.cpp
#	src/os/windows/win32.h
#	src/video/win32_v.cpp
#	src/video/win32_v.h
pull/642/head
Jonathan G Rennison 4 months ago
commit 8ae1587987

@ -50,7 +50,7 @@ jobs:
uses: dtolnay/rust-toolchain@stable
- name: Enable Rust cache
uses: Swatinem/rust-cache@v2
uses: Swatinem/rust-cache@v2.7.0
- name: Setup vcpkg caching
uses: actions/github-script@v6

@ -388,6 +388,7 @@ link_package(ZSTD TARGET ZSTD::ZSTD RECOMMENDED)
if(NOT WIN32 AND NOT EMSCRIPTEN)
link_package(CURL ENCOURAGED)
target_link_libraries(openttd_lib ${CMAKE_DL_LIBS})
endif()
if(NOT OPTION_DEDICATED)

@ -54,6 +54,9 @@ string(REPLACE "0x(nil)" "0x00000000" REGRESSION_RESULT "${REGRESSION_RESULT}")
string(REPLACE "0x0000000000000000" "0x00000000" REGRESSION_RESULT "${REGRESSION_RESULT}")
string(REPLACE "0x0x0" "0x00000000" REGRESSION_RESULT "${REGRESSION_RESULT}")
# Convert path separators
string(REPLACE "\\" "/" REGRESSION_RESULT "${REGRESSION_RESULT}")
# Remove timestamps if any
string(REGEX REPLACE "\[[0-9-]+ [0-9:]+\] " "" REGRESSION_RESULT "${REGRESSION_RESULT}")
@ -62,6 +65,7 @@ string(REPLACE "\ndbg: [script]" "\n" REGRESSION_RESULT "${REGRESSION_RESULT}")
string(REPLACE "\n " "\nERROR: " REGRESSION_RESULT "${REGRESSION_RESULT}")
string(REPLACE "\nERROR: [1] " "\n" REGRESSION_RESULT "${REGRESSION_RESULT}")
string(REPLACE "\n[P] " "\n" REGRESSION_RESULT "${REGRESSION_RESULT}")
string(REPLACE "\n[S] " "\n" REGRESSION_RESULT "${REGRESSION_RESULT}")
string(REGEX REPLACE "dbg: ([^\n]*)\n?" "" REGRESSION_RESULT "${REGRESSION_RESULT}")
# Read the expected result

@ -2024,5 +2024,12 @@ function Regression::Start()
print(" IsEventWaiting: false");
this.Math();
/* Check Valuate() is actually limited, MUST BE THE LAST TEST. */
print("--Valuate() with excessive CPU usage--")
local list = AIList();
list.AddItem(0, 0);
local Infinite = function(id) { while(true); }
list.Valuate(Infinite);
}

@ -9585,4 +9585,23 @@ ERROR: IsEnd() is invalid as Begin() is never called
-1 > 2147483647: false
-2147483648 > 2147483647: false
13725 > -2147483648: true
--Valuate() with excessive CPU usage--
Your script made an error: excessive CPU usage in valuator function
*FUNCTION [unknown()] regression/main.nut line [2032]
*FUNCTION [Valuate()] NATIVE line [-1]
*FUNCTION [Start()] regression/main.nut line [2033]
[id] 0
[this] TABLE
[Infinite] CLOSURE
[list] INSTANCE
[this] INSTANCE
Your script made an error: excessive CPU usage in valuator function
*FUNCTION [Start()] regression/main.nut line [2033]
[Infinite] CLOSURE
[list] INSTANCE
[this] INSTANCE
ERROR: The script died unexpectedly.

@ -242,6 +242,7 @@ add_files(
league_gui.h
league_gui.cpp
league_type.h
library_loader.h
livery.h
load_check.h
main_gui.cpp

@ -256,6 +256,11 @@ std::unique_ptr<const ParagraphLayouter::Line> FallbackParagraphLayout::NextLine
next_run = this->buffer_begin + iter->first;
begin = this->buffer;
/* Since a next run is started, there is already some text that
* will be shown for this line. However, we do not want to break
* this line at the previous space, so pretend we passed a space
* just before this next run. */
last_space = begin - 1;
}
if (IsWhitespace(c)) last_space = this->buffer;

@ -202,6 +202,7 @@ STR_UNITS_POWER_IMPERIAL :{DECIMAL}{NBSP}
STR_UNITS_POWER_METRIC :{DECIMAL}{NBSP}حصان
STR_UNITS_POWER_SI :{DECIMAL}{NBSP}ك واط
STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t
STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg
STR_UNITS_WEIGHT_SHORT_IMPERIAL :{DECIMAL}{NBSP} طن
@ -390,6 +391,7 @@ STR_SCENEDIT_FILE_MENU_QUIT :انهاء
###length 15
STR_SETTINGS_MENU_GAME_OPTIONS :إعدادات اللعبه
STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :الإعدادات
STR_SETTINGS_MENU_AI_SETTINGS :اعدادات االذكاء الاصطناعي
STR_SETTINGS_MENU_NEWGRF_SETTINGS :إعدادات اﻹضافات
STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :خيارات الشفافية
STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :عرض اسماء المدن
@ -752,6 +754,7 @@ STR_SMALLMAP_TOOLTIP_SHOW_HEIGHT :{BLACK}بدل
STR_SMALLMAP_TOOLTIP_DISABLE_ALL_COMPANIES :{BLACK}عدم عرض ممتلكات اي شركة على الخارطة
STR_SMALLMAP_TOOLTIP_ENABLE_ALL_COMPANIES :{BLACK}عرض جميع املاك الشركة على الخريطة
STR_SMALLMAP_TOOLTIP_DISABLE_ALL_CARGOS :{BLACK}عدم عرض أي بضائع على الخريطة
STR_SMALLMAP_TOOLTIP_ENABLE_ALL_CARGOS :{BLACK}عرض جميع البضائع على الخريطة
# Status bar messages
STR_STATUSBAR_TOOLTIP_SHOW_LAST_NEWS :{BLACK}اظهر اخر رسالة / تقرير
@ -948,6 +951,7 @@ STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync
STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}حدد هذا المربع لمزامنة الشاشة (v-sync). سيتم تطبيق الإعداد الذي تم تغييره فقط عند إعادة تشغيل اللعبة. يعمل فقط مع تمكين تسريع الأجهزة (hardware acceleration)
STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}اسحب شريط التمرير لتعيين حجم الواجهة. اضغط مع الاستمرار على Ctrl للتعديل المستمر
STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}الكشف التلقائي عن الحجم
STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}اختر هذا المربع لكشف حجم الواجهة تلقائيا
@ -1252,6 +1256,7 @@ 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_HELPTEXT :عند التمكين ، يتم إرسال رسالة إخبارية عندما لا تحقق السيارة أي ربح خلال سنة تقويمية واحدة
STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES :المركبات لا تنتهي صلاحيتها ابدا : {STRING}
@ -1406,6 +1411,7 @@ STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS :استخدام
STR_CONFIG_SETTING_LOADING_INDICATORS :تفعيل مؤشر التحميل: {STRING}
STR_CONFIG_SETTING_LOADING_INDICATORS_HELPTEXT :حدد ما إذا كانت مؤشرات التحميل معروضة فوق تحميل المركبات أو تفريغها
STR_CONFIG_SETTING_TIMETABLE_MODE_HELPTEXT :حدد الوحدات الزمنية المستخدمة في جداول مواعيد المركبات
###length 3
STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE :عرض الوصول و المغادرة في جدولة الاعمال: {STRING}
@ -1469,6 +1475,7 @@ STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT :حظر الطا
STR_CONFIG_SETTING_AI_BUILDS_SHIPS :حظر السفن على الحاسوب: {STRING}
STR_CONFIG_SETTING_AI_PROFILE :الملف الشخصي للإعدادات الافتراضية: {STRING}
###length 3
STR_CONFIG_SETTING_AI_PROFILE_EASY :سهل
@ -1480,8 +1487,10 @@ STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB
STR_CONFIG_SETTING_SERVINT_ISPERCENT :فترات الصيانة بالنسبة المئوية : {STRING}
STR_CONFIG_SETTING_SERVINT_AIRCRAFT ::مدة فحص الطائرة الإفتراضي{STRING}
STR_CONFIG_SETTING_SERVINT_AIRCRAFT :مدة فحص الإفتراضي للطائرة: {STRING}
STR_CONFIG_SETTING_SERVINT_SHIPS :مدة فحص الإفتراضي للسفن: {STRING}
###setting-zero-is-special
STR_CONFIG_SETTING_SERVINT_DISABLED :غير مفعل
STR_CONFIG_SETTING_NOSERVICE :الغاء الصيانة عندما يكون التعطيل للمركبات غير مفعل: {STRING}
@ -1624,6 +1633,7 @@ STR_CONFIG_SETTING_LARGER_TOWNS_VALUE :1 في {COMMA}
STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :مضاعف المدن المبدئي: {STRING}
STR_CONFIG_SETTING_DISTRIBUTION_PAX :وضع التوزيع للركاب: {STRING}
###length 3
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :كلما قمت بتعليت هذا بشكل اكثر، كلما ازداد وقت الCPU في حساب الرسم البياني الرابط. إذا استغرق الأمر وقتًا طويلاً فقد تلاحظ تأخير في الاستجبة. إذا قمت بتغيره إلى قيمة منخفضة، فسيكون التوزيع غير دقيق، وقد تلاحظ عدم إرسال البضائع إلى الأماكن التي تتوقع أن تذهب إليها.
@ -1648,6 +1658,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_WEIGHT_METRIC :متري (طن)
STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE ::وحدات جهد الجر {STRING}
###length 3
STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_IMPERIAL :إمبراطوري (lbf)
STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_METRIC :متري (كغ - قوة)
###length 3
@ -1979,6 +1990,7 @@ STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :منع
STR_NETWORK_CLIENT_LIST_ASK_CLIENT_KICK :{YELLOW}هل أنت متأكد أنك تريد طرد اللاعب '{STRING}'؟
STR_NETWORK_CLIENT_LIST_ASK_CLIENT_BAN :{YELLOW}هل أنت متأكد أنك تريد حظر اللاعب '{STRING}'؟
STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET :{YELLOW}هل أنت متأكد أنك تريد حذف شركة '{COMPANY}'؟
STR_NETWORK_CLIENT_LIST_ASK_COMPANY_UNLOCK :{YELLOW}هل أنت متأكد أنك تريد محو كلمة السر الخاصة بالشركة '{COMPANY}'?
STR_NETWORK_ASK_RELAY_NO :{BLACK}لا
@ -2600,6 +2612,7 @@ STR_ABOUT_VERSION :{BLACK}النس
STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}النسخة المفتوحة {COPYRIGHT}2002-{STRING} فريق النسخة المفتوحة
# Framerate display window
STR_FRAMERATE_CURRENT :{WHITE}الحالي
STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms
STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} ms
STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} صورة في الثانية
@ -2845,6 +2858,7 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING
STR_NEWGRF_ERROR_MSG_WARNING :{RED} تحذير: {SILVER}{STRING}
STR_NEWGRF_ERROR_MSG_ERROR :{RED} خطأ: {SILVER}{STRING}
STR_NEWGRF_ERROR_MSG_FATAL :{RED} خطأ قاتل: {SILVER}{STRING}
STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}ال NewGRF "{STRING}" قام باعادة خطء فادح:{}{STRING}
STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} لن يعمل مع اصدار الباتش المسجل في النسخة المفتوحة
STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} يعمل مع {STRING} اصدار من TTD.
STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} مصمم ليستخدم مع {STRING}
@ -3114,6 +3128,7 @@ STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG
STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG}
STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}السيولة المتاحة
STR_FINANCES_LOAN_TITLE :{WHITE}القرض
STR_FINANCES_INTEREST_RATE :{WHITE}فائدة القرض: {BLACK}{NUM}%
STR_FINANCES_MAX_LOAN :{WHITE}اقصى حد للقرض: {BLACK}{CURRENCY_LONG}
STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG}
STR_FINANCES_BORROW_BUTTON :{BLACK}اقتراض{CURRENCY_LONG}
@ -3333,6 +3348,7 @@ STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}شراء
STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}شراء طائرة
###length VEHICLE_TYPES
STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}شراء العربة وتجديد بضائعها
STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}شراء العربة وتجديد بضائعها
STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}شراء وإعادة تجهيز السفينة
@ -3496,6 +3512,7 @@ STR_REPLACE_HELP_LEFT_ARRAY :{BLACK} اخت
STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK} اختر نوع المحرك المراد إحلاله محل المحرك المختار في القائمة اليسرى
STR_REPLACE_VEHICLES_START :{BLACK} بدأ تبديل العربات
STR_REPLACE_VEHICLES_NOW :استبدل جميع المركبات الآن
STR_REPLACE_HELP_START_BUTTON :{BLACK}اضغط لبدأ عملية تبديل المحركات المختارة في القائمة اليسرى بالمحركات المختارة في القائمة اليمنى
STR_REPLACE_NOT_REPLACING :{BLACK}لم يتم التبديل
STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}لم يتم اختيار اي عربة
@ -3865,13 +3882,13 @@ STR_TIMETABLE_STAY_FOR_ESTIMATED :(البقاء
STR_TIMETABLE_STAY_FOR :ويبقى لـ {STRING}
STR_TIMETABLE_AND_TRAVEL_FOR :ويسافر لـ {STRING}
STR_TIMETABLE_TOTAL_TIME :{BLACK}جدولة الاوامر هذه ستأخذ {STRING} لنهاية
STR_TIMETABLE_TOTAL_TIME_INCOMPLETE :{BLACK}جدولة الاوامر هذه ستأخذ على الاقل {STRING} لتكتمل (لايشمل كل الجدولة)
STR_TIMETABLE_TOTAL_TIME :{BLACK}جدول الاوامر هذه ستأخذ {STRING} للانتهاء
STR_TIMETABLE_TOTAL_TIME_INCOMPLETE :{BLACK}جدول الاوامر هذا سيأخذ على الاقل {STRING} للانتهاء (ليست جميعها مجدولة)
STR_TIMETABLE_STATUS_ON_TIME :{BLACK}هذه العربة تعمل حسب الجدولة في الوقت المُحَدَد
STR_TIMETABLE_STATUS_LATE :{BLACK}هذه العربه {STRING} مُتاخِرة حاليا عن الجدوله
STR_TIMETABLE_STATUS_EARLY :{BLACK}هذه العربه {STRING} مُتَقَدِمه عن الجدوله
STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}جدولة الاعمال لم تبدأ بعد
STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}جدول الاعمال لم تبدأ بعد
@ -4070,6 +4087,7 @@ STR_ERROR_OWNED_BY :{WHITE}مملو
STR_ERROR_AREA_IS_OWNED_BY_ANOTHER :{WHITE}... المنطقة مملوكة لشركة منافسة
STR_ERROR_TERRAFORM_LIMIT_REACHED :{WHITE}... تم الوصول لاقصى حدود للتضاريس
STR_ERROR_CLEARING_LIMIT_REACHED :{WHITE}... تم الوصول لاقصى عدد ازالة
STR_ERROR_TREE_PLANT_LIMIT_REACHED :{WHITE}... تم الوصول للحد الاقصى لزرع الاشجار
STR_ERROR_NAME_MUST_BE_UNIQUE :{WHITE}السم يجب ان يكون فريدا - غير مستخدم
STR_ERROR_GENERIC_OBJECT_IN_THE_WAY :{WHITE}{1:STRING} على الطريق
STR_ERROR_NOT_ALLOWED_WHILE_PAUSED :{WHITE}غير مسموح في حين توقفت
@ -4405,6 +4423,7 @@ STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... ال
STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}لا يمكن جدولة العربة ...
STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}يمكن للعربات الانتظار في المحطات فقط.
STR_ERROR_TIMETABLE_NOT_STOPPING_HERE :{WHITE}هذه العربة لا تتوقف في هذه المحطة.
STR_ERROR_TIMETABLE_NOT_STARTED :{WHITE}... جدول الاعمال لم تبدأ بعد
# Sign related errors
STR_ERROR_TOO_MANY_SIGNS :{WHITE}... العلامات كثيرة جدا

@ -772,7 +772,7 @@ STR_SMALLMAP_LEGENDA_AIRCRAFT :{TINY_FONT}{BLA
STR_SMALLMAP_LEGENDA_TRANSPORT_ROUTES :{TINY_FONT}{BLACK}Rotas de Transporte
STR_SMALLMAP_LEGENDA_FOREST :{TINY_FONT}{BLACK}Floresta
STR_SMALLMAP_LEGENDA_RAILROAD_STATION :{TINY_FONT}{BLACK}Estação Ferroviária
STR_SMALLMAP_LEGENDA_TRUCK_LOADING_BAY :{TINY_FONT}{BLACK}Compartimento de Carga de Caminhões
STR_SMALLMAP_LEGENDA_TRUCK_LOADING_BAY :{TINY_FONT}{BLACK}Estação de caminhões
STR_SMALLMAP_LEGENDA_BUS_STATION :{TINY_FONT}{BLACK}Estação de Ônibus
STR_SMALLMAP_LEGENDA_AIRPORT_HELIPORT :{TINY_FONT}{BLACK}Aeroporto/Heliporto
STR_SMALLMAP_LEGENDA_DOCK :{TINY_FONT}{BLACK}Doca
@ -1003,6 +1003,7 @@ STR_GAME_OPTIONS_CURRENCY_HKD :Dólar de Hong
STR_GAME_OPTIONS_CURRENCY_INR :Rúpia Indiana
STR_GAME_OPTIONS_CURRENCY_IDR :Rupia Indonésia
STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit Malaio
STR_GAME_OPTIONS_CURRENCY_LVL :Lats da Letônia
STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Salvar automaticamente
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Selecionar o intervalo entre jogos salvos automaticos
@ -2056,14 +2057,17 @@ STR_CONFIG_SETTING_ACCOUNTING :Contabilidade
STR_CONFIG_SETTING_VEHICLES :Veículos
STR_CONFIG_SETTING_VEHICLES_PHYSICS :Física
STR_CONFIG_SETTING_VEHICLES_ROUTING :Rota
STR_CONFIG_SETTING_VEHICLES_ORDERS :Ordens
STR_CONFIG_SETTING_LIMITATIONS :Limitações
STR_CONFIG_SETTING_ACCIDENTS :Desastres / Acidentes
STR_CONFIG_SETTING_GENWORLD :Geração de Mundo
STR_CONFIG_SETTING_ENVIRONMENT :Meio-Ambiente
STR_CONFIG_SETTING_ENVIRONMENT_TIME :Tempo
STR_CONFIG_SETTING_ENVIRONMENT_AUTHORITIES :Autoridades
STR_CONFIG_SETTING_ENVIRONMENT_TOWNS : Cidades
STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES :Indústrias
STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :Distribuição de Carga
STR_CONFIG_SETTING_ENVIRONMENT_TREES :Árvores
STR_CONFIG_SETTING_AI :Oponentes
STR_CONFIG_SETTING_AI_NPC :Computadores
STR_CONFIG_SETTING_NETWORK :Rede
@ -2721,9 +2725,9 @@ STR_RAIL_TOOLBAR_MAGLEV_CONSTRUCTION_CAPTION :Construir ferro
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Construir ferrovias. Ctrl alterna entre construção/remoção de trilhos. Shift altera construção/preço estimado
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}Construir ferrovias usando o modo Autotrilho. Ctrl alterna entre construção/remoçao de trilhos. Shift altera construção/preço estimado
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Construir depósito (para compra e manutenção de trens). Shift altera construção/preço estimado
STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}Converter linha em ponto de controle. Ctrl permite a união de pontos de controle. Shift altera construção/preço estimado
STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}Construir ponto de controle na rodovia. Ctrl permite unir pontos de controle. Shift alterna construir/mostrar custo estimado
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}Construir estação ferroviária. Ctrl permite a união de estações. Shift altera construção/preço estimado
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Construir sinais ferroviários. Ctrl alterna a construção de semáforos/sinais{}Clicar e arrastar constroi sinais até a próxima junção ou sinal{}Ctrl+Clique alterna a janela de seleção de sinais. Shift alterna construção/preço estimado
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Construir sinais na ferrovia. Ctrl alterna entre a construção de semáforos/sinais{}Clicar e arrastar constrói sinais ao longo de uma linha de trilhos. Ctrl constrói sinais até a próxima junção ou sinal{}Ctrl+Clique abre a janela de seleção de sinais. Shift alterna construir/mostrar custo estimado
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE :{BLACK}Construir ponte ferroviária. Shift altera construção/preço estimado
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL :{BLACK}Construir túnel ferroviário. Shift altera construção/preço estimado
STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Alternar construir/remover ferrovias, sinais, pontos de controle e estações. Segure ctrl para remover os trilhos de estações e pontos de controle.
@ -2811,7 +2815,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Construi
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT :{BLACK}Construir depósito de bonde (para compra e manutenção de bondes). Shift altera construção/preço estimado
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION :{BLACK}Construir estação de ônibus. Ctrl permite a união de estações. Shift altera construção/preço estimado
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION :{BLACK}Constuir estação de bonde para passageiros. Ctrl permite a união de estações. Shift altera construção/preço estimado
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY :{BLACK}Construir área de carga. Ctrl permite a união de estações. Shift altera construção/preço estimado
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY :{BLACK}Construir estação de caminhões. Ctrl permite unir estações. Shift alterna construir/mostrar custo estimado
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_CARGO_TRAM_STATION :{BLACK}Constuir estação de bonde para carga. Ctrl permite a união de estações. Shift altera construção/preço estimado
STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD :{BLACK}Ativar/Desativar vias de mão única
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE :{BLACK}Construir ponte rodoviária. Shift altera construção/preço estimado
@ -2836,7 +2840,7 @@ STR_BUILD_DEPOT_TRAM_ORIENTATION_SELECT_TOOLTIP :{BLACK}Selecion
STR_STATION_BUILD_BUS_ORIENTATION :{WHITE}Orientação do estação de ônibus
STR_STATION_BUILD_BUS_ORIENTATION_TOOLTIP :{BLACK}Selecionar orientação do estação de ônibus
STR_STATION_BUILD_TRUCK_ORIENTATION :{WHITE}Orientação da área de carga
STR_STATION_BUILD_TRUCK_ORIENTATION_TOOLTIP :{BLACK}Selecionar orientação da área de carga
STR_STATION_BUILD_TRUCK_ORIENTATION_TOOLTIP :{BLACK}Selecionar a orientação da estação de caminhões
STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION :{WHITE}Orientação da Estação de Bonde Passageiros
STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION_TOOLTIP :{BLACK}Selecionar orientação da estação de bonde
STR_STATION_BUILD_CARGO_TRAM_ORIENTATION :{WHITE}Orientação da Estação de Bonde de Carga
@ -3080,7 +3084,7 @@ STR_LAI_TREE_NAME_CACTUS_PLANTS :Cactos
STR_LAI_STATION_DESCRIPTION_RAILROAD_STATION :Estação ferroviária
STR_LAI_STATION_DESCRIPTION_AIRCRAFT_HANGAR :Hangar
STR_LAI_STATION_DESCRIPTION_AIRPORT :Aeroporto
STR_LAI_STATION_DESCRIPTION_TRUCK_LOADING_AREA :Área de carga
STR_LAI_STATION_DESCRIPTION_TRUCK_LOADING_AREA :Estação de caminhões
STR_LAI_STATION_DESCRIPTION_BUS_STATION :Estação de ônibus
STR_LAI_STATION_DESCRIPTION_SHIP_DOCK :Doca
STR_LAI_STATION_DESCRIPTION_BUOY :Bóia

@ -1003,6 +1003,7 @@ STR_GAME_OPTIONS_CURRENCY_HKD :홍콩 달러
STR_GAME_OPTIONS_CURRENCY_INR :인도 루피
STR_GAME_OPTIONS_CURRENCY_IDR :인도네시아 루피아
STR_GAME_OPTIONS_CURRENCY_MYR :말레이시아 링깃
STR_GAME_OPTIONS_CURRENCY_LVL :라트비아 라츠
STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}자동 저장
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}게임 자동 저장 간격을 선택

@ -1884,7 +1884,7 @@ STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Wysokość gran
STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Wybierz, na jakiej wysokości zaczyna zalegać śnieg w krajobrazie arktycznym. Poziom pokrywy śnieżnej wpływa na rozmieszczenie przedsiębiorstw i na warunki rozwoju miast. Może być zmodyfikowana poprzez Edytor Scenariuszy, w innym przypadku jest obliczana za pomocą ustawienia „pokrycie śniegiem”
STR_CONFIG_SETTING_SNOW_COVERAGE :Pokrycie śniegiem: {STRING}
STR_CONFIG_SETTING_SNOW_COVERAGE_HELPTEXT :Wybierz przybliżoną ilość śniegu w krajobrazie arktycznym. Śnieg wpływa również wpływa na rozmieszczenie przedsiębiorstw i na warunki rozwoju miast. Używane tylko podczas generowania mapy. Teren tuż ponad poziomem wody jest zawsze bez śniegu
STR_CONFIG_SETTING_SNOW_COVERAGE_HELPTEXT :Wybierz przybliżoną ilość śniegu w krajobrazie arktycznym. Śnieg wpływa również wpływa na rozmieszczenie przedsiębiorstw i na warunki rozwoju miast. Używane tylko podczas generowania mapy. Teren tuż ponad poziomem morza jest zawsze bez śniegu
STR_CONFIG_SETTING_SNOW_COVERAGE_VALUE :{NUM}%
STR_CONFIG_SETTING_DESERT_COVERAGE :Pokrycie pustynią: {STRING}
@ -3612,7 +3612,7 @@ STR_MAPGEN_DATE_TOOLTIP :{BLACK}Wybierz
STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Liczba przedsiębiorstw:
STR_MAPGEN_NUMBER_OF_INDUSTRIES_TOOLTIP :{BLACK}Wybierz gęstość rozmieszczenia przedsiębiorstw lub podaj ich określoną liczbę
STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Najwyższy szczyt:
STR_MAPGEN_HEIGHTMAP_HEIGHT_TOOLTIP :{BLACK}Wybierz najwyższy szczyt, który gra spróbuje utworzyć, mierzony wysokością nad poziomem wody
STR_MAPGEN_HEIGHTMAP_HEIGHT_TOOLTIP :{BLACK}Wybierz najwyższy szczyt, który gra spróbuje utworzyć, mierzony wysokością nad poziomem morza
STR_MAPGEN_HEIGHTMAP_HEIGHT_UP :{BLACK}Zwiększ wysokość najwyższego szczytu na mapie o jeden poziom
STR_MAPGEN_HEIGHTMAP_HEIGHT_DOWN :{BLACK}Zmniejsz wysokość najwyższego szczytu na mapie o jeden poziom
STR_MAPGEN_SNOW_COVERAGE :{BLACK}Pokrycie śniegiem:
@ -3624,8 +3624,8 @@ STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Zwiększ
STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Zmniejsz pokrycie pustynią o 10%
STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}%
STR_MAPGEN_TERRAIN_TYPE :{BLACK}Typ terenu:
STR_MAPGEN_SEA_LEVEL :{BLACK}Poziom wody:
STR_MAPGEN_SEA_LEVEL_TOOLTIP :{BLACK}Określ wysokość poziomu wody
STR_MAPGEN_SEA_LEVEL :{BLACK}Poziom morza:
STR_MAPGEN_SEA_LEVEL_TOOLTIP :{BLACK}Określ wysokość poziomu morza
STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Liczba rzek:
STR_MAPGEN_SMOOTHNESS :{BLACK}Gładkość:
STR_MAPGEN_VARIETY :{BLACK}Różnorodność:

@ -1356,12 +1356,12 @@ STR_CONFIG_SETTING_INDUSTRY_PLATFORM_HELPTEXT :设置工厂周
STR_CONFIG_SETTING_MULTIPINDTOWN :允许在一个城镇中建设多个同类工业设施:{STRING}
STR_CONFIG_SETTING_MULTIPINDTOWN_HELPTEXT :通常,城市不希望有多个相同类型工业,本设置“打开”时允许多个同类型工厂在同一个城市
STR_CONFIG_SETTING_SIGNALSIDE :显示信号灯{STRING}
STR_CONFIG_SETTING_SIGNALSIDE_HELPTEXT :选择在铁路哪一边放置信号灯
STR_CONFIG_SETTING_SIGNALSIDE :铁路信号位置{STRING}
STR_CONFIG_SETTING_SIGNALSIDE_HELPTEXT :选择在铁路的哪一侧放置信号。
###length 3
STR_CONFIG_SETTING_SIGNALSIDE_LEFT :在左边
STR_CONFIG_SETTING_SIGNALSIDE_LEFT :左侧
STR_CONFIG_SETTING_SIGNALSIDE_DRIVING_SIDE :道路通行方向
STR_CONFIG_SETTING_SIGNALSIDE_RIGHT :右侧
STR_CONFIG_SETTING_SIGNALSIDE_RIGHT :右侧
STR_CONFIG_SETTING_SHOWFINANCES :在年终显示财务报表:{STRING}
STR_CONFIG_SETTING_SHOWFINANCES_HELPTEXT :“打开”时,在年底显示财务报表窗口,方便查看公司财务状况
@ -1369,7 +1369,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 :新列车调度计划中默认命令为停靠在站台 {STRING} 位置
STR_CONFIG_SETTING_STOP_LOCATION_HELPTEXT :设置车辆在站台的默认停靠位置,“近端”是靠近车辆进入的那一端,“中间”是站台中间位置,“远端”是远离车辆进入的那一端。注意:本设定只改变新指令的默认设定。玩家仍可通过点击指令文字改变列车在某车站的停车位置。
###length 3
STR_CONFIG_SETTING_STOP_LOCATION_NEAR_END :近端
@ -1675,11 +1675,11 @@ STR_CONFIG_SETTING_QUICKGOTO :快速创建车
STR_CONFIG_SETTING_QUICKGOTO_HELPTEXT :启用时,打开调度计划窗口时预先选定“前往”命令
STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE :默认铁路类型 (新建/读取游戏后) {STRING}
STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_HELPTEXT :设置开启或者载入游戏时的默认铁路类型,“第一可用的”是最老的铁路类型,“最后一个可用”的是最新的铁路类型,“最常用的”是当前用的最多的铁路类型
STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_HELPTEXT :设置开启或者载入游戏时的默认铁路类型,“最先可用的类型”是最老的铁路类型,“最新可用的类型”的是最新的铁路类型,“最常用的类型”是当前用的最多的铁路类型
###length 3
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_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 :让预留的铁路轨道显示不同的颜色,以帮助查找列车拒绝进入路径轨道的原因
@ -1754,10 +1754,10 @@ STR_CONFIG_SETTING_AI_PROFILE_HARD :困难
STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :联机游戏时允许电脑玩家(AI) {STRING}
STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :“打开”时联机游戏允许电脑玩家
STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :可允许的最大的代码量(如超过则会令脚本被禁用):{STRING}
STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :脚本在一个回合中可进行计算步数的最大值
STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :不令脚本停运的最大代码数量:{STRING}
STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :设定在每个计算循环中脚本AI与游戏脚本的每一句代码最多可进行多少个计算步骤。
STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :每个脚本的内存上限: {STRING}
STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :单个脚本强制终止前可占用的最大内存量。对于大地图可能需要增加。
STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :单个脚本AI与游戏脚本可使用的最大内存量在游玩大型地图时可能需要增加。
STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB
STR_CONFIG_SETTING_SERVINT_ISPERCENT :维护间隔以百分比(%)计算: {STRING}
@ -1914,7 +1914,7 @@ STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :树木自动生
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :控制游戏中数目的随机生长,这将影响依赖树木的工业,比如木材厂
###length 4
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_NO_SPREAD :生长但不扩散 {RED}(损坏伐木场)
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_SPREAD_RAINFOREST :只生长在雨林
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_SPREAD_RAINFOREST :仅在雨林扩散
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_SPREAD_ALL :生长并四处扩散
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_NO_GROWTH_NO_SPREAD :不生长,不扩散 {RED}(损坏伐木场)
@ -3239,7 +3239,7 @@ STR_MAPGEN_SNOW_COVERAGE :{BLACK}雪地
STR_MAPGEN_SNOW_COVERAGE_UP :{BLACK}将雪地比率增加10%
STR_MAPGEN_SNOW_COVERAGE_DOWN :{BLACK}将雪地比率减少10%
STR_MAPGEN_SNOW_COVERAGE_TEXT :{BLACK}{NUM}%
STR_MAPGEN_DESERT_COVERAGE :{BLACK}沙漠覆盖率:
STR_MAPGEN_DESERT_COVERAGE :{BLACK}沙漠率:
STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}将沙漠比率增加10%
STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}将沙漠比率减少10%
STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}%
@ -3304,7 +3304,7 @@ STR_MAPGEN_HEIGHTMAP_SIZE :{ORANGE}{NUM}
STR_MAPGEN_TERRAIN_TYPE_QUERY_CAPT :{WHITE}最高峰目标高度
STR_MAPGEN_HEIGHTMAP_HEIGHT_QUERY_CAPT :{WHITE}最高峰
STR_MAPGEN_SNOW_COVERAGE_QUERY_CAPT :{WHITE}积雪覆盖率 (百分比)
STR_MAPGEN_DESERT_COVERAGE_QUERY_CAPT :{WHITE}沙漠覆盖率 (百分比)
STR_MAPGEN_DESERT_COVERAGE_QUERY_CAPT :{WHITE}沙漠率 (百分比)
STR_MAPGEN_START_DATE_QUERY_CAPT :{WHITE}改变游戏开始的日期
# SE Map generation
@ -3375,7 +3375,7 @@ STR_NEWGRF_SETTINGS_FILENAME :{BLACK}文件
STR_NEWGRF_SETTINGS_GRF_ID :{BLACK}GRF ID{SILVER}{STRING}
STR_NEWGRF_SETTINGS_VERSION :{BLACK}版本: {SILVER}{NUM}
STR_NEWGRF_SETTINGS_MIN_VERSION :{BLACK}最低兼容版本: {SILVER}{NUM}
STR_NEWGRF_SETTINGS_MD5SUM :{BLACK}MD5 码:{SILVER}{STRING}
STR_NEWGRF_SETTINGS_MD5SUM :{BLACK}MD5码{SILVER}{STRING}
STR_NEWGRF_SETTINGS_PALETTE :{BLACK}调色板: {SILVER}{STRING}
STR_NEWGRF_SETTINGS_PALETTE_DEFAULT :默认 (DOS)
STR_NEWGRF_SETTINGS_PALETTE_DEFAULT_32BPP :默认 (DOS) / 32 bpp

@ -0,0 +1,116 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file library_loader.h Functions/types related to loading libraries dynamically. */
#ifndef LIBRARY_LOADER_H
#define LIBRARY_LOADER_H
#include <optional>
#include <string>
#include <type_traits>
class LibraryLoader {
public:
/**
* A function loaded from a library.
*
* Will automatically cast to the correct function pointer type on retrieval.
*/
class Function {
public:
explicit Function(void *p) : p(p) {}
template <typename T, typename = std::enable_if_t<std::is_function_v<T>>>
operator T *() const
{
return reinterpret_cast<T *>(this->p);
}
private:
void *p;
};
/**
* Load a library with the given filename.
*/
explicit LibraryLoader(const std::string &filename)
{
this->handle = this->OpenLibrary(filename);
}
/**
* Close the library.
*/
~LibraryLoader()
{
if (this->handle != nullptr) {
this->CloseLibrary();
}
}
/**
* Check whether an error occurred while loading the library or a function.
*
* @return Whether an error occurred.
*/
bool HasError()
{
return this->error.has_value();
}
/**
* Get the last error that occurred while loading the library or a function.
*
* @return The error message.
*/
std::string GetLastError()
{
return this->error.value_or("No error");
}
/**
* Get a function from a loaded library.
*
* @param symbol_name The name of the function to get.
* @return The function. Check HasError() before using.
*/
Function GetFunction(const std::string &symbol_name)
{
if (this->error.has_value()) return Function(nullptr);
return Function(this->GetSymbol(symbol_name));
}
private:
/**
* Open the library with the given filename.
*
* Should set error if any error occurred.
*
* @param filename The filename of the library to open.
*/
void *OpenLibrary(const std::string &filename);
/**
* Close the library.
*/
void CloseLibrary();
/**
* Get a symbol from the library.
*
* Should set error if any error occurred.
*
* @param symbol_name The name of the symbol to get.
*/
void *GetSymbol(const std::string &symbol_name);
std::optional<std::string> error = {}; ///< The last error that occurred, if set.
void *handle = nullptr; ///< Handle to the library.
};
#endif /* LIBRARY_LOADER_H */

@ -5,6 +5,7 @@ add_files(
)
add_files(
library_loader_unix.cpp
unix.cpp
CONDITION UNIX
)

@ -0,0 +1,64 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file library_loader_unix.cpp Implementation of the LibraryLoader for Linux / MacOS */
#include "../../stdafx.h"
#include <dlfcn.h>
#include "../../library_loader.h"
#include "../../safeguards.h"
/* Emscripten cannot dynamically load other files. */
#if defined(__EMSCRIPTEN__)
void *LibraryLoader::OpenLibrary(const std::string &)
{
this->error = "Dynamic loading is not supported on this platform.";
return nullptr;
}
void LibraryLoader::CloseLibrary()
{
}
void *LibraryLoader::GetSymbol(const std::string &)
{
this->error = "Dynamic loading is not supported on this platform.";
return nullptr;
}
#else
void *LibraryLoader::OpenLibrary(const std::string &filename)
{
void *h = dlopen(filename.c_str(), RTLD_NOW | RTLD_LOCAL);
if (h == nullptr) {
this->error = dlerror();
}
return h;
}
void LibraryLoader::CloseLibrary()
{
dlclose(this->handle);
}
void *LibraryLoader::GetSymbol(const std::string &symbol_name)
{
void *p = dlsym(this->handle, symbol_name.c_str());
if (p == nullptr) {
this->error = dlerror();
}
return p;
}
#endif /* __EMSCRIPTEN__ */

@ -2,6 +2,7 @@ add_files(
crashlog_win.cpp
font_win32.cpp
font_win32.h
library_loader_win.cpp
string_uniscribe.cpp
string_uniscribe.h
survey_win.cpp

@ -19,6 +19,7 @@
#include "../../gamelog.h"
#include "../../sl/saveload.h"
#include "../../video/video_driver.hpp"
#include "../../library_loader.h"
#include "../../screenshot.h"
#include "../../debug.h"
#include "../../settings_type.h"
@ -334,22 +335,7 @@ static const uint MAX_FRAMES = 64;
/* virtual */ char *CrashLogWindows::LogStacktrace(char *buffer, const char *last) const
{
#define M(x) x "\0"
static const char dbg_import[] =
M("dbghelp.dll")
M("SymInitialize")
M("SymSetOptions")
M("SymCleanup")
M("StackWalk64")
M("SymFunctionTableAccess64")
M("SymGetModuleBase64")
M("SymGetModuleInfo64")
M("SymGetSymFromAddr64")
M("SymGetLineFromAddr64")
M("")
;
#undef M
LibraryLoader dbghelp("dbghelp.dll");
struct ProcPtrs {
BOOL (WINAPI * pSymInitialize)(HANDLE, PCSTR, BOOL);
BOOL (WINAPI * pSymSetOptions)(DWORD);
@ -360,12 +346,22 @@ static const uint MAX_FRAMES = 64;
BOOL (WINAPI * pSymGetModuleInfo64)(HANDLE, DWORD64, PIMAGEHLP_MODULE64);
BOOL (WINAPI * pSymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
BOOL (WINAPI * pSymGetLineFromAddr64)(HANDLE, DWORD64, PDWORD, PIMAGEHLP_LINE64);
} proc;
} proc = {
dbghelp.GetFunction("SymInitialize"),
dbghelp.GetFunction("SymSetOptions"),
dbghelp.GetFunction("SymCleanup"),
dbghelp.GetFunction("StackWalk64"),
dbghelp.GetFunction("SymFunctionTableAccess64"),
dbghelp.GetFunction("SymGetModuleBase64"),
dbghelp.GetFunction("SymGetModuleInfo64"),
dbghelp.GetFunction("SymGetSymFromAddr64"),
dbghelp.GetFunction("SymGetLineFromAddr64"),
};
buffer += seprintf(buffer, last, "Decoded stack trace:\n");
/* Try to load the functions from the DLL, if that fails because of a too old dbghelp.dll, just skip it. */
if (LoadLibraryList((Function*)&proc, dbg_import)) {
if (!dbghelp.HasError()) {
/* Initialize symbol handler. */
HANDLE hCur = GetCurrentProcess();
proc.pSymInitialize(hCur, nullptr, TRUE);
@ -522,12 +518,12 @@ static const uint MAX_FRAMES = 64;
int ret = 0;
HMODULE dbghelp = LoadLibrary(L"dbghelp.dll");
if (dbghelp != nullptr) {
typedef BOOL (WINAPI *MiniDumpWriteDump_t)(HANDLE, DWORD, HANDLE,
typedef BOOL (WINAPI *MiniDumpWriteDumpT)(HANDLE, DWORD, HANDLE,
MINIDUMP_TYPE,
CONST PMINIDUMP_EXCEPTION_INFORMATION,
CONST PMINIDUMP_USER_STREAM_INFORMATION,
CONST PMINIDUMP_CALLBACK_INFORMATION);
MiniDumpWriteDump_t funcMiniDumpWriteDump = GetProcAddressT<MiniDumpWriteDump_t>(dbghelp, "MiniDumpWriteDump");
MiniDumpWriteDumpT funcMiniDumpWriteDump = (MiniDumpWriteDumpT) GetProcAddress(dbghelp, "MiniDumpWriteDump");
if (funcMiniDumpWriteDump != nullptr) {
seprintf(filename, filename_last, "%scrash.dmp", _personal_dir.c_str());
HANDLE file = CreateFile(OTTD2FS(filename).c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, 0);
@ -751,7 +747,9 @@ static void CDECL CustomAbort(int)
using VEX_HANDLER_TYPE = LONG WINAPI (EXCEPTION_POINTERS *);
void* (WINAPI *AddVectoredExceptionHandler)(ULONG, VEX_HANDLER_TYPE*);
if (LoadLibraryList((Function*)&AddVectoredExceptionHandler, "kernel32.dll\0AddVectoredExceptionHandler\0\0")) {
static LibraryLoader _kernel32("Kernel32.dll");
AddVectoredExceptionHandler = _kernel32.GetFunction("AddVectoredExceptionHandler");
if (AddVectoredExceptionHandler != nullptr) {
AddVectoredExceptionHandler(1, VectoredExceptionHandler);
}
}

@ -14,9 +14,10 @@
#include "../../core/math_func.hpp"
#include "../../core/mem_func.hpp"
#include "../../fileio_func.h"
#include "../../fontdetection.h"
#include "../../fontcache.h"
#include "../../fontcache/truetypefontcache.h"
#include "../../fontdetection.h"
#include "../../library_loader.h"
#include "../../string_func.h"
#include "../../strings_func.h"
#include "../../zoom_func.h"
@ -358,8 +359,9 @@ void LoadWin32Font(FontSize fs)
if (AddFontResourceEx(fontPath, FR_PRIVATE, 0) != 0) {
/* Try a nice little undocumented function first for getting the internal font name.
* Some documentation is found at: http://www.undocprint.org/winspool/getfontresourceinfo */
static LibraryLoader _gdi32("gdi32.dll");
typedef BOOL(WINAPI *PFNGETFONTRESOURCEINFO)(LPCTSTR, LPDWORD, LPVOID, DWORD);
static PFNGETFONTRESOURCEINFO GetFontResourceInfo = GetProcAddressT<PFNGETFONTRESOURCEINFO>(GetModuleHandle(L"Gdi32"), "GetFontResourceInfoW");
static PFNGETFONTRESOURCEINFO GetFontResourceInfo = _gdi32.GetFunction("GetFontResourceInfoW");
if (GetFontResourceInfo != nullptr) {
/* Try to query an array of LOGFONTs that describe the file. */

@ -13,6 +13,8 @@
#include "../../fontcache/truetypefontcache.h"
#include "win32.h"
#include <windows.h>
/** Font cache for fonts that are based on a Win32 font. */
class Win32FontCache : public TrueTypeFontCache {
private:

@ -0,0 +1,59 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file library_loader_win.cpp Implementation of the LibraryLoader for Windows */
#include "../../stdafx.h"
#include <windows.h>
#include "../../library_loader.h"
#include "../../core/format.hpp"
#include "../../safeguards.h"
static std::string GetLoadError()
{
auto error_code = GetLastError();
char buffer[512];
if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, error_code,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, sizeof(buffer), nullptr) == 0) {
return fmt::format("Unknown error {}", error_code);
}
return buffer;
}
void *LibraryLoader::OpenLibrary(const std::string &filename)
{
void *h = ::LoadLibraryW(OTTD2FS(filename).c_str());
if (h == nullptr) {
this->error = GetLoadError();
}
return h;
}
void LibraryLoader::CloseLibrary()
{
HMODULE handle = static_cast<HMODULE>(this->handle);
::FreeLibrary(handle);
}
void *LibraryLoader::GetSymbol(const std::string &symbol_name)
{
HMODULE handle = static_cast<HMODULE>(this->handle);
void *p = reinterpret_cast<void *>(::GetProcAddress(handle, symbol_name.c_str()));
if (p == nullptr) {
this->error = GetLoadError();
}
return p;
}

@ -418,7 +418,7 @@ static std::vector<SCRIPT_ITEM> UniscribeItemizeString(UniscribeParagraphLayoutF
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 && remaining_offset < (last_run - 1)->len) {
if (i_run == last_run - 1 && remaining_offset <= (last_run - 1)->len) {
run.len = remaining_offset - 1;
if (!UniscribeShapeRun(this->text_buffer, run)) return nullptr;

@ -31,12 +31,17 @@
#include <sys/stat.h>
#include "../../language.h"
#include "../../thread.h"
#include "../../library_loader.h"
#include <array>
#include <map>
#include <mutex>
#include "../../safeguards.h"
#if defined(__MINGW32__) && !defined(__MINGW64__) && !(_WIN32_IE >= 0x0500)
#define SHGFP_TYPE_CURRENT 0
#endif /* __MINGW32__ */
static bool _has_console;
static bool _cursor_disable = true;
static bool _cursor_visible = true;
@ -53,30 +58,6 @@ bool MyShowCursor(bool show, bool toggle)
return !show;
}
/**
* Helper function needed by dynamically loading libraries
*/
bool LoadLibraryList(Function proc[], const char *dll)
{
while (*dll != '\0') {
HMODULE lib;
lib = LoadLibrary(OTTD2FS(dll).c_str());
if (lib == nullptr) return false;
for (;;) {
Function p;
while (*dll++ != '\0') { /* Nothing */ }
if (*dll == '\0') break;
p = GetProcAddressT<Function>(lib, dll);
if (p == nullptr) return false;
*proc++ = p;
}
dll++;
}
return true;
}
void ShowOSErrorBox(const char *buf, bool system)
{
MyShowCursor(true);
@ -614,7 +595,8 @@ int OTTDStringCompare(std::string_view s1, std::string_view s2)
#endif
if (first_time) {
_CompareStringEx = GetProcAddressT<PFNCOMPARESTRINGEX>(GetModuleHandle(L"Kernel32"), "CompareStringEx");
static LibraryLoader _kernel32("Kernel32.dll");
_CompareStringEx = _kernel32.GetFunction("CompareStringEx");
first_time = false;
}
@ -657,7 +639,8 @@ int Win32StringContains(const std::string_view str, const std::string_view value
static bool first_time = true;
if (first_time) {
_FindNLSStringEx = GetProcAddressT<PFNFINDNLSSTRINGEX>(GetModuleHandle(L"Kernel32"), "FindNLSStringEx");
static LibraryLoader _kernel32("Kernel32.dll");
_FindNLSStringEx = _kernel32.GetFunction("FindNLSStringEx");
first_time = false;
}
@ -704,7 +687,8 @@ void PerThreadSetup()
void PerThreadSetupInit()
{
LoadLibraryList((Function*)&_SetThreadStackGuarantee, "kernel32.dll\0SetThreadStackGuarantee\0\0");
static LibraryLoader _kernel32("Kernel32.dll");
_SetThreadStackGuarantee = _kernel32.GetFunction("SetThreadStackGuarantee");
}
bool IsMainThread()

@ -10,19 +10,11 @@
#ifndef WIN32_H
#define WIN32_H
#include <windows.h>
bool MyShowCursor(bool show, bool toggle = false);
typedef void (*Function)(int);
bool LoadLibraryList(Function proc[], const char *dll);
char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen);
wchar_t *convert_to_fs(const std::string_view name, wchar_t *utf16_buf, size_t buflen);
#if defined(__MINGW32__) && !defined(__MINGW64__) && !(_WIN32_IE >= 0x0500)
#define SHGFP_TYPE_CURRENT 0
#endif /* __MINGW32__ */
void Win32SetCurrentLocaleName(const char *iso_code);
int OTTDStringCompare(std::string_view s1, std::string_view s2);
int Win32StringContains(const std::string_view str, const std::string_view value, bool case_insensitive);
@ -33,12 +25,6 @@ int Win32StringContains(const std::string_view str, const std::string_view value
#pragma GCC diagnostic ignored "-Wcast-function-type"
#endif /* __MINGW32__ */
template <typename T>
T GetProcAddressT(HMODULE hModule, LPCSTR lpProcName)
{
return reinterpret_cast<T>(GetProcAddress(hModule, lpProcName));
}
#ifdef __MINGW32__
#pragma GCC diagnostic pop
#endif

@ -9,7 +9,6 @@
#include "../../stdafx.h"
#include "script_list.hpp"
#include "script_controller.hpp"
#include "../../debug.h"
#include "../../script/squirrel.hpp"
@ -1074,16 +1073,6 @@ SQInteger ScriptList::Valuate(HSQUIRRELVM vm)
}
}
/* Kill the script when the valuator call takes way too long.
* Triggered by nesting valuators, which then take billions of iterations. */
if (ScriptController::GetOpsTillSuspend() < -1000000) {
/* See below for explanation. The extra pop is the return value. */
sq_pop(vm, nparam + 4);
ScriptObject::SetAllowDoCommand(backup_allow);
return sq_throwerror(vm, "excessive CPU usage in valuator function");
}
/* Was something changed? */
if (previous_modification_count != this->modifications) {
/* See below for explanation. The extra pop is the return value. */

@ -158,7 +158,7 @@ const char *SoundDriver_XAudio2::Start(const StringList &parm)
return "Failed to load XAudio2 DLL";
}
API_XAudio2Create xAudio2Create = GetProcAddressT<API_XAudio2Create>(_xaudio_dll_handle, "XAudio2Create");
API_XAudio2Create xAudio2Create = (API_XAudio2Create) GetProcAddress(_xaudio_dll_handle, "XAudio2Create");
if (xAudio2Create == nullptr)
{

@ -21,6 +21,7 @@
#include "../window_gui.h"
#include "../window_func.h"
#include "../framerate_type.h"
#include "../library_loader.h"
#include "win32_v.h"
#include <windows.h>
#include <imm.h>
@ -987,10 +988,11 @@ float VideoDriver_Win32Base::GetDPIScale()
static bool init_done = false;
if (!init_done) {
init_done = true;
_GetDpiForWindow = GetProcAddressT<PFNGETDPIFORWINDOW>(GetModuleHandle(L"User32"), "GetDpiForWindow");
_GetDpiForSystem = GetProcAddressT<PFNGETDPIFORSYSTEM>(GetModuleHandle(L"User32"), "GetDpiForSystem");
_GetDpiForMonitor = GetProcAddressT<PFNGETDPIFORMONITOR>(LoadLibrary(L"Shcore.dll"), "GetDpiForMonitor");
static LibraryLoader _user32("user32.dll");
static LibraryLoader _shcore("shcore.dll");
_GetDpiForWindow = _user32.GetFunction("GetDpiForWindow");
_GetDpiForSystem = _user32.GetFunction("GetDpiForSystem");
_GetDpiForMonitor = _shcore.GetFunction("GetDpiForMonitor");
}
UINT cur_dpi = 0;

@ -14,6 +14,7 @@
#include <mutex>
#include <condition_variable>
#include <vector>
#include <windows.h>
/** Base class for Windows video drivers. */
class VideoDriver_Win32Base : public VideoDriver {

Loading…
Cancel
Save