mirror of https://github.com/OpenTTD/OpenTTD
Compare commits
6 Commits
9a27fff66c
...
5459c78603
Author | SHA1 | Date |
---|---|---|
|
5459c78603 | |
|
ae917cb8c6 | |
|
e6b45731c0 | |
|
24f173e7a8 | |
|
ccfb40944b | |
|
5b0e9f82d5 |
|
@ -449,6 +449,7 @@ if(WIN32)
|
||||||
psapi
|
psapi
|
||||||
winhttp
|
winhttp
|
||||||
bcrypt
|
bcrypt
|
||||||
|
xinput
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,7 @@ void HandleTextInput(std::string_view str, bool marked = false,
|
||||||
std::optional<size_t> insert_location = std::nullopt, std::optional<size_t> replacement_end = std::nullopt);
|
std::optional<size_t> insert_location = std::nullopt, std::optional<size_t> replacement_end = std::nullopt);
|
||||||
void HandleCtrlChanged();
|
void HandleCtrlChanged();
|
||||||
void HandleMouseEvents();
|
void HandleMouseEvents();
|
||||||
|
void HandleGamepadScrolling(int stick_x, int stick_y, int max_axis_value);
|
||||||
void UpdateWindows();
|
void UpdateWindows();
|
||||||
void ChangeGameSpeed(bool enable_fast_forward);
|
void ChangeGameSpeed(bool enable_fast_forward);
|
||||||
|
|
||||||
|
|
|
@ -1700,6 +1700,25 @@ STR_CONFIG_SETTING_SCROLLWHEEL_ZOOM :Zoom map
|
||||||
STR_CONFIG_SETTING_SCROLLWHEEL_SCROLL :Scroll map
|
STR_CONFIG_SETTING_SCROLLWHEEL_SCROLL :Scroll map
|
||||||
STR_CONFIG_SETTING_SCROLLWHEEL_OFF :Off
|
STR_CONFIG_SETTING_SCROLLWHEEL_OFF :Off
|
||||||
|
|
||||||
|
STR_CONFIG_SETTING_GAMEPAD_STICK_SELECTION :Gamepad stick for scrolling: {STRING2}
|
||||||
|
STR_CONFIG_SETTING_GAMEPAD_STICK_SELECTION_HELPTEXT :Select which analog stick to use for map scrolling
|
||||||
|
###length 3
|
||||||
|
STR_CONFIG_SETTING_GAMEPAD_STICK_DISABLED :Disabled
|
||||||
|
STR_CONFIG_SETTING_GAMEPAD_STICK_LEFT :Left stick
|
||||||
|
STR_CONFIG_SETTING_GAMEPAD_STICK_RIGHT :Right stick
|
||||||
|
|
||||||
|
STR_CONFIG_SETTING_GAMEPAD_DEADZONE :Gamepad deadzone: {STRING2}%
|
||||||
|
STR_CONFIG_SETTING_GAMEPAD_DEADZONE_HELPTEXT :Minimum stick movement required before scrolling starts (0-100%)
|
||||||
|
|
||||||
|
STR_CONFIG_SETTING_GAMEPAD_SENSITIVITY :Gamepad sensitivity: {STRING2}
|
||||||
|
STR_CONFIG_SETTING_GAMEPAD_SENSITIVITY_HELPTEXT :Control the sensitivity of gamepad analog stick scrolling
|
||||||
|
|
||||||
|
STR_CONFIG_SETTING_GAMEPAD_INVERT_X :Invert gamepad X-axis: {STRING2}
|
||||||
|
STR_CONFIG_SETTING_GAMEPAD_INVERT_X_HELPTEXT :Invert the horizontal axis movement of the gamepad analog stick
|
||||||
|
|
||||||
|
STR_CONFIG_SETTING_GAMEPAD_INVERT_Y :Invert gamepad Y-axis: {STRING2}
|
||||||
|
STR_CONFIG_SETTING_GAMEPAD_INVERT_Y_HELPTEXT :Invert the vertical axis movement of the gamepad analog stick
|
||||||
|
|
||||||
STR_CONFIG_SETTING_OSK_ACTIVATION :On screen keyboard: {STRING2}
|
STR_CONFIG_SETTING_OSK_ACTIVATION :On screen keyboard: {STRING2}
|
||||||
STR_CONFIG_SETTING_OSK_ACTIVATION_HELPTEXT :Select the method to open the on screen keyboard for entering text into editboxes only using the pointing device. This is meant for small devices without actual keyboard
|
STR_CONFIG_SETTING_OSK_ACTIVATION_HELPTEXT :Select the method to open the on screen keyboard for entering text into editboxes only using the pointing device. This is meant for small devices without actual keyboard
|
||||||
###length 4
|
###length 4
|
||||||
|
|
|
@ -267,6 +267,7 @@ STR_UNITS_YEARS :{NUM}{NBSP}năm
|
||||||
STR_UNITS_PERIODS :{NUM}{NBSP}kỳ
|
STR_UNITS_PERIODS :{NUM}{NBSP}kỳ
|
||||||
|
|
||||||
STR_LIST_SEPARATOR :,{SPACE}
|
STR_LIST_SEPARATOR :,{SPACE}
|
||||||
|
STR_TRUNCATION_ELLIPSIS :...
|
||||||
|
|
||||||
# Common window strings
|
# Common window strings
|
||||||
STR_LIST_FILTER_TITLE :{BLACK}Lọc:
|
STR_LIST_FILTER_TITLE :{BLACK}Lọc:
|
||||||
|
@ -285,7 +286,7 @@ STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Đóng c
|
||||||
STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Tiêu đề cửa sổ - kéo nó để di chuyển cửa số
|
STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Tiêu đề cửa sổ - kéo nó để di chuyển cửa số
|
||||||
STR_TOOLTIP_SHADE :{BLACK}Thu gọn cửa sổ - Chỉ hiển thị thanh tiêu đề
|
STR_TOOLTIP_SHADE :{BLACK}Thu gọn cửa sổ - Chỉ hiển thị thanh tiêu đề
|
||||||
STR_TOOLTIP_DEBUG :{BLACK}Hiện thông tin debug của NewGRF
|
STR_TOOLTIP_DEBUG :{BLACK}Hiện thông tin debug của NewGRF
|
||||||
STR_TOOLTIP_DEFSIZE :{BLACK}Chuyển cửa sổ về kích thước mặc định. Ctrl+Click để lưu kích thước hiện tại làm mặc định
|
STR_TOOLTIP_DEFSIZE :{BLACK}Chuyển cửa sổ về kích thước mặc định. Ctrl+Click để lưu kích thước hiện tại làm mặc định. Ctri+Click kép để thiết lập lại mặc định cũ.
|
||||||
STR_TOOLTIP_STICKY :{BLACK}Đánh dấu không-thể-đóng khi bấm nút "Đóng Tất Cả Cửa Sổ". Ctrl+Click để lưu thành trạng thái mặc định
|
STR_TOOLTIP_STICKY :{BLACK}Đánh dấu không-thể-đóng khi bấm nút "Đóng Tất Cả Cửa Sổ". Ctrl+Click để lưu thành trạng thái mặc định
|
||||||
STR_TOOLTIP_RESIZE :{BLACK}Click và kéo để thay đổi kích thước cửa sổ
|
STR_TOOLTIP_RESIZE :{BLACK}Click và kéo để thay đổi kích thước cửa sổ
|
||||||
STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Bật kích cỡ cửa sổ lớn/nhỏ
|
STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Bật kích cỡ cửa sổ lớn/nhỏ
|
||||||
|
@ -451,6 +452,12 @@ STR_SETTINGS_MENU_SANDBOX_OPTIONS :Tuỳ chọn Sa
|
||||||
STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Thiết lập hiệu ứng trong suốt
|
STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Thiết lập hiệu ứng trong suốt
|
||||||
STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Hiển thị tên thị trấn
|
STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Hiển thị tên thị trấn
|
||||||
STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED :Hiển thị tên nhà ga
|
STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED :Hiển thị tên nhà ga
|
||||||
|
STR_SETTINGS_MENU_STATION_NAMES_TRAIN :Ga tàu
|
||||||
|
STR_SETTINGS_MENU_STATION_NAMES_LORRY :Trạm xe tải
|
||||||
|
STR_SETTINGS_MENU_STATION_NAMES_BUS :Trạm xe buýt
|
||||||
|
STR_SETTINGS_MENU_STATION_NAMES_SHIP :Cảng
|
||||||
|
STR_SETTINGS_MENU_STATION_NAMES_PLANE :Sân bay
|
||||||
|
STR_SETTINGS_MENU_STATION_NAMES_GHOST :Trạm ma
|
||||||
STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED :Hiển thị tên điểm mốc
|
STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED :Hiển thị tên điểm mốc
|
||||||
STR_SETTINGS_MENU_SIGNS_DISPLAYED :Hiển thị ký hiệu
|
STR_SETTINGS_MENU_SIGNS_DISPLAYED :Hiển thị ký hiệu
|
||||||
STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS :Hiển thị biển hiệu và tên của đối thủ
|
STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS :Hiển thị biển hiệu và tên của đối thủ
|
||||||
|
@ -627,8 +634,11 @@ STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL :{BLACK}Không h
|
||||||
STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO :{BLACK}Bật/tắt đồ thị cho hàng hóa này
|
STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO :{BLACK}Bật/tắt đồ thị cho hàng hóa này
|
||||||
STR_GRAPH_CARGO_PAYMENT_CARGO :{TINY_FONT}{BLACK}{STRING}
|
STR_GRAPH_CARGO_PAYMENT_CARGO :{TINY_FONT}{BLACK}{STRING}
|
||||||
|
|
||||||
|
STR_GRAPH_INDUSTRY_CAPTION :{WHITE}{INDUSTRY} - Lịch sử hàng hóa
|
||||||
STR_GRAPH_INDUSTRY_RANGE_PRODUCED :Đã cung cấp
|
STR_GRAPH_INDUSTRY_RANGE_PRODUCED :Đã cung cấp
|
||||||
STR_GRAPH_INDUSTRY_RANGE_TRANSPORTED :Đã vận chuyển
|
STR_GRAPH_INDUSTRY_RANGE_TRANSPORTED :Đã vận chuyển
|
||||||
|
STR_GRAPH_INDUSTRY_RANGE_DELIVERED :Đã giao
|
||||||
|
STR_GRAPH_INDUSTRY_RANGE_WAITING :Đang chờ...
|
||||||
|
|
||||||
STR_GRAPH_PERFORMANCE_DETAIL_TOOLTIP :{BLACK}Hiện chi tiết đánh giá chỉ số năng suất
|
STR_GRAPH_PERFORMANCE_DETAIL_TOOLTIP :{BLACK}Hiện chi tiết đánh giá chỉ số năng suất
|
||||||
|
|
||||||
|
@ -958,11 +968,14 @@ STR_GAME_OPTIONS_TAB_SOUND :Âm thanh
|
||||||
STR_GAME_OPTIONS_TAB_SOUND_TOOLTIP :Lựa chọn thiết lập cho âm thanh và nhạc
|
STR_GAME_OPTIONS_TAB_SOUND_TOOLTIP :Lựa chọn thiết lập cho âm thanh và nhạc
|
||||||
STR_GAME_OPTIONS_TAB_SOCIAL :Xã hội
|
STR_GAME_OPTIONS_TAB_SOCIAL :Xã hội
|
||||||
STR_GAME_OPTIONS_TAB_SOCIAL_TOOLTIP :Chọn thiết lập các tích hợp xã hội
|
STR_GAME_OPTIONS_TAB_SOCIAL_TOOLTIP :Chọn thiết lập các tích hợp xã hội
|
||||||
|
STR_GAME_OPTIONS_TAB_ADVANCED :Tùy chọn nâng cao
|
||||||
|
STR_GAME_OPTIONS_TAB_ADVANCED_TOOLTIP :Thay đổi tùy chọn nâng cao
|
||||||
|
|
||||||
STR_GAME_OPTIONS_VOLUME :Âm lượng
|
STR_GAME_OPTIONS_VOLUME :Âm lượng
|
||||||
STR_GAME_OPTIONS_SFX_VOLUME :Hiệu ứng âm thanh
|
STR_GAME_OPTIONS_SFX_VOLUME :Hiệu ứng âm thanh
|
||||||
STR_GAME_OPTIONS_MUSIC_VOLUME :Âm nhạc
|
STR_GAME_OPTIONS_MUSIC_VOLUME :Âm nhạc
|
||||||
|
|
||||||
|
STR_GAME_OPTIONS_SETTING :{STRING}: {ORANGE}{STRING}
|
||||||
|
|
||||||
STR_GAME_OPTIONS_VOLUME_MARK :{NUM}%
|
STR_GAME_OPTIONS_VOLUME_MARK :{NUM}%
|
||||||
|
|
||||||
|
@ -1016,6 +1029,7 @@ STR_GAME_OPTIONS_CURRENCY_IDR :Rupiah Indonesi
|
||||||
STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit Malaysia
|
STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit Malaysia
|
||||||
STR_GAME_OPTIONS_CURRENCY_LVL :Lát-vi-a Lats
|
STR_GAME_OPTIONS_CURRENCY_LVL :Lát-vi-a Lats
|
||||||
STR_GAME_OPTIONS_CURRENCY_PTE :Escudo Bồ Đào Nha
|
STR_GAME_OPTIONS_CURRENCY_PTE :Escudo Bồ Đào Nha
|
||||||
|
STR_GAME_OPTIONS_CURRENCY_UAH :Hryvnia Ukraina
|
||||||
|
|
||||||
STR_GAME_OPTIONS_AUTOSAVE_FRAME :Lưu tự động
|
STR_GAME_OPTIONS_AUTOSAVE_FRAME :Lưu tự động
|
||||||
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :Lựa chọn khoảng thời gian tự động lưu
|
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :Lựa chọn khoảng thời gian tự động lưu
|
||||||
|
@ -1049,6 +1063,7 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :Đánh dấu v
|
||||||
|
|
||||||
STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :Trình điều khiển hiện tại: {STRING}
|
STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :Trình điều khiển hiện tại: {STRING}
|
||||||
|
|
||||||
|
STR_GAME_OPTIONS_INTERFACE :Giao diện
|
||||||
|
|
||||||
STR_GAME_OPTIONS_GUI_SCALE_FRAME :Kích thước giao diện
|
STR_GAME_OPTIONS_GUI_SCALE_FRAME :Kích thước giao diện
|
||||||
STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :Kéo thanh trượt để điều chỉnh kích thước giao diện. Giữ Ctrl để điều chỉnh liên tục
|
STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :Kéo thanh trượt để điều chỉnh kích thước giao diện. Giữ Ctrl để điều chỉnh liên tục
|
||||||
|
@ -1073,6 +1088,7 @@ STR_GAME_OPTIONS_PARTICIPATE_SURVEY_LINK_TOOLTIP :Sẽ mở trìn
|
||||||
STR_GAME_OPTIONS_PARTICIPATE_SURVEY_PREVIEW :Xem trước kết quả khảo sát
|
STR_GAME_OPTIONS_PARTICIPATE_SURVEY_PREVIEW :Xem trước kết quả khảo sát
|
||||||
STR_GAME_OPTIONS_PARTICIPATE_SURVEY_PREVIEW_TOOLTIP :Hiển thị kết quả khảo sát ở ván chơi hiện tại
|
STR_GAME_OPTIONS_PARTICIPATE_SURVEY_PREVIEW_TOOLTIP :Hiển thị kết quả khảo sát ở ván chơi hiện tại
|
||||||
|
|
||||||
|
STR_GAME_OPTIONS_DISPLAY :Hiển thị
|
||||||
|
|
||||||
STR_GAME_OPTIONS_REFRESH_RATE :Tần số quét màn hình
|
STR_GAME_OPTIONS_REFRESH_RATE :Tần số quét màn hình
|
||||||
STR_GAME_OPTIONS_REFRESH_RATE_TOOLTIP :Chọn tần số quét màn hình
|
STR_GAME_OPTIONS_REFRESH_RATE_TOOLTIP :Chọn tần số quét màn hình
|
||||||
|
@ -1094,7 +1110,7 @@ STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP :Thông tin thê
|
||||||
STR_GAME_OPTIONS_ONLINE_CONTENT :Tải Nội Dung
|
STR_GAME_OPTIONS_ONLINE_CONTENT :Tải Nội Dung
|
||||||
STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP :Kiểm tra những nội dung mới & cập nhật để tải về
|
STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP :Kiểm tra những nội dung mới & cập nhật để tải về
|
||||||
|
|
||||||
STR_GAME_OPTIONS_SOCIAL_PLUGINS_NONE :{LTBLUE}(không có plugins được cài đặt để tích hợp vào nền tảng xã hội)
|
STR_GAME_OPTIONS_SOCIAL_PLUGINS_NONE :(không có plugins được cài đặt để tích hợp vào nền tảng xã hội)
|
||||||
|
|
||||||
STR_GAME_OPTIONS_SOCIAL_PLUGIN_TITLE :{STRING} ({STRING})
|
STR_GAME_OPTIONS_SOCIAL_PLUGIN_TITLE :{STRING} ({STRING})
|
||||||
STR_GAME_OPTIONS_SOCIAL_PLUGIN_PLATFORM :Nền tảng:
|
STR_GAME_OPTIONS_SOCIAL_PLUGIN_PLATFORM :Nền tảng:
|
||||||
|
@ -1288,6 +1304,9 @@ STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Lãi xuất vay
|
||||||
STR_CONFIG_SETTING_RUNNING_COSTS :Chi phí hoạt động: {STRING}
|
STR_CONFIG_SETTING_RUNNING_COSTS :Chi phí hoạt động: {STRING}
|
||||||
STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Thiết lập mức độ tính chi phí bảo trì và vận hành đối với phương tiện và hạ tầng giao thông
|
STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Thiết lập mức độ tính chi phí bảo trì và vận hành đối với phương tiện và hạ tầng giao thông
|
||||||
###length 3
|
###length 3
|
||||||
|
STR_CONFIG_SETTING_RUNNING_COSTS_LOW :Thấp
|
||||||
|
STR_CONFIG_SETTING_RUNNING_COSTS_MEDIUM :Trung bình
|
||||||
|
STR_CONFIG_SETTING_RUNNING_COSTS_HIGH :Cao
|
||||||
|
|
||||||
STR_CONFIG_SETTING_CONSTRUCTION_SPEED :Tốc độ xây dựng: {STRING}
|
STR_CONFIG_SETTING_CONSTRUCTION_SPEED :Tốc độ xây dựng: {STRING}
|
||||||
STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :Giới hạn hành động xây dựng của AI
|
STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :Giới hạn hành động xây dựng của AI
|
||||||
|
@ -1310,6 +1329,9 @@ STR_CONFIG_SETTING_SUBSIDY_DURATION_DISABLED :Không có tr
|
||||||
STR_CONFIG_SETTING_CONSTRUCTION_COSTS :Chi phí xây dựng: {STRING}
|
STR_CONFIG_SETTING_CONSTRUCTION_COSTS :Chi phí xây dựng: {STRING}
|
||||||
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :Thiết lập mức độ xây dựng và chi phí mua sắm
|
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :Thiết lập mức độ xây dựng và chi phí mua sắm
|
||||||
###length 3
|
###length 3
|
||||||
|
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_LOW :Thấp
|
||||||
|
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_MEDIUM :Trung bình
|
||||||
|
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HIGH :Cao
|
||||||
|
|
||||||
STR_CONFIG_SETTING_RECESSIONS :Suy thoái: {STRING}
|
STR_CONFIG_SETTING_RECESSIONS :Suy thoái: {STRING}
|
||||||
STR_CONFIG_SETTING_RECESSIONS_HELPTEXT :Nếu bật, thì các đợt suy thoái sẽ xảy ra vài năm một lần. Trong suy thoái tất cả sản xuất sẽ giảm mạnh (và sẽ trở lại như cũ sau khi suy thoái kết thúc)
|
STR_CONFIG_SETTING_RECESSIONS_HELPTEXT :Nếu bật, thì các đợt suy thoái sẽ xảy ra vài năm một lần. Trong suy thoái tất cả sản xuất sẽ giảm mạnh (và sẽ trở lại như cũ sau khi suy thoái kết thúc)
|
||||||
|
@ -1979,8 +2001,12 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :không cho phé
|
||||||
STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :cho phép
|
STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :cho phép
|
||||||
STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :cho phép, tùy chọn bố trí đô thị
|
STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :cho phép, tùy chọn bố trí đô thị
|
||||||
|
|
||||||
|
STR_CONFIG_SETTING_HOUSE_PLACER :Đật từng ngôi nhà: {STRING}
|
||||||
STR_CONFIG_SETTING_HOUSE_PLACER_HELPTEXT :Bật tùy chọn này cho phép người chơi đặt nhà cửa bằng tay
|
STR_CONFIG_SETTING_HOUSE_PLACER_HELPTEXT :Bật tùy chọn này cho phép người chơi đặt nhà cửa bằng tay
|
||||||
###length 3
|
###length 3
|
||||||
|
STR_CONFIG_SETTING_HOUSE_PLACER_FORBIDDEN :Không cho phép
|
||||||
|
STR_CONFIG_SETTING_HOUSE_PLACER_ALLOWED :Cho phép
|
||||||
|
STR_CONFIG_SETTING_HOUSE_PLACER_FULLY_CONSTRUCTED :Cho phép, đã hoàn thành thi công
|
||||||
|
|
||||||
STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Nhu cầu vận chuyển hàng đô thị: {STRING}
|
STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Nhu cầu vận chuyển hàng đô thị: {STRING}
|
||||||
STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Lượng hàng hoá cần vận chuyển ở trong đô thị, tỉ lệ với tổng dân số của độ thị.{}Tăng tỉ lệ bình phương: một đô thị to gấp 2 sẽ tăng 4 lần số hành khách.{}Tăng tỉ lệ thuận: một đô thị tăng gấp 2 sẽ tăng gấp 2 lần số hành khách
|
STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Lượng hàng hoá cần vận chuyển ở trong đô thị, tỉ lệ với tổng dân số của độ thị.{}Tăng tỉ lệ bình phương: một đô thị to gấp 2 sẽ tăng 4 lần số hành khách.{}Tăng tỉ lệ thuận: một đô thị tăng gấp 2 sẽ tăng gấp 2 lần số hành khách
|
||||||
|
@ -2009,7 +2035,7 @@ STR_CONFIG_SETTING_SOFT_LIMIT :Giới hạn s
|
||||||
STR_CONFIG_SETTING_SOFT_LIMIT_HELPTEXT :Số lượng cửa sổ chưa neo (tối đa) trước khi tự động đóng để nhường chỗ khi mở cửa sổ mới
|
STR_CONFIG_SETTING_SOFT_LIMIT_HELPTEXT :Số lượng cửa sổ chưa neo (tối đa) trước khi tự động đóng để nhường chỗ khi mở cửa sổ mới
|
||||||
STR_CONFIG_SETTING_SOFT_LIMIT_VALUE :{COMMA}
|
STR_CONFIG_SETTING_SOFT_LIMIT_VALUE :{COMMA}
|
||||||
###setting-zero-is-special
|
###setting-zero-is-special
|
||||||
STR_CONFIG_SETTING_SOFT_LIMIT_DISABLED :tắt
|
STR_CONFIG_SETTING_SOFT_LIMIT_DISABLED :Tắt
|
||||||
|
|
||||||
STR_CONFIG_SETTING_ZOOM_MIN :Độ phóng to tối đa: {STRING}
|
STR_CONFIG_SETTING_ZOOM_MIN :Độ phóng to tối đa: {STRING}
|
||||||
STR_CONFIG_SETTING_ZOOM_MIN_HELPTEXT :Độ phóng to tối đa của cửa sổ. Độ càng cao thì yêu cầu bộ nhớ càng nhiều
|
STR_CONFIG_SETTING_ZOOM_MIN_HELPTEXT :Độ phóng to tối đa của cửa sổ. Độ càng cao thì yêu cầu bộ nhớ càng nhiều
|
||||||
|
@ -2061,9 +2087,9 @@ STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Loại hàng h
|
||||||
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Chế độ phân phối đối với các loại hàng hóa mặc định: {STRING}
|
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Chế độ phân phối đối với các loại hàng hóa mặc định: {STRING}
|
||||||
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Không đối xứng" có nghĩa là số lượng hàng hóa tùy ý có thể được gửi theo một trong hai hướng. "Thủ công" có nghĩa là những loại hàng hóa đó sẽ không được phân phối tự động
|
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Không đối xứng" có nghĩa là số lượng hàng hóa tùy ý có thể được gửi theo một trong hai hướng. "Thủ công" có nghĩa là những loại hàng hóa đó sẽ không được phân phối tự động
|
||||||
###length 3
|
###length 3
|
||||||
STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :bằng tay
|
STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :Bằng tay
|
||||||
STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :bất đối xứng
|
STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :Bất đối xứng
|
||||||
STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :đối xứng
|
STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :Đối xứng
|
||||||
|
|
||||||
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Độ chính xác phân phối: {STRING}
|
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Độ chính xác phân phối: {STRING}
|
||||||
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Mức chính xác tính toán đồ thị, nếu giá trị càng cao càng tốn CPU và trò chơi có thể chậm phản ứng, tuy nhiên giá trị thấp sẽ khiến việc phân phối sẽ giảm sự chính xác và bạn sẽ thấy sự khác biệt là hàng hóa không gửi đến chỗ cần đến
|
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Mức chính xác tính toán đồ thị, nếu giá trị càng cao càng tốn CPU và trò chơi có thể chậm phản ứng, tuy nhiên giá trị thấp sẽ khiến việc phân phối sẽ giảm sự chính xác và bạn sẽ thấy sự khác biệt là hàng hóa không gửi đến chỗ cần đến
|
||||||
|
@ -2124,7 +2150,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m)
|
||||||
STR_CONFIG_SETTING_LOCALISATION :Tiêu Chuẩn Đo Lường
|
STR_CONFIG_SETTING_LOCALISATION :Tiêu Chuẩn Đo Lường
|
||||||
STR_CONFIG_SETTING_GRAPHICS :Đồ họa
|
STR_CONFIG_SETTING_GRAPHICS :Đồ họa
|
||||||
STR_CONFIG_SETTING_SOUND :Âm thanh
|
STR_CONFIG_SETTING_SOUND :Âm thanh
|
||||||
STR_CONFIG_SETTING_INTERFACE :Giao Diện
|
STR_CONFIG_SETTING_INTERFACE :Giao diện
|
||||||
STR_CONFIG_SETTING_INTERFACE_GENERAL :Tổng quát
|
STR_CONFIG_SETTING_INTERFACE_GENERAL :Tổng quát
|
||||||
STR_CONFIG_SETTING_INTERFACE_VIEWPORTS :Vùng nhìn
|
STR_CONFIG_SETTING_INTERFACE_VIEWPORTS :Vùng nhìn
|
||||||
STR_CONFIG_SETTING_INTERFACE_CONSTRUCTION :Xây Dựng
|
STR_CONFIG_SETTING_INTERFACE_CONSTRUCTION :Xây Dựng
|
||||||
|
@ -2178,6 +2204,8 @@ STR_VIDEO_DRIVER_ERROR_NO_HARDWARE_ACCELERATION :{WHITE}... khô
|
||||||
STR_VIDEO_DRIVER_ERROR_HARDWARE_ACCELERATION_CRASH :{WHITE}... trình điều khiển GPU đã làm trò chơi bị lỗi. Tăng tốc phần cứng đã được tắt
|
STR_VIDEO_DRIVER_ERROR_HARDWARE_ACCELERATION_CRASH :{WHITE}... trình điều khiển GPU đã làm trò chơi bị lỗi. Tăng tốc phần cứng đã được tắt
|
||||||
|
|
||||||
# Intro window
|
# Intro window
|
||||||
|
STR_INTRO_CAPTION :{WHITE}OpenTTD
|
||||||
|
STR_INTRO_VERSION :OpenTTD {REV}
|
||||||
|
|
||||||
STR_INTRO_NEW_GAME :{BLACK}Màn Chơi Mới
|
STR_INTRO_NEW_GAME :{BLACK}Màn Chơi Mới
|
||||||
STR_INTRO_LOAD_GAME :{BLACK}Nạp Ván Chơi
|
STR_INTRO_LOAD_GAME :{BLACK}Nạp Ván Chơi
|
||||||
|
@ -2311,16 +2339,19 @@ STR_FACE_SIMPLE_TOOLTIP :{BLACK}Trình c
|
||||||
STR_FACE_LOAD :{BLACK}Nạp
|
STR_FACE_LOAD :{BLACK}Nạp
|
||||||
STR_FACE_LOAD_TOOLTIP :{BLACK}Chọn vẻ mặt ưa thích
|
STR_FACE_LOAD_TOOLTIP :{BLACK}Chọn vẻ mặt ưa thích
|
||||||
STR_FACE_LOAD_DONE :{WHITE}Vẻ mặt ưa thích đã được nạp từ file thiết lập của OpenTTD.
|
STR_FACE_LOAD_DONE :{WHITE}Vẻ mặt ưa thích đã được nạp từ file thiết lập của OpenTTD.
|
||||||
STR_FACE_FACECODE :{BLACK}Khuôn mặt thứ.
|
STR_FACE_FACECODE :{BLACK}Mã số khuôn mặt
|
||||||
STR_FACE_FACECODE_TOOLTIP :{BLACK}Xem và/hoặc sửa số vẻ mặt của chủ tịch công ty
|
STR_FACE_FACECODE_TOOLTIP :{BLACK}Xem và/hoặc sửa mã số gương mặt của chủ tịch công ty
|
||||||
STR_FACE_FACECODE_CAPTION :{WHITE}Xem và/hoặc chọn số bộ mặt người chơi
|
STR_FACE_FACECODE_CAPTION :{WHITE}Xem và/hoặc chọn mã số gương mặt người chơi
|
||||||
STR_FACE_FACECODE_SET :{WHITE}Mã số gương mặt mới được thiết lập.
|
STR_FACE_FACECODE_SET :{WHITE}Gương mặt người chơi mới được thiết lập.
|
||||||
STR_FACE_FACECODE_ERR :{WHITE}Không thể thiết lập mã số gương mặt - mã số phải trong khoảng từ 0 đến 4,294,967,295!
|
STR_FACE_FACECODE_ERR :{WHITE}Không thể thiết lập mã số gương mặt - Nhãn và mã số phải hợp lệ
|
||||||
STR_FACE_SAVE :{BLACK}Lưu
|
STR_FACE_SAVE :{BLACK}Lưu
|
||||||
STR_FACE_SAVE_TOOLTIP :{BLACK}Lưu gương mặt yêu thích
|
STR_FACE_SAVE_TOOLTIP :{BLACK}Lưu gương mặt yêu thích
|
||||||
STR_FACE_SAVE_DONE :{WHITE}Gương mặt yêu thích này sẽ được lưu lại trong tập tin cấu hình OpenTTD .
|
STR_FACE_SAVE_DONE :{WHITE}Gương mặt yêu thích này sẽ được lưu lại trong tập tin cấu hình OpenTTD .
|
||||||
|
STR_FACE_SETTING_TOGGLE :{STRING} {ORANGE}{STRING}
|
||||||
|
STR_FACE_SETTING_NUMERIC :{STRING} {ORANGE}{NUM} / {NUM}
|
||||||
STR_FACE_YES :Đồng ý
|
STR_FACE_YES :Đồng ý
|
||||||
STR_FACE_NO :Không
|
STR_FACE_NO :Không
|
||||||
|
STR_FACE_STYLE :Kiểu:
|
||||||
STR_FACE_HAIR :Tóc:
|
STR_FACE_HAIR :Tóc:
|
||||||
STR_FACE_EYEBROWS :Lông mày:
|
STR_FACE_EYEBROWS :Lông mày:
|
||||||
STR_FACE_EYECOLOUR :Màu mắt:
|
STR_FACE_EYECOLOUR :Màu mắt:
|
||||||
|
@ -2607,7 +2638,7 @@ STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} r
|
||||||
STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} đã đổi tên thành {STRING}
|
STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} đã đổi tên thành {STRING}
|
||||||
STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} tặng {CURRENCY_LONG} cho {STRING}
|
STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} tặng {CURRENCY_LONG} cho {STRING}
|
||||||
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Server kết thúc phiên
|
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Server kết thúc phiên
|
||||||
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Server khởi động lại...{}Xin chờ...
|
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Server khởi động lại...{}{}Xin chờ...
|
||||||
STR_NETWORK_MESSAGE_KICKED :*** {STRING} đã bị đá khỏi ván chơi. Lý do: ({STRING})
|
STR_NETWORK_MESSAGE_KICKED :*** {STRING} đã bị đá khỏi ván chơi. Lý do: ({STRING})
|
||||||
|
|
||||||
STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED :{WHITE}Đăng ký server thất bại
|
STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED :{WHITE}Đăng ký server thất bại
|
||||||
|
@ -2793,6 +2824,10 @@ STR_PICKER_MODE_USED_TOOLTIP :Bật/tắt hi
|
||||||
STR_PICKER_MODE_SAVED :Đã lưu
|
STR_PICKER_MODE_SAVED :Đã lưu
|
||||||
STR_PICKER_MODE_SAVED_TOOLTIP :Bật/tắt hiển thị những hạng mục được lưu
|
STR_PICKER_MODE_SAVED_TOOLTIP :Bật/tắt hiển thị những hạng mục được lưu
|
||||||
|
|
||||||
|
STR_PICKER_PREVIEW_SHRINK :-
|
||||||
|
STR_PICKER_PREVIEW_SHRINK_TOOLTIP :Giảm chiều cao của ảnh xem trước. Ctrl+Click để giảm đến mức tối thiểu
|
||||||
|
STR_PICKER_PREVIEW_EXPAND :+
|
||||||
|
STR_PICKER_PREVIEW_EXPAND_TOOLTIP :Tăng chiều cao của ảnh xem trước. Ctrl+Click để tăng đến mức tối đa
|
||||||
|
|
||||||
STR_PICKER_STATION_CLASS_TOOLTIP :Chọn loại ga bến cần hiển thị
|
STR_PICKER_STATION_CLASS_TOOLTIP :Chọn loại ga bến cần hiển thị
|
||||||
STR_PICKER_STATION_TYPE_TOOLTIP :Chọn loại ga bến để xây. Ctrl+Click để thêm hoặc bớt vào danh sách lưu
|
STR_PICKER_STATION_TYPE_TOOLTIP :Chọn loại ga bến để xây. Ctrl+Click để thêm hoặc bớt vào danh sách lưu
|
||||||
|
@ -2816,6 +2851,7 @@ STR_HOUSE_PICKER_YEARS_FROM :{BLACK}Năm: {O
|
||||||
STR_HOUSE_PICKER_YEARS_UNTIL :{BLACK}Năm: {ORANGE}Đến {NUM}
|
STR_HOUSE_PICKER_YEARS_UNTIL :{BLACK}Năm: {ORANGE}Đến {NUM}
|
||||||
STR_HOUSE_PICKER_SIZE :{BLACK}Kích thước: {ORANGE}{NUM}x{NUM} ô
|
STR_HOUSE_PICKER_SIZE :{BLACK}Kích thước: {ORANGE}{NUM}x{NUM} ô
|
||||||
STR_HOUSE_PICKER_CARGO_ACCEPTED :{BLACK}Hàng hóa được chấp nhận: {ORANGE}
|
STR_HOUSE_PICKER_CARGO_ACCEPTED :{BLACK}Hàng hóa được chấp nhận: {ORANGE}
|
||||||
|
STR_HOUSE_PICKER_CARGO_PRODUCED :{BLACK}Hàng hóa cung cấp: {ORANGE}{CARGO_LIST}
|
||||||
|
|
||||||
STR_HOUSE_PICKER_CLASS_ZONE1 :Ngoài rìa
|
STR_HOUSE_PICKER_CLASS_ZONE1 :Ngoài rìa
|
||||||
STR_HOUSE_PICKER_CLASS_ZONE2 :Ngoại ô
|
STR_HOUSE_PICKER_CLASS_ZONE2 :Ngoại ô
|
||||||
|
@ -2824,6 +2860,7 @@ STR_HOUSE_PICKER_CLASS_ZONE4 :Phía trong ngo
|
||||||
STR_HOUSE_PICKER_CLASS_ZONE5 :Nội thành
|
STR_HOUSE_PICKER_CLASS_ZONE5 :Nội thành
|
||||||
|
|
||||||
STR_HOUSE_PICKER_PROTECT_TITLE :Ngăn chặn nâng cấp
|
STR_HOUSE_PICKER_PROTECT_TITLE :Ngăn chặn nâng cấp
|
||||||
|
STR_HOUSE_PICKER_PROTECT_TOOLTIP :Chọn nếu ngôi nhà này có được bảo vệ khỏi việc bị thay thế hay không khi thị trấn phát triển
|
||||||
STR_HOUSE_PICKER_PROTECT_OFF :Tắt
|
STR_HOUSE_PICKER_PROTECT_OFF :Tắt
|
||||||
STR_HOUSE_PICKER_PROTECT_ON :Bật
|
STR_HOUSE_PICKER_PROTECT_ON :Bật
|
||||||
|
|
||||||
|
@ -3031,6 +3068,11 @@ STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP :{BLACK}Chọn q
|
||||||
STR_FOUND_TOWN_CITY :{BLACK}Đô thị
|
STR_FOUND_TOWN_CITY :{BLACK}Đô thị
|
||||||
STR_FOUND_TOWN_CITY_TOOLTIP :{BLACK}Thành phố phát triển nhanh hơn thị trấn{}Tuỳ thuộc thiết lập, chúng lớn hơn khi khai sinh
|
STR_FOUND_TOWN_CITY_TOOLTIP :{BLACK}Thành phố phát triển nhanh hơn thị trấn{}Tuỳ thuộc thiết lập, chúng lớn hơn khi khai sinh
|
||||||
|
|
||||||
|
STR_FOUND_TOWN_EXPAND_MODE :{YELLOW}Mở rộng thị trấn:
|
||||||
|
STR_FOUND_TOWN_EXPAND_BUILDINGS :Công trình
|
||||||
|
STR_FOUND_TOWN_EXPAND_BUILDINGS_TOOLTIP :Tăng số công trình của thị trấn
|
||||||
|
STR_FOUND_TOWN_EXPAND_ROADS :Đường sá
|
||||||
|
STR_FOUND_TOWN_EXPAND_ROADS_TOOLTIP :Tăng số đường sá của thị trấn
|
||||||
|
|
||||||
STR_FOUND_TOWN_ROAD_LAYOUT :{YELLOW}Quy hoạch đường đô thị:
|
STR_FOUND_TOWN_ROAD_LAYOUT :{YELLOW}Quy hoạch đường đô thị:
|
||||||
STR_FOUND_TOWN_SELECT_LAYOUT_TOOLTIP :{BLACK}Chọn để quy hoạch đường bộ trong đô thị
|
STR_FOUND_TOWN_SELECT_LAYOUT_TOOLTIP :{BLACK}Chọn để quy hoạch đường bộ trong đô thị
|
||||||
|
@ -3103,6 +3145,8 @@ STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}Kiểu x
|
||||||
STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Giới hạn tốc độ đường ray: {LTBLUE}{VELOCITY}
|
STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Giới hạn tốc độ đường ray: {LTBLUE}{VELOCITY}
|
||||||
STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Hạn chế tốc độ đường bộ: {LTBLUE}{VELOCITY}
|
STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Hạn chế tốc độ đường bộ: {LTBLUE}{VELOCITY}
|
||||||
STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}Tốc độ xe điện giới hạn: {LTBLUE}{VELOCITY}
|
STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}Tốc độ xe điện giới hạn: {LTBLUE}{VELOCITY}
|
||||||
|
STR_LAND_AREA_INFORMATION_TOWN_CAN_UPGRADE :{BLACK}Nâng cấp thị trấn: {LTBLUE}Có thể
|
||||||
|
STR_LAND_AREA_INFORMATION_TOWN_CANNOT_UPGRADE :{BLACK}Nâng cấp thị trấn: {LTBLUE}Không thể
|
||||||
|
|
||||||
# Description of land area of different tiles
|
# Description of land area of different tiles
|
||||||
STR_LAI_CLEAR_DESCRIPTION_ROCKS :Đá
|
STR_LAI_CLEAR_DESCRIPTION_ROCKS :Đá
|
||||||
|
@ -3111,6 +3155,9 @@ STR_LAI_CLEAR_DESCRIPTION_BARE_LAND :Đất trống
|
||||||
STR_LAI_CLEAR_DESCRIPTION_GRASS :Bãi cỏ
|
STR_LAI_CLEAR_DESCRIPTION_GRASS :Bãi cỏ
|
||||||
STR_LAI_CLEAR_DESCRIPTION_FIELDS :Cánh đồng
|
STR_LAI_CLEAR_DESCRIPTION_FIELDS :Cánh đồng
|
||||||
STR_LAI_CLEAR_DESCRIPTION_DESERT :Hoang mạc
|
STR_LAI_CLEAR_DESCRIPTION_DESERT :Hoang mạc
|
||||||
|
STR_LAI_CLEAR_DESCRIPTION_SNOWY_ROCKS :Đá có tuyết phủ
|
||||||
|
STR_LAI_CLEAR_DESCRIPTION_SNOWY_ROUGH_LAND :Đất gồ ghề có tuyết phủ
|
||||||
|
STR_LAI_CLEAR_DESCRIPTION_SNOWY_GRASS :Cỏ có tuyết phủ
|
||||||
|
|
||||||
STR_LAI_RAIL_DESCRIPTION_TRACK :Đường ray
|
STR_LAI_RAIL_DESCRIPTION_TRACK :Đường ray
|
||||||
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_SIGNALS :Đường ray với đèn hiệu khóa
|
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_SIGNALS :Đường ray với đèn hiệu khóa
|
||||||
|
@ -3579,17 +3626,17 @@ STR_NEWGRF_LIST_COMPATIBLE :{YELLOW}Đã t
|
||||||
STR_NEWGRF_LIST_MISSING :{RED}Thiếu files
|
STR_NEWGRF_LIST_MISSING :{RED}Thiếu files
|
||||||
|
|
||||||
# NewGRF 'it's broken' warnings
|
# NewGRF 'it's broken' warnings
|
||||||
STR_NEWGRF_BROKEN :{WHITE}Hoạt động của NewGRF '{0:STRING}' có thể gây mất đồng bộ hoặc bị treo.
|
STR_NEWGRF_BROKEN :{WHITE}Hoạt động của NewGRF '{PUSH_COLOUR}{0:STRING}{POP_COLOUR}' có thể gây mất đồng bộ hoặc bị treo.
|
||||||
STR_NEWGRF_BROKEN_POWERED_WAGON :{WHITE}Trạng thái đầu kéo '{1:ENGINE}' được thay đổi khi không ở trong xưởng sửa chữa.
|
STR_NEWGRF_BROKEN_POWERED_WAGON :{WHITE}Trạng thái đầu kéo '{PUSH_COLOUR}{1:ENGINE}{POP_COLOUR}' được thay đổi khi không ở trong xưởng sửa chữa.
|
||||||
STR_NEWGRF_BROKEN_VEHICLE_LENGTH :{WHITE}Nó cắt ngắn độ dài của đoàn tàu '{1:ENGINE}' nếu không ở trong xưởng.
|
STR_NEWGRF_BROKEN_VEHICLE_LENGTH :{WHITE}Nó cắt ngắn độ dài của đoàn tàu '{PUSH_COLOUR}{1:ENGINE}{POP_COLOUR}' nếu không ở trong xưởng.
|
||||||
STR_NEWGRF_BROKEN_CAPACITY :{WHITE}Sức chứa của phương tiện bị thay đổi '{1:ENGINE}' khi không ở trong xưởng hoặc vì cải biến
|
STR_NEWGRF_BROKEN_CAPACITY :{WHITE}Sức chứa của phương tiện bị thay đổi '{PUSH_COLOUR}{1:ENGINE}{POP_COLOUR}' khi không ở trong xưởng hoặc vì cải biến
|
||||||
STR_BROKEN_VEHICLE_LENGTH :{WHITE}Đoàn tàu '{VEHICLE}' của '{COMPANY}' có độ dài không hợp lệ. Sự cố có thể có căn nguyên từ NewGRFs. Ván chơi có thể mất đồng bộ hoặc bị treo
|
STR_BROKEN_VEHICLE_LENGTH :{WHITE}Đoàn tàu '{VEHICLE}' của '{COMPANY}' có độ dài không hợp lệ. Sự cố có thể có căn nguyên từ NewGRFs. Ván chơi có thể mất đồng bộ hoặc bị treo
|
||||||
|
|
||||||
STR_NEWGRF_BUGGY :{WHITE}NewGRF '{0:STRING}' không hợp lệ.
|
STR_NEWGRF_BUGGY :{WHITE}NewGRF '{PUSH_COLOUR}{0:STRING}{POP_COLOUR}' không hợp lệ.
|
||||||
STR_NEWGRF_BUGGY_ARTICULATED_CARGO :{WHITE}Danh mục hàng hoá/cải biến được cho '{1:ENGINE}' khác với danh mục mua được sau khi đã có. Việc này khiến cho việc tự thay thế hay là tự cải biến không chính xác.
|
STR_NEWGRF_BUGGY_ARTICULATED_CARGO :{WHITE}Danh mục hàng hoá/cải biến được cho '{PUSH_COLOUR}{1:ENGINE}{POP_COLOUR}' khác với danh mục mua được sau khi đã có. Việc này khiến cho việc tự thay thế hay là tự cải biến không chính xác.
|
||||||
STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' gây ra một vòng lặp vô tận khi gọi hàm callback.
|
STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK :{WHITE}'{PUSH_COLOUR}{1:STRING}{POP_COLOUR}' gây ra một vòng lặp vô tận khi gọi hàm callback.
|
||||||
STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT :{WHITE}Hàm callback {1:HEX} gửi trả kết quả sai/không rõ {2:HEX}
|
STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT :{WHITE}Hàm callback {1:HEX} gửi trả kết quả sai/không rõ {2:HEX}
|
||||||
STR_NEWGRF_BUGGY_INVALID_CARGO_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' trả về loại hàng hoá sản xuất không hợp lệ khi gọi lại tại {2:HEX}
|
STR_NEWGRF_BUGGY_INVALID_CARGO_PRODUCTION_CALLBACK :{WHITE}'{PUSH_COLOUR}{1:STRING}{POP_COLOUR}' trả về loại hàng hoá sản xuất không hợp lệ khi gọi lại tại {2:HEX}
|
||||||
|
|
||||||
# 'User removed essential NewGRFs'-placeholders for stuff without specs
|
# 'User removed essential NewGRFs'-placeholders for stuff without specs
|
||||||
STR_NEWGRF_INVALID_CARGO :<sai kiểu hàng>
|
STR_NEWGRF_INVALID_CARGO :<sai kiểu hàng>
|
||||||
|
@ -3650,6 +3697,10 @@ STR_TOWN_VIEW_RENAME_TOOLTIP :{BLACK}Đổi t
|
||||||
|
|
||||||
STR_TOWN_VIEW_EXPAND_BUTTON :{BLACK}Mở rộng
|
STR_TOWN_VIEW_EXPAND_BUTTON :{BLACK}Mở rộng
|
||||||
STR_TOWN_VIEW_EXPAND_TOOLTIP :{BLACK}Tăng quy mô đô thị
|
STR_TOWN_VIEW_EXPAND_TOOLTIP :{BLACK}Tăng quy mô đô thị
|
||||||
|
STR_TOWN_VIEW_EXPAND_BUILDINGS_BUTTON :{BLACK}Mở rộng công trình
|
||||||
|
STR_TOWN_VIEW_EXPAND_BUILDINGS_TOOLTIP :{BLACK}Tăng số công trình của thị trấn
|
||||||
|
STR_TOWN_VIEW_EXPAND_ROADS_BUTTON :{BLACK}Mở rộng đường
|
||||||
|
STR_TOWN_VIEW_EXPAND_ROADS_TOOLTIP :{BLACK}Tăng số đường sá của thị trấn
|
||||||
STR_TOWN_VIEW_DELETE_BUTTON :{BLACK}Xoá
|
STR_TOWN_VIEW_DELETE_BUTTON :{BLACK}Xoá
|
||||||
STR_TOWN_VIEW_DELETE_TOOLTIP :{BLACK}Xoá bỏ đô thị này hoàn toàn
|
STR_TOWN_VIEW_DELETE_TOOLTIP :{BLACK}Xoá bỏ đô thị này hoàn toàn
|
||||||
|
|
||||||
|
@ -3975,6 +4026,8 @@ STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE :{BLACK}Sản l
|
||||||
STR_INDUSTRY_VIEW_PRODUCTION_LAST_MINUTE_TITLE :{BLACK}Sản lượng phút trước:
|
STR_INDUSTRY_VIEW_PRODUCTION_LAST_MINUTE_TITLE :{BLACK}Sản lượng phút trước:
|
||||||
STR_INDUSTRY_VIEW_TRANSPORTED :{YELLOW}{CARGO_LONG}{STRING}{BLACK} ({COMMA}% đã vận chuyển)
|
STR_INDUSTRY_VIEW_TRANSPORTED :{YELLOW}{CARGO_LONG}{STRING}{BLACK} ({COMMA}% đã vận chuyển)
|
||||||
STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Xem vị trí trung tâm của nhà máy. Ctrl+Click mở cửa sổ mới để xem
|
STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Xem vị trí trung tâm của nhà máy. Ctrl+Click mở cửa sổ mới để xem
|
||||||
|
STR_INDUSTRY_VIEW_CARGO_GRAPH :{BLACK}Đồ thị hàng hóa
|
||||||
|
STR_INDUSTRY_VIEW_CARGO_GRAPH_TOOLTIP :{BLACK}Xem đồ thị lịch sử kinh doanh hàng hóa
|
||||||
STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Mức sản lượng: {YELLOW}{COMMA}%
|
STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Mức sản lượng: {YELLOW}{COMMA}%
|
||||||
STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}Nhà máy này đã thông báo sắp đóng cửa!
|
STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}Nhà máy này đã thông báo sắp đóng cửa!
|
||||||
|
|
||||||
|
@ -4386,10 +4439,10 @@ STR_VEHICLE_VIEW_SHIP_ORDERS_TOOLTIP :{BLACK}Hiện l
|
||||||
STR_VEHICLE_VIEW_AIRCRAFT_ORDERS_TOOLTIP :{BLACK}Hiện lộ trình máy bay. Ctrl+Click để hiện lịch trình
|
STR_VEHICLE_VIEW_AIRCRAFT_ORDERS_TOOLTIP :{BLACK}Hiện lộ trình máy bay. Ctrl+Click để hiện lịch trình
|
||||||
|
|
||||||
###length VEHICLE_TYPES
|
###length VEHICLE_TYPES
|
||||||
STR_VEHICLE_VIEW_TRAIN_SHOW_DETAILS_TOOLTIP :{BLACK}Hiện chi tiết tàu hoả
|
STR_VEHICLE_VIEW_TRAIN_SHOW_DETAILS_TOOLTIP :{BLACK}Hiện chi tiết tàu hoả. Ctrl+Click vào để hiện nhóm của tàu hỏa
|
||||||
STR_VEHICLE_VIEW_ROAD_VEHICLE_SHOW_DETAILS_TOOLTIP :{BLACK}Hiện chi tiết xe
|
STR_VEHICLE_VIEW_ROAD_VEHICLE_SHOW_DETAILS_TOOLTIP :{BLACK}Hiện chi tiết xe. Ctrl+Click để hiện nhóm phương tiện
|
||||||
STR_VEHICLE_VIEW_SHIP_SHOW_DETAILS_TOOLTIP :{BLACK}Hiện chi tiết tàu thuỷ
|
STR_VEHICLE_VIEW_SHIP_SHOW_DETAILS_TOOLTIP :{BLACK}Hiện chi tiết tàu thuỷ. Ctrl+Click vào để hiện nhóm của tàu thủy
|
||||||
STR_VEHICLE_VIEW_AIRCRAFT_SHOW_DETAILS_TOOLTIP :{BLACK}Hiện chi tiết máy bay
|
STR_VEHICLE_VIEW_AIRCRAFT_SHOW_DETAILS_TOOLTIP :{BLACK}Hiện chi tiết máy bay. Ctrl+Click để hiện nhóm của máy bay
|
||||||
|
|
||||||
###length VEHICLE_TYPES
|
###length VEHICLE_TYPES
|
||||||
STR_VEHICLE_VIEW_TRAIN_STATUS_START_STOP_TOOLTIP :{BLACK}Tác động đến tàu hỏa hiện tại - bấm để dừng/chạy tàu hỏa
|
STR_VEHICLE_VIEW_TRAIN_STATUS_START_STOP_TOOLTIP :{BLACK}Tác động đến tàu hỏa hiện tại - bấm để dừng/chạy tàu hỏa
|
||||||
|
@ -4644,55 +4697,56 @@ STR_ORDER_ROAD_VEHICLE_DEPOT :Xưởng xe
|
||||||
STR_ORDER_SHIP_DEPOT :Xưởng tàu thuỷ
|
STR_ORDER_SHIP_DEPOT :Xưởng tàu thuỷ
|
||||||
###next-name-looks-similar
|
###next-name-looks-similar
|
||||||
|
|
||||||
|
STR_ORDER_GO_TO_NEAREST_HANGAR_FORMAT :{STRING} xưởng sân bay gần nhất
|
||||||
STR_ORDER_GO_TO_NEAREST_DEPOT_FORMAT :{STRING} gần {STRING} nhất
|
STR_ORDER_GO_TO_NEAREST_DEPOT_FORMAT :{STRING} gần {STRING} nhất
|
||||||
STR_ORDER_GO_TO_DEPOT_FORMAT :{STRING} {DEPOT}
|
STR_ORDER_GO_TO_DEPOT_FORMAT :{STRING} {DEPOT}
|
||||||
|
|
||||||
STR_ORDER_REFIT_ORDER :(Cải biến thành {STRING})
|
STR_ORDER_REFIT_ORDER :{SPACE}(Cải biến thành {STRING})
|
||||||
STR_ORDER_REFIT_STOP_ORDER :(Cải biến thành {STRING} và dừng)
|
STR_ORDER_REFIT_STOP_ORDER :{SPACE}(Cải biến thành {STRING} và dừng)
|
||||||
STR_ORDER_STOP_ORDER :(Dừng)
|
STR_ORDER_STOP_ORDER :{SPACE}(Dừng)
|
||||||
|
|
||||||
STR_ORDER_WAIT_TO_UNBUNCH :(Chờ để gỡ gộp)
|
STR_ORDER_WAIT_TO_UNBUNCH :{SPACE}(Chờ để gỡ gộp)
|
||||||
|
|
||||||
STR_ORDER_GO_TO_STATION :{STRING} {STATION}
|
STR_ORDER_GO_TO_STATION :{STRING} {STATION}
|
||||||
STR_ORDER_GO_TO_STATION_CAN_T_USE_STATION :{PUSH_COLOUR}{RED}(Không thể sử dụng trạm){POP_COLOUR} {STRING} {STATION}
|
STR_ORDER_GO_TO_STATION_CAN_T_USE_STATION :{PUSH_COLOUR}{RED}(Không thể sử dụng trạm){POP_COLOUR} {STRING} {STATION}
|
||||||
|
|
||||||
STR_ORDER_IMPLICIT :(Chạy ngầm)
|
STR_ORDER_IMPLICIT :{SPACE}(Chạy ngầm)
|
||||||
|
|
||||||
STR_ORDER_FULL_LOAD :(Bốc đầy hàng)
|
STR_ORDER_FULL_LOAD :{SPACE}(Bốc đầy hàng)
|
||||||
STR_ORDER_FULL_LOAD_ANY :(Bốc đủ bất kỳ hàng nào)
|
STR_ORDER_FULL_LOAD_ANY :{SPACE}(Bốc đủ bất kỳ hàng nào)
|
||||||
STR_ORDER_NO_LOAD :(Không bốc xếp)
|
STR_ORDER_NO_LOAD :{SPACE}(Không bốc xếp)
|
||||||
STR_ORDER_UNLOAD :(Dỡ và lấy hàng khác)
|
STR_ORDER_UNLOAD :{SPACE}(Dỡ và lấy hàng khác)
|
||||||
STR_ORDER_UNLOAD_FULL_LOAD :(Dỡ tất hàng và chờ bốc đầy hàng)
|
STR_ORDER_UNLOAD_FULL_LOAD :{SPACE}(Dỡ tất hàng và chờ bốc đầy hàng)
|
||||||
STR_ORDER_UNLOAD_FULL_LOAD_ANY :(Dỡ tất hàng và chờ bốc đủ bất kỳ hàng nào)
|
STR_ORDER_UNLOAD_FULL_LOAD_ANY :{SPACE}(Dỡ tất hàng và chờ bốc đủ bất kỳ hàng nào)
|
||||||
STR_ORDER_UNLOAD_NO_LOAD :(Dỡ tất hàng và để trống)
|
STR_ORDER_UNLOAD_NO_LOAD :{SPACE}(Dỡ tất hàng và để trống)
|
||||||
STR_ORDER_TRANSFER :(Trung chuyển hàng và lấy hàng khác)
|
STR_ORDER_TRANSFER :{SPACE}(Trung chuyển hàng và lấy hàng khác)
|
||||||
STR_ORDER_TRANSFER_FULL_LOAD :(Trung chuyển và chờ bốc đầy hàng)
|
STR_ORDER_TRANSFER_FULL_LOAD :{SPACE}(Trung chuyển và chờ bốc đầy hàng)
|
||||||
STR_ORDER_TRANSFER_FULL_LOAD_ANY :(Trung chuyển và chờ bốc đủ hàng bất kỳ)
|
STR_ORDER_TRANSFER_FULL_LOAD_ANY :{SPACE}(Trung chuyển và chờ bốc đủ hàng bất kỳ)
|
||||||
STR_ORDER_TRANSFER_NO_LOAD :(Trung chuyển và để trống)
|
STR_ORDER_TRANSFER_NO_LOAD :{SPACE}(Trung chuyển và để trống)
|
||||||
STR_ORDER_NO_UNLOAD :(Không dỡ và lấy hàng)
|
STR_ORDER_NO_UNLOAD :{SPACE}(Không dỡ và lấy hàng)
|
||||||
STR_ORDER_NO_UNLOAD_FULL_LOAD :(Không dỡ và chờ lấy thêm đầy hàng)
|
STR_ORDER_NO_UNLOAD_FULL_LOAD :{SPACE}(Không dỡ và chờ lấy thêm đầy hàng)
|
||||||
STR_ORDER_NO_UNLOAD_FULL_LOAD_ANY :(Không dỡ và chờ lấy đủ hàng bất kỳ)
|
STR_ORDER_NO_UNLOAD_FULL_LOAD_ANY :{SPACE}(Không dỡ và chờ lấy đủ hàng bất kỳ)
|
||||||
STR_ORDER_NO_UNLOAD_NO_LOAD :(Không bốc hàng và không dỡ hàng)
|
STR_ORDER_NO_UNLOAD_NO_LOAD :{SPACE}(Không bốc hàng và không dỡ hàng)
|
||||||
|
|
||||||
STR_ORDER_AUTO_REFIT :(Tự cải biến thành {STRING})
|
STR_ORDER_AUTO_REFIT :{SPACE}(Tự cải biến thành {STRING})
|
||||||
STR_ORDER_FULL_LOAD_REFIT :(Tự cải biến và chất đầy {STRING})
|
STR_ORDER_FULL_LOAD_REFIT :{SPACE}(Tự cải biến và chất đầy {STRING})
|
||||||
STR_ORDER_FULL_LOAD_ANY_REFIT :(Tự cải biến và chất đầy bất kỳ {STRING})
|
STR_ORDER_FULL_LOAD_ANY_REFIT :{SPACE}(Tự cải biến và chất đầy bất kỳ {STRING})
|
||||||
STR_ORDER_UNLOAD_REFIT :(Dỡ hàng và tự cải biến để lấy {STRING})
|
STR_ORDER_UNLOAD_REFIT :{SPACE}(Dỡ hàng và tự cải biến để lấy {STRING})
|
||||||
STR_ORDER_UNLOAD_FULL_LOAD_REFIT :(Dỡ hàng và tự cải biến đề bốc đầy {STRING})
|
STR_ORDER_UNLOAD_FULL_LOAD_REFIT :{SPACE}(Dỡ hàng và tự cải biến đề bốc đầy {STRING})
|
||||||
STR_ORDER_UNLOAD_FULL_LOAD_ANY_REFIT :(Dỡ hàng và tự cải biến để bốc đầy bất kỳ {STRING})
|
STR_ORDER_UNLOAD_FULL_LOAD_ANY_REFIT :{SPACE}(Dỡ hàng và tự cải biến để bốc đầy bất kỳ {STRING})
|
||||||
STR_ORDER_TRANSFER_REFIT :(Trung chuyển và tự cải biến để lấy {STRING})
|
STR_ORDER_TRANSFER_REFIT :{SPACE}(Trung chuyển và tự cải biến để lấy {STRING})
|
||||||
STR_ORDER_TRANSFER_FULL_LOAD_REFIT :(Trung chuyển và tự cải biến đề bốc đầy {STRING})
|
STR_ORDER_TRANSFER_FULL_LOAD_REFIT :{SPACE}(Trung chuyển và tự cải biến đề bốc đầy {STRING})
|
||||||
STR_ORDER_TRANSFER_FULL_LOAD_ANY_REFIT :(Trung chuyển và tự cải biến để bốc đầy bất kỳ {STRING})
|
STR_ORDER_TRANSFER_FULL_LOAD_ANY_REFIT :{SPACE}(Trung chuyển và tự cải biến để bốc đầy bất kỳ {STRING})
|
||||||
STR_ORDER_NO_UNLOAD_REFIT :(Không dỡ hàng và tự cái biến để lấy {STRING})
|
STR_ORDER_NO_UNLOAD_REFIT :{SPACE}(Không dỡ hàng và tự cái biến để lấy {STRING})
|
||||||
STR_ORDER_NO_UNLOAD_FULL_LOAD_REFIT :(Không dỡ hàng và tự cải biến để bốc đầy {STRING})
|
STR_ORDER_NO_UNLOAD_FULL_LOAD_REFIT :{SPACE}(Không dỡ hàng và tự cải biến để bốc đầy {STRING})
|
||||||
STR_ORDER_NO_UNLOAD_FULL_LOAD_ANY_REFIT :(Không dỡ hàng và tự cải biến để bốc đầy bất kỳ {STRING})
|
STR_ORDER_NO_UNLOAD_FULL_LOAD_ANY_REFIT :{SPACE}(Không dỡ hàng và tự cải biến để bốc đầy bất kỳ {STRING})
|
||||||
|
|
||||||
STR_ORDER_AUTO_REFIT_ANY :hàng hóa sẵn có
|
STR_ORDER_AUTO_REFIT_ANY :hàng hóa sẵn có
|
||||||
|
|
||||||
###length 3
|
###length 3
|
||||||
STR_ORDER_STOP_LOCATION_NEAR_END :[đỗ ở đầu gần]
|
STR_ORDER_STOP_LOCATION_NEAR_END :{SPACE}[đỗ ở đầu gần]
|
||||||
STR_ORDER_STOP_LOCATION_MIDDLE :[đỗ ở giữa]
|
STR_ORDER_STOP_LOCATION_MIDDLE :{SPACE}[đỗ ở giữa]
|
||||||
STR_ORDER_STOP_LOCATION_FAR_END :[đỗ ở đầu xa]
|
STR_ORDER_STOP_LOCATION_FAR_END :{SPACE}[đỗ ở đầu xa]
|
||||||
|
|
||||||
STR_ORDER_OUT_OF_RANGE :{RED} (Điểm đến kế tiếp ngoài tầm xa)
|
STR_ORDER_OUT_OF_RANGE :{RED} (Điểm đến kế tiếp ngoài tầm xa)
|
||||||
|
|
||||||
|
@ -4712,14 +4766,15 @@ STR_TIMETABLE_TOOLTIP :{BLACK}Lịch t
|
||||||
STR_TIMETABLE_NO_TRAVEL :Không di chuyển
|
STR_TIMETABLE_NO_TRAVEL :Không di chuyển
|
||||||
STR_TIMETABLE_NOT_TIMETABLEABLE :Hành trình (tự động; tính thời gian theo lịch trình thủ công kế tiếp)
|
STR_TIMETABLE_NOT_TIMETABLEABLE :Hành trình (tự động; tính thời gian theo lịch trình thủ công kế tiếp)
|
||||||
STR_TIMETABLE_TRAVEL_NOT_TIMETABLED :Di chuyển (không bó buộc theo lịch trình)
|
STR_TIMETABLE_TRAVEL_NOT_TIMETABLED :Di chuyển (không bó buộc theo lịch trình)
|
||||||
|
STR_TIMETABLE_TRAVEL_NOT_TIMETABLED_SPEED :Hành trình với tốc độ tối đa là {VELOCITY} (chưa dựng lịch trình)
|
||||||
STR_TIMETABLE_TRAVEL_FOR :Di chuyển trong {STRING}
|
STR_TIMETABLE_TRAVEL_FOR :Di chuyển trong {STRING}
|
||||||
STR_TIMETABLE_TRAVEL_FOR_SPEED :Lộ trình {STRING} với tốc độ tối đa {VELOCITY}
|
STR_TIMETABLE_TRAVEL_FOR_SPEED :Lộ trình {STRING} với tốc độ tối đa {VELOCITY}
|
||||||
STR_TIMETABLE_TRAVEL_FOR_ESTIMATED :Lộ trình (cho {STRING}, chưa có lịch trình)
|
STR_TIMETABLE_TRAVEL_FOR_ESTIMATED :Lộ trình (cho {STRING}, chưa có lịch trình)
|
||||||
STR_TIMETABLE_TRAVEL_FOR_SPEED_ESTIMATED :Lộ trình (cho {STRING}, chưa có lịch trình) với tốc độ đối đa {VELOCITY}
|
STR_TIMETABLE_TRAVEL_FOR_SPEED_ESTIMATED :Lộ trình (cho {STRING}, chưa có lịch trình) với tốc độ đối đa {VELOCITY}
|
||||||
STR_TIMETABLE_STAY_FOR_ESTIMATED :(ở lại {STRING}, chưa có lịch trình)
|
STR_TIMETABLE_STAY_FOR_ESTIMATED :{SPACE}(ở lại {STRING}, chưa có lịch trình)
|
||||||
STR_TIMETABLE_AND_TRAVEL_FOR_ESTIMATED :(di chuyển đến {STRING}, chưa có lịch trình)
|
STR_TIMETABLE_AND_TRAVEL_FOR_ESTIMATED :{SPACE}(di chuyển đến {STRING}, chưa có lịch trình)
|
||||||
STR_TIMETABLE_STAY_FOR :và ở lại trong {STRING}
|
STR_TIMETABLE_STAY_FOR :{SPACE}và ở lại trong {STRING}
|
||||||
STR_TIMETABLE_AND_TRAVEL_FOR :và di chuyển trong {STRING}
|
STR_TIMETABLE_AND_TRAVEL_FOR :{SPACE}và di chuyển trong {STRING}
|
||||||
|
|
||||||
STR_TIMETABLE_APPROX_TIME :{BLACK}Lịch trình này sẽ mất khoảng {STRING} để hoàn thành
|
STR_TIMETABLE_APPROX_TIME :{BLACK}Lịch trình này sẽ mất khoảng {STRING} để hoàn thành
|
||||||
STR_TIMETABLE_TOTAL_TIME :{BLACK}Lịch trình này sẽ mất {STRING} để hoàn thành
|
STR_TIMETABLE_TOTAL_TIME :{BLACK}Lịch trình này sẽ mất {STRING} để hoàn thành
|
||||||
|
@ -4738,12 +4793,14 @@ STR_TIMETABLE_START_SECONDS_QUERY :Số giây cho
|
||||||
|
|
||||||
STR_TIMETABLE_CHANGE_TIME :{BLACK}Đổi thời gian
|
STR_TIMETABLE_CHANGE_TIME :{BLACK}Đổi thời gian
|
||||||
STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Thay đổi thời lượng của điểm lộ trình được phép sử dụng. Ctrl+Click đặt thời gian cho mọi lộ trình
|
STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Thay đổi thời lượng của điểm lộ trình được phép sử dụng. Ctrl+Click đặt thời gian cho mọi lộ trình
|
||||||
|
STR_TIMETABLE_CHANGE_TIME_QUERY :Thay đổi thời gian
|
||||||
|
|
||||||
STR_TIMETABLE_CLEAR_TIME :{BLACK}Xoá thời gian
|
STR_TIMETABLE_CLEAR_TIME :{BLACK}Xoá thời gian
|
||||||
STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Xóa thời lượng áp dụng cho điểm lộ trình. Ctrl+Click xoá tất cả thời gian cho mọi lộ trình
|
STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Xóa thời lượng áp dụng cho điểm lộ trình. Ctrl+Click xoá tất cả thời gian cho mọi lộ trình
|
||||||
|
|
||||||
STR_TIMETABLE_CHANGE_SPEED :{BLACK}Thay Đổi Giới Hạn Tốc Độ
|
STR_TIMETABLE_CHANGE_SPEED :{BLACK}Thay Đổi Giới Hạn Tốc Độ
|
||||||
STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Thay đổi tốc độ tối đa của lộ trình được chọn. Ctrl+Click đặt tốc độ cho mọi lộ trình
|
STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Thay đổi tốc độ tối đa của lộ trình được chọn. Ctrl+Click đặt tốc độ cho mọi lộ trình
|
||||||
|
STR_TIMETABLE_CHANGE_SPEED_QUERY :Thay đổi giới hạn tốc độ
|
||||||
|
|
||||||
STR_TIMETABLE_CLEAR_SPEED :{BLACK}Xóa Giới Hạn Tốc Độ
|
STR_TIMETABLE_CLEAR_SPEED :{BLACK}Xóa Giới Hạn Tốc Độ
|
||||||
STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Xóa tốc độ đối đa đối với lộ trình được chọn. Ctrl+Click xoá tốc độ cho mọi lộ trình
|
STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Xóa tốc độ đối đa đối với lộ trình được chọn. Ctrl+Click xoá tốc độ cho mọi lộ trình
|
||||||
|
@ -4907,7 +4964,7 @@ STR_GAME_SAVELOAD_NOT_AVAILABLE :<không có s
|
||||||
STR_WARNING_LOADGAME_REMOVED_TRAMS :{WHITE}Lưu ván chơi sẽ không có xe điện. Những công trình cho xe điện sẽ bị xoá bỏ
|
STR_WARNING_LOADGAME_REMOVED_TRAMS :{WHITE}Lưu ván chơi sẽ không có xe điện. Những công trình cho xe điện sẽ bị xoá bỏ
|
||||||
|
|
||||||
# Map generation messages
|
# Map generation messages
|
||||||
STR_ERROR_COULD_NOT_CREATE_TOWN :{WHITE}Sinh bản đồ bị ngưng...{}... không có nơi đặt đô thị
|
STR_ERROR_COULD_NOT_CREATE_TOWN :{WHITE}Sinh bản đồ bị ngưng...{}{}... không có nơi đặt đô thị
|
||||||
STR_ERROR_NO_TOWN_IN_SCENARIO :{WHITE}... không có đô thị nào ở màn chơi kịch bản này
|
STR_ERROR_NO_TOWN_IN_SCENARIO :{WHITE}... không có đô thị nào ở màn chơi kịch bản này
|
||||||
|
|
||||||
STR_ERROR_PNGMAP :{WHITE}Không thể nạp nền từ file PNG...
|
STR_ERROR_PNGMAP :{WHITE}Không thể nạp nền từ file PNG...
|
||||||
|
@ -4946,6 +5003,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}Yêu c
|
||||||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Tạo dốc bị sai hướng
|
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Tạo dốc bị sai hướng
|
||||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}Không làm thế này được...
|
STR_ERROR_CAN_T_DO_THIS :{WHITE}Không làm thế này được...
|
||||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Cần giải toả nhà cửa trước
|
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Cần giải toả nhà cửa trước
|
||||||
|
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... công trình được bảo vệ
|
||||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Không thể dọn dẹp khu vực này...
|
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Không thể dọn dẹp khu vực này...
|
||||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... điểm không phù hợp
|
STR_ERROR_SITE_UNSUITABLE :{WHITE}... điểm không phù hợp
|
||||||
STR_ERROR_ALREADY_BUILT :{WHITE}... đã xây rồi
|
STR_ERROR_ALREADY_BUILT :{WHITE}... đã xây rồi
|
||||||
|
@ -4998,7 +5056,7 @@ STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... quá
|
||||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... quá nhiều đô thị
|
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... quá nhiều đô thị
|
||||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... không còn khoảng trống nào trên bản đồ
|
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... không còn khoảng trống nào trên bản đồ
|
||||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Xây dựng cầu đường đang tiến hành
|
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Xây dựng cầu đường đang tiến hành
|
||||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Không thể xoá đo thị này...{}Có một ga, bến hoặc xưởng thuộc đô thị hoặc là 1 ô đất của đô thị không thể xoá được.
|
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Không thể xoá đo thị này...{}{}Có một ga, bến hoặc xưởng thuộc đô thị hoặc là 1 ô đất của đô thị không thể xoá được.
|
||||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... không có nơi nào hợp lý để dựng tượng đài ở trung tâm đô thị này
|
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... không có nơi nào hợp lý để dựng tượng đài ở trung tâm đô thị này
|
||||||
STR_ERROR_CAN_T_BUILD_HOUSE :{WHITE}Không thể xây dựng nhà...
|
STR_ERROR_CAN_T_BUILD_HOUSE :{WHITE}Không thể xây dựng nhà...
|
||||||
|
|
||||||
|
@ -5825,6 +5883,7 @@ STR_CURRENCY_SHORT_GIGA :{NBSP}tỷ
|
||||||
STR_CURRENCY_SHORT_TERA :{NBSP}ktỷ
|
STR_CURRENCY_SHORT_TERA :{NBSP}ktỷ
|
||||||
|
|
||||||
STR_JUST_CARGO :{CARGO_LONG}
|
STR_JUST_CARGO :{CARGO_LONG}
|
||||||
|
STR_JUST_LEFT_ARROW :{LEFT_ARROW}
|
||||||
STR_JUST_RIGHT_ARROW :{RIGHT_ARROW}
|
STR_JUST_RIGHT_ARROW :{RIGHT_ARROW}
|
||||||
STR_JUST_CHECKMARK :{CHECKMARK}
|
STR_JUST_CHECKMARK :{CHECKMARK}
|
||||||
STR_JUST_COMMA :{COMMA}
|
STR_JUST_COMMA :{COMMA}
|
||||||
|
@ -5864,3 +5923,11 @@ STR_SHIP :{BLACK}{SHIP}
|
||||||
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
|
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
|
||||||
|
|
||||||
STR_BADGE_NAME_LIST :{STRING}: {GOLD}{STRING}
|
STR_BADGE_NAME_LIST :{STRING}: {GOLD}{STRING}
|
||||||
|
STR_BADGE_CONFIG_MENU_TOOLTIP :Mở thiết lập phù hiệu
|
||||||
|
STR_BADGE_CONFIG_RESET :Thiêt lập lại
|
||||||
|
STR_BADGE_CONFIG_ICONS :{WHITE}Ảnh phù hiệu
|
||||||
|
STR_BADGE_CONFIG_FILTERS :{WHITE}Bộ lọc phù hiệu
|
||||||
|
STR_BADGE_CONFIG_PREVIEW :Ảnh xem trước
|
||||||
|
STR_BADGE_CONFIG_NAME :Tên
|
||||||
|
STR_BADGE_FILTER_ANY_LABEL :Bất cứ {STRING} nào
|
||||||
|
STR_BADGE_FILTER_IS_LABEL :{STRING} là {STRING}
|
||||||
|
|
|
@ -681,6 +681,11 @@ SettingsContainer &GetSettingsTree()
|
||||||
* Since it's also able to completely disable the scrollwheel will we display it on all platforms anyway */
|
* Since it's also able to completely disable the scrollwheel will we display it on all platforms anyway */
|
||||||
viewports->Add(new SettingEntry("gui.scrollwheel_scrolling"));
|
viewports->Add(new SettingEntry("gui.scrollwheel_scrolling"));
|
||||||
viewports->Add(new SettingEntry("gui.scrollwheel_multiplier"));
|
viewports->Add(new SettingEntry("gui.scrollwheel_multiplier"));
|
||||||
|
viewports->Add(new SettingEntry("gui.gamepad_stick_selection"));
|
||||||
|
viewports->Add(new SettingEntry("gui.gamepad_deadzone"));
|
||||||
|
viewports->Add(new SettingEntry("gui.gamepad_sensitivity"));
|
||||||
|
viewports->Add(new SettingEntry("gui.gamepad_invert_x"));
|
||||||
|
viewports->Add(new SettingEntry("gui.gamepad_invert_y"));
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
/* We might need to emulate a right mouse button on mac */
|
/* We might need to emulate a right mouse button on mac */
|
||||||
viewports->Add(new SettingEntry("gui.right_mouse_btn_emulation"));
|
viewports->Add(new SettingEntry("gui.right_mouse_btn_emulation"));
|
||||||
|
|
|
@ -140,6 +140,13 @@ enum ScrollWheelScrollingSetting : uint8_t {
|
||||||
SWS_OFF = 2 ///< Scroll wheel has no effect.
|
SWS_OFF = 2 ///< Scroll wheel has no effect.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Settings related to gamepad stick selection. */
|
||||||
|
enum GamepadStickSelection : uint8_t {
|
||||||
|
GSS_DISABLED = 0, ///< Gamepad scrolling disabled.
|
||||||
|
GSS_LEFT_STICK = 1, ///< Use left analog stick for scrolling.
|
||||||
|
GSS_RIGHT_STICK = 2, ///< Use right analog stick for scrolling.
|
||||||
|
};
|
||||||
|
|
||||||
/** Settings related to the GUI and other stuff that is not saved in the savegame. */
|
/** Settings related to the GUI and other stuff that is not saved in the savegame. */
|
||||||
struct GUISettings {
|
struct GUISettings {
|
||||||
bool sg_full_load_any; ///< new full load calculation, any cargo must be full read from pre v93 savegames
|
bool sg_full_load_any; ///< new full load calculation, any cargo must be full read from pre v93 savegames
|
||||||
|
@ -183,6 +190,11 @@ struct GUISettings {
|
||||||
uint8_t right_mouse_btn_emulation; ///< should we emulate right mouse clicking?
|
uint8_t right_mouse_btn_emulation; ///< should we emulate right mouse clicking?
|
||||||
uint8_t scrollwheel_scrolling; ///< scrolling using the scroll wheel?
|
uint8_t scrollwheel_scrolling; ///< scrolling using the scroll wheel?
|
||||||
uint8_t scrollwheel_multiplier; ///< how much 'wheel' per incoming event from the OS?
|
uint8_t scrollwheel_multiplier; ///< how much 'wheel' per incoming event from the OS?
|
||||||
|
uint8_t gamepad_deadzone; ///< deadzone for gamepad analog sticks (0-100)
|
||||||
|
uint8_t gamepad_sensitivity; ///< sensitivity multiplier for gamepad scrolling
|
||||||
|
bool gamepad_invert_x; ///< invert X axis for gamepad scrolling?
|
||||||
|
bool gamepad_invert_y; ///< invert Y axis for gamepad scrolling?
|
||||||
|
uint8_t gamepad_stick_selection; ///< which stick to use for scrolling (left/right/disabled)
|
||||||
bool timetable_arrival_departure; ///< show arrivals and departures in vehicle timetables
|
bool timetable_arrival_departure; ///< show arrivals and departures in vehicle timetables
|
||||||
RightClickClose right_click_wnd_close; ///< close window with right click
|
RightClickClose right_click_wnd_close; ///< close window with right click
|
||||||
bool pause_on_newgame; ///< whether to start new games paused or not
|
bool pause_on_newgame; ///< whether to start new games paused or not
|
||||||
|
|
|
@ -912,3 +912,62 @@ post_cb = [](auto) { SetupWidgetDimensions(); ReInitAllWindows(true); }
|
||||||
cat = SC_BASIC
|
cat = SC_BASIC
|
||||||
startup = true
|
startup = true
|
||||||
|
|
||||||
|
[SDTC_VAR]
|
||||||
|
var = gui.gamepad_deadzone
|
||||||
|
type = SLE_UINT8
|
||||||
|
flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync
|
||||||
|
def = 10
|
||||||
|
min = 0
|
||||||
|
max = 100
|
||||||
|
interval = 5
|
||||||
|
str = STR_CONFIG_SETTING_GAMEPAD_DEADZONE
|
||||||
|
strhelp = STR_CONFIG_SETTING_GAMEPAD_DEADZONE_HELPTEXT
|
||||||
|
strval = STR_JUST_COMMA
|
||||||
|
cat = SC_BASIC
|
||||||
|
startup = true
|
||||||
|
|
||||||
|
[SDTC_VAR]
|
||||||
|
var = gui.gamepad_sensitivity
|
||||||
|
type = SLE_UINT8
|
||||||
|
flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync
|
||||||
|
def = 10
|
||||||
|
min = 1
|
||||||
|
max = 100
|
||||||
|
interval = 5
|
||||||
|
str = STR_CONFIG_SETTING_GAMEPAD_SENSITIVITY
|
||||||
|
strhelp = STR_CONFIG_SETTING_GAMEPAD_SENSITIVITY_HELPTEXT
|
||||||
|
strval = STR_JUST_COMMA
|
||||||
|
cat = SC_BASIC
|
||||||
|
startup = true
|
||||||
|
|
||||||
|
[SDTC_BOOL]
|
||||||
|
var = gui.gamepad_invert_x
|
||||||
|
flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync
|
||||||
|
def = false
|
||||||
|
str = STR_CONFIG_SETTING_GAMEPAD_INVERT_X
|
||||||
|
strhelp = STR_CONFIG_SETTING_GAMEPAD_INVERT_X_HELPTEXT
|
||||||
|
cat = SC_BASIC
|
||||||
|
startup = true
|
||||||
|
|
||||||
|
[SDTC_BOOL]
|
||||||
|
var = gui.gamepad_invert_y
|
||||||
|
flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync
|
||||||
|
def = false
|
||||||
|
str = STR_CONFIG_SETTING_GAMEPAD_INVERT_Y
|
||||||
|
strhelp = STR_CONFIG_SETTING_GAMEPAD_INVERT_Y_HELPTEXT
|
||||||
|
cat = SC_BASIC
|
||||||
|
startup = true
|
||||||
|
|
||||||
|
[SDTC_VAR]
|
||||||
|
var = gui.gamepad_stick_selection
|
||||||
|
type = SLE_UINT8
|
||||||
|
flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown
|
||||||
|
def = GSS_LEFT_STICK
|
||||||
|
min = GSS_DISABLED
|
||||||
|
max = GSS_RIGHT_STICK
|
||||||
|
str = STR_CONFIG_SETTING_GAMEPAD_STICK_SELECTION
|
||||||
|
strhelp = STR_CONFIG_SETTING_GAMEPAD_STICK_SELECTION_HELPTEXT
|
||||||
|
strval = STR_CONFIG_SETTING_GAMEPAD_STICK_DISABLED
|
||||||
|
cat = SC_BASIC
|
||||||
|
startup = true
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "../fileio_func.h"
|
#include "../fileio_func.h"
|
||||||
#include "../framerate_type.h"
|
#include "../framerate_type.h"
|
||||||
#include "../window_func.h"
|
#include "../window_func.h"
|
||||||
|
#include "../zoom_func.h"
|
||||||
#include "sdl2_v.h"
|
#include "sdl2_v.h"
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
|
@ -524,6 +525,27 @@ bool VideoDriver_SDL_Base::PollEvent()
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SDL_CONTROLLERDEVICEADDED: {
|
||||||
|
Debug(driver, 1, "SDL2: Gamepad device added, index: {}", ev.cdevice.which);
|
||||||
|
/* Try to open the newly connected gamepad */
|
||||||
|
if (this->gamepad == nullptr) {
|
||||||
|
this->OpenGamepad();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SDL_CONTROLLERDEVICEREMOVED: {
|
||||||
|
Debug(driver, 1, "SDL2: Gamepad device removed, instance ID: {}", ev.cdevice.which);
|
||||||
|
/* Close gamepad if it was removed */
|
||||||
|
if (this->gamepad != nullptr && ev.cdevice.which == SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(this->gamepad))) {
|
||||||
|
Debug(driver, 1, "SDL2: Current gamepad was removed, closing and reopening");
|
||||||
|
this->CloseGamepad();
|
||||||
|
/* Try to open another gamepad if available */
|
||||||
|
this->OpenGamepad();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -539,6 +561,12 @@ static std::optional<std::string_view> InitializeSDL()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) return SDL_GetError();
|
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) return SDL_GetError();
|
||||||
|
|
||||||
|
/* Initialize gamepad subsystem for gamepad scrolling support */
|
||||||
|
if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) < 0) {
|
||||||
|
Debug(driver, 1, "SDL2: Failed to initialize gamepad subsystem: {}", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,6 +618,11 @@ std::optional<std::string_view> VideoDriver_SDL_Base::Start(const StringList &pa
|
||||||
SDL_StopTextInput();
|
SDL_StopTextInput();
|
||||||
this->edit_box_focused = false;
|
this->edit_box_focused = false;
|
||||||
|
|
||||||
|
/* Initialize gamepad for scrolling */
|
||||||
|
Debug(driver, 1, "SDL2: Attempting to initialize gamepad support");
|
||||||
|
Debug(driver, 1, "SDL2: Gamepad stick selection setting: {}", _settings_client.gui.gamepad_stick_selection);
|
||||||
|
this->OpenGamepad();
|
||||||
|
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
this->is_game_threaded = false;
|
this->is_game_threaded = false;
|
||||||
#else
|
#else
|
||||||
|
@ -601,6 +634,8 @@ std::optional<std::string_view> VideoDriver_SDL_Base::Start(const StringList &pa
|
||||||
|
|
||||||
void VideoDriver_SDL_Base::Stop()
|
void VideoDriver_SDL_Base::Stop()
|
||||||
{
|
{
|
||||||
|
this->CloseGamepad();
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
|
||||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||||
if (SDL_WasInit(SDL_INIT_EVERYTHING) == 0) {
|
if (SDL_WasInit(SDL_INIT_EVERYTHING) == 0) {
|
||||||
SDL_Quit(); // If there's nothing left, quit SDL
|
SDL_Quit(); // If there's nothing left, quit SDL
|
||||||
|
@ -629,6 +664,9 @@ void VideoDriver_SDL_Base::InputLoop()
|
||||||
(keys[SDL_SCANCODE_DOWN] ? 8 : 0);
|
(keys[SDL_SCANCODE_DOWN] ? 8 : 0);
|
||||||
|
|
||||||
if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();
|
if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();
|
||||||
|
|
||||||
|
/* Process gamepad input for scrolling */
|
||||||
|
this->ProcessGamepadInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoDriver_SDL_Base::LoopOnce()
|
void VideoDriver_SDL_Base::LoopOnce()
|
||||||
|
@ -755,3 +793,84 @@ void VideoDriver_SDL_Base::UnlockVideoBuffer()
|
||||||
|
|
||||||
this->buffer_locked = false;
|
this->buffer_locked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VideoDriver_SDL_Base::OpenGamepad()
|
||||||
|
{
|
||||||
|
/* Don't open gamepad if already open or if gamepad scrolling is disabled */
|
||||||
|
if (this->gamepad != nullptr) {
|
||||||
|
Debug(driver, 1, "SDL2: Gamepad already open, skipping");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_settings_client.gui.gamepad_stick_selection == GSS_DISABLED) {
|
||||||
|
Debug(driver, 1, "SDL2: Gamepad scrolling disabled, not opening gamepad");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if any gamepads are available */
|
||||||
|
int num_gamepads = SDL_NumJoysticks();
|
||||||
|
Debug(driver, 1, "SDL2: Found {} joystick(s)", num_gamepads);
|
||||||
|
|
||||||
|
for (int i = 0; i < num_gamepads; i++) {
|
||||||
|
if (SDL_IsGameController(i)) {
|
||||||
|
Debug(driver, 1, "SDL2: Joystick {} is a gamepad, attempting to open", i);
|
||||||
|
this->gamepad = SDL_GameControllerOpen(i);
|
||||||
|
if (this->gamepad != nullptr) {
|
||||||
|
Debug(driver, 1, "SDL2: Opened gamepad: {}", SDL_GameControllerName(this->gamepad));
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
Debug(driver, 1, "SDL2: Failed to open gamepad {}: {}", i, SDL_GetError());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Debug(driver, 1, "SDL2: Joystick {} is not a gamepad", i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->gamepad == nullptr) {
|
||||||
|
Debug(driver, 1, "SDL2: No gamepad opened");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VideoDriver_SDL_Base::CloseGamepad()
|
||||||
|
{
|
||||||
|
if (this->gamepad != nullptr) {
|
||||||
|
SDL_GameControllerClose(this->gamepad);
|
||||||
|
this->gamepad = nullptr;
|
||||||
|
Debug(driver, 1, "SDL2: Closed gamepad");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VideoDriver_SDL_Base::ProcessGamepadInput()
|
||||||
|
{
|
||||||
|
/* Skip if gamepad is not available */
|
||||||
|
if (this->gamepad == nullptr) {
|
||||||
|
static bool logged_no_gamepad = false;
|
||||||
|
if (!logged_no_gamepad) {
|
||||||
|
Debug(driver, 2, "SDL2: No gamepad available for input processing");
|
||||||
|
logged_no_gamepad = true;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if gamepad is still connected */
|
||||||
|
if (!SDL_GameControllerGetAttached(this->gamepad)) {
|
||||||
|
Debug(driver, 1, "SDL2: Gamepad disconnected, closing and reopening");
|
||||||
|
this->CloseGamepad();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get analog stick values based on stick selection */
|
||||||
|
Sint16 stick_x = 0, stick_y = 0;
|
||||||
|
if (_settings_client.gui.gamepad_stick_selection == GSS_LEFT_STICK) {
|
||||||
|
stick_x = SDL_GameControllerGetAxis(this->gamepad, SDL_CONTROLLER_AXIS_LEFTX);
|
||||||
|
stick_y = SDL_GameControllerGetAxis(this->gamepad, SDL_CONTROLLER_AXIS_LEFTY);
|
||||||
|
Debug(driver, 3, "SDL2: Left stick raw values: x={}, y={}", stick_x, stick_y);
|
||||||
|
} else if (_settings_client.gui.gamepad_stick_selection == GSS_RIGHT_STICK) {
|
||||||
|
stick_x = SDL_GameControllerGetAxis(this->gamepad, SDL_CONTROLLER_AXIS_RIGHTX);
|
||||||
|
stick_y = SDL_GameControllerGetAxis(this->gamepad, SDL_CONTROLLER_AXIS_RIGHTY);
|
||||||
|
Debug(driver, 3, "SDL2: Right stick raw values: x={}, y={}", stick_x, stick_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use the common gamepad handling function */
|
||||||
|
HandleGamepadScrolling(stick_x, stick_y, 32767);
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,10 @@
|
||||||
|
|
||||||
#include "video_driver.hpp"
|
#include "video_driver.hpp"
|
||||||
|
|
||||||
|
/* Forward declaration of SDL_GameController */
|
||||||
|
struct _SDL_GameController;
|
||||||
|
typedef struct _SDL_GameController SDL_GameController;
|
||||||
|
|
||||||
/** The SDL video driver. */
|
/** The SDL video driver. */
|
||||||
class VideoDriver_SDL_Base : public VideoDriver {
|
class VideoDriver_SDL_Base : public VideoDriver {
|
||||||
public:
|
public:
|
||||||
|
@ -69,6 +73,13 @@ protected:
|
||||||
/** Create the main window. */
|
/** Create the main window. */
|
||||||
virtual bool CreateMainWindow(uint w, uint h, uint flags = 0);
|
virtual bool CreateMainWindow(uint w, uint h, uint flags = 0);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** Gamepad support for map scrolling */
|
||||||
|
SDL_GameController *gamepad = nullptr; ///< Currently opened gamepad.
|
||||||
|
void OpenGamepad();
|
||||||
|
void CloseGamepad();
|
||||||
|
void ProcessGamepadInput();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void LoopOnce();
|
void LoopOnce();
|
||||||
void MainLoopCleanup();
|
void MainLoopCleanup();
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <imm.h>
|
#include <imm.h>
|
||||||
#include <versionhelpers.h>
|
#include <versionhelpers.h>
|
||||||
|
#include <xinput.h>
|
||||||
#if defined(_MSC_VER) && defined(NTDDI_WIN10_RS4)
|
#if defined(_MSC_VER) && defined(NTDDI_WIN10_RS4)
|
||||||
#include <winrt/Windows.UI.ViewManagement.h>
|
#include <winrt/Windows.UI.ViewManagement.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -984,6 +985,9 @@ void VideoDriver_Win32Base::InputLoop()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();
|
if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();
|
||||||
|
|
||||||
|
/* Process gamepad input for scrolling */
|
||||||
|
this->ProcessGamepadInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VideoDriver_Win32Base::PollEvent()
|
bool VideoDriver_Win32Base::PollEvent()
|
||||||
|
@ -1143,6 +1147,106 @@ void VideoDriver_Win32Base::UnlockVideoBuffer()
|
||||||
this->buffer_locked = false;
|
this->buffer_locked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VideoDriver_Win32Base::OpenGamepad()
|
||||||
|
{
|
||||||
|
/* Don't open gamepad if already open or if gamepad scrolling is disabled */
|
||||||
|
if (this->gamepad_user_index != XUSER_MAX_COUNT) {
|
||||||
|
Debug(driver, 1, "Win32: Gamepad already open, skipping");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_settings_client.gui.gamepad_stick_selection == GSS_DISABLED) {
|
||||||
|
Debug(driver, 1, "Win32: Gamepad scrolling disabled, not opening gamepad");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for any connected gamepads */
|
||||||
|
for (DWORD i = 0; i < XUSER_MAX_COUNT; i++) {
|
||||||
|
XINPUT_STATE state = {};
|
||||||
|
|
||||||
|
if (XInputGetState(i, &state) == ERROR_SUCCESS) {
|
||||||
|
this->gamepad_user_index = i;
|
||||||
|
Debug(driver, 1, "Win32: Opened gamepad at index {}", i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VideoDriver_Win32Base::CloseGamepad()
|
||||||
|
{
|
||||||
|
if (this->gamepad_user_index != XUSER_MAX_COUNT) {
|
||||||
|
this->gamepad_user_index = XUSER_MAX_COUNT;
|
||||||
|
Debug(driver, 1, "Win32: Closed gamepad");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VideoDriver_Win32Base::ProcessGamepadInput()
|
||||||
|
{
|
||||||
|
/* Skip if gamepad scrolling is disabled */
|
||||||
|
if (_settings_client.gui.gamepad_stick_selection == GSS_DISABLED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If no gamepad is currently open, try to reconnect periodically */
|
||||||
|
if (this->gamepad_user_index == XUSER_MAX_COUNT) {
|
||||||
|
static bool logged_no_gamepad = false;
|
||||||
|
|
||||||
|
/* Only try to reconnect every 60 frames (~1 second at 60 FPS) to avoid spam */
|
||||||
|
if (this->gamepad_reconnect_timer > 0) {
|
||||||
|
this->gamepad_reconnect_timer--;
|
||||||
|
if (!logged_no_gamepad) {
|
||||||
|
Debug(driver, 2, "Win32: No gamepad available for input processing");
|
||||||
|
logged_no_gamepad = true;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to open gamepad */
|
||||||
|
this->OpenGamepad();
|
||||||
|
|
||||||
|
/* If still no gamepad, set timer for next retry */
|
||||||
|
if (this->gamepad_user_index == XUSER_MAX_COUNT) {
|
||||||
|
this->gamepad_reconnect_timer = 60; /* Retry in ~1 second */
|
||||||
|
if (!logged_no_gamepad) {
|
||||||
|
Debug(driver, 2, "Win32: No gamepad available for input processing");
|
||||||
|
logged_no_gamepad = true;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
/* Successfully reconnected */
|
||||||
|
logged_no_gamepad = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get gamepad state */
|
||||||
|
XINPUT_STATE state = {};
|
||||||
|
|
||||||
|
if (XInputGetState(this->gamepad_user_index, &state) != ERROR_SUCCESS) {
|
||||||
|
Debug(driver, 1, "Win32: Gamepad disconnected, closing and will retry connection");
|
||||||
|
this->CloseGamepad();
|
||||||
|
this->gamepad_reconnect_timer = 60; /* Start retry timer */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get analog stick values based on stick selection
|
||||||
|
* Note: XInput uses SHORT values for stick positions, but we have to extend to INT
|
||||||
|
* to avoid overflow when inverting the Y-axis value */
|
||||||
|
INT stick_x = 0, stick_y = 0;
|
||||||
|
if (_settings_client.gui.gamepad_stick_selection == GSS_LEFT_STICK) {
|
||||||
|
stick_x = state.Gamepad.sThumbLX;
|
||||||
|
stick_y = state.Gamepad.sThumbLY;
|
||||||
|
Debug(driver, 3, "Win32: Left stick raw values: x={}, y={}", stick_x, stick_y);
|
||||||
|
} else if (_settings_client.gui.gamepad_stick_selection == GSS_RIGHT_STICK) {
|
||||||
|
stick_x = state.Gamepad.sThumbRX;
|
||||||
|
stick_y = state.Gamepad.sThumbRY;
|
||||||
|
Debug(driver, 3, "Win32: Right stick raw values: x={}, y={}", stick_x, stick_y);
|
||||||
|
}
|
||||||
|
stick_y = -stick_y; // Xinput Y-axis is inverted from other libraries
|
||||||
|
|
||||||
|
/* Use the common gamepad handling function */
|
||||||
|
HandleGamepadScrolling(stick_x, stick_y, 32767);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static FVideoDriver_Win32GDI iFVideoDriver_Win32GDI;
|
static FVideoDriver_Win32GDI iFVideoDriver_Win32GDI;
|
||||||
|
|
||||||
|
@ -1158,6 +1262,11 @@ std::optional<std::string_view> VideoDriver_Win32GDI::Start(const StringList &pa
|
||||||
|
|
||||||
MarkWholeScreenDirty();
|
MarkWholeScreenDirty();
|
||||||
|
|
||||||
|
/* Initialize gamepad for scrolling */
|
||||||
|
Debug(driver, 1, "Win32: Attempting to initialize gamepad support");
|
||||||
|
Debug(driver, 1, "Win32: Gamepad stick selection setting: {}", _settings_client.gui.gamepad_stick_selection);
|
||||||
|
this->OpenGamepad();
|
||||||
|
|
||||||
this->is_game_threaded = !GetDriverParamBool(param, "no_threads") && !GetDriverParamBool(param, "no_thread");
|
this->is_game_threaded = !GetDriverParamBool(param, "no_threads") && !GetDriverParamBool(param, "no_thread");
|
||||||
|
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
@ -1165,6 +1274,7 @@ std::optional<std::string_view> VideoDriver_Win32GDI::Start(const StringList &pa
|
||||||
|
|
||||||
void VideoDriver_Win32GDI::Stop()
|
void VideoDriver_Win32GDI::Stop()
|
||||||
{
|
{
|
||||||
|
this->CloseGamepad();
|
||||||
DeleteObject(this->gdi_palette);
|
DeleteObject(this->gdi_palette);
|
||||||
DeleteObject(this->dib_sect);
|
DeleteObject(this->dib_sect);
|
||||||
|
|
||||||
|
@ -1472,6 +1582,11 @@ std::optional<std::string_view> VideoDriver_Win32OpenGL::Start(const StringList
|
||||||
|
|
||||||
MarkWholeScreenDirty();
|
MarkWholeScreenDirty();
|
||||||
|
|
||||||
|
/* Initialize gamepad for scrolling */
|
||||||
|
Debug(driver, 1, "Win32: Attempting to initialize gamepad support");
|
||||||
|
Debug(driver, 1, "Win32: Gamepad stick selection setting: {}", _settings_client.gui.gamepad_stick_selection);
|
||||||
|
this->OpenGamepad();
|
||||||
|
|
||||||
this->is_game_threaded = !GetDriverParamBool(param, "no_threads") && !GetDriverParamBool(param, "no_thread");
|
this->is_game_threaded = !GetDriverParamBool(param, "no_threads") && !GetDriverParamBool(param, "no_thread");
|
||||||
|
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
@ -1479,6 +1594,7 @@ std::optional<std::string_view> VideoDriver_Win32OpenGL::Start(const StringList
|
||||||
|
|
||||||
void VideoDriver_Win32OpenGL::Stop()
|
void VideoDriver_Win32OpenGL::Stop()
|
||||||
{
|
{
|
||||||
|
this->CloseGamepad();
|
||||||
this->DestroyContext();
|
this->DestroyContext();
|
||||||
this->VideoDriver_Win32Base::Stop();
|
this->VideoDriver_Win32Base::Stop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <xinput.h>
|
||||||
|
|
||||||
/** Base class for Windows video drivers. */
|
/** Base class for Windows video drivers. */
|
||||||
class VideoDriver_Win32Base : public VideoDriver {
|
class VideoDriver_Win32Base : public VideoDriver {
|
||||||
|
@ -48,6 +49,13 @@ protected:
|
||||||
|
|
||||||
bool buffer_locked; ///< Video buffer was locked by the main thread.
|
bool buffer_locked; ///< Video buffer was locked by the main thread.
|
||||||
|
|
||||||
|
/** Gamepad support for map scrolling */
|
||||||
|
DWORD gamepad_user_index = XUSER_MAX_COUNT; ///< Index of currently opened gamepad (XUSER_MAX_COUNT = no gamepad).
|
||||||
|
uint32_t gamepad_reconnect_timer = 0; ///< Timer for retrying gamepad connection after disconnect.
|
||||||
|
void OpenGamepad();
|
||||||
|
void CloseGamepad();
|
||||||
|
void ProcessGamepadInput();
|
||||||
|
|
||||||
Dimension GetScreenSize() const override;
|
Dimension GetScreenSize() const override;
|
||||||
float GetDPIScale() override;
|
float GetDPIScale() override;
|
||||||
void InputLoop() override;
|
void InputLoop() override;
|
||||||
|
|
|
@ -3572,3 +3572,81 @@ void PickerWindowBase::Close([[maybe_unused]] int data)
|
||||||
ResetObjectToPlace();
|
ResetObjectToPlace();
|
||||||
this->Window::Close();
|
this->Window::Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process gamepad analog stick input for viewport scrolling.
|
||||||
|
* This is a common function that can be used by any video driver that supports gamepads.
|
||||||
|
* @param stick_x Raw analog stick X value (typically -32768 to 32767 range)
|
||||||
|
* @param stick_y Raw analog stick Y value (typically -32768 to 32767 range)
|
||||||
|
* @param max_axis_value Maximum value for the analog stick axes (e.g., 32767 for SDL2)
|
||||||
|
*/
|
||||||
|
void HandleGamepadScrolling(int stick_x, int stick_y, int max_axis_value)
|
||||||
|
{
|
||||||
|
/* Skip if gamepad stick selection is disabled */
|
||||||
|
if (_settings_client.gui.gamepad_stick_selection == GSS_DISABLED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Apply deadzone (convert percentage to axis range) */
|
||||||
|
const int deadzone = (_settings_client.gui.gamepad_deadzone * max_axis_value) / 100;
|
||||||
|
|
||||||
|
if (abs(stick_x) < deadzone) stick_x = 0;
|
||||||
|
if (abs(stick_y) < deadzone) stick_y = 0;
|
||||||
|
|
||||||
|
/* Skip if no movement after deadzone */
|
||||||
|
if (stick_x == 0 && stick_y == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate scroll delta with sensitivity */
|
||||||
|
float sensitivity = _settings_client.gui.gamepad_sensitivity / 10.0f;
|
||||||
|
int delta_x = (int)(stick_x * sensitivity / (max_axis_value / 16)); // Scale down from axis range
|
||||||
|
int delta_y = (int)(stick_y * sensitivity / (max_axis_value / 16));
|
||||||
|
|
||||||
|
/* Apply axis inversion */
|
||||||
|
if (_settings_client.gui.gamepad_invert_x) delta_x = -delta_x;
|
||||||
|
if (_settings_client.gui.gamepad_invert_y) delta_y = -delta_y;
|
||||||
|
|
||||||
|
/* Skip if deltas are too small */
|
||||||
|
if (abs(delta_x) < 1 && abs(delta_y) < 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Apply scrolling based on cursor position */
|
||||||
|
if (_game_mode != GM_MENU && _game_mode != GM_BOOTSTRAP) {
|
||||||
|
Window *target_window = nullptr;
|
||||||
|
|
||||||
|
/* Check if cursor is over a window with a viewport */
|
||||||
|
Window *w = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y);
|
||||||
|
if (w != nullptr && w->viewport != nullptr) {
|
||||||
|
/* Check if cursor is actually over the viewport area within the window */
|
||||||
|
Point pt = { _cursor.pos.x - w->left, _cursor.pos.y - w->top };
|
||||||
|
if (pt.x >= w->viewport->left - w->left &&
|
||||||
|
pt.x < w->viewport->left - w->left + w->viewport->width &&
|
||||||
|
pt.y >= w->viewport->top - w->top &&
|
||||||
|
pt.y < w->viewport->top - w->top + w->viewport->height) {
|
||||||
|
target_window = w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If no viewport under cursor, use main window */
|
||||||
|
if (target_window == nullptr) {
|
||||||
|
target_window = GetMainWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Apply scrolling to the target viewport */
|
||||||
|
if (target_window != nullptr && target_window->viewport != nullptr) {
|
||||||
|
/* Check if the viewport is following a vehicle (similar to mouse scroll behavior) */
|
||||||
|
if (target_window == GetMainWindow() && target_window->viewport->follow_vehicle != VehicleID::Invalid()) {
|
||||||
|
/* If following a vehicle, center on it and stop following (like mouse scroll) */
|
||||||
|
const Vehicle *veh = Vehicle::Get(target_window->viewport->follow_vehicle);
|
||||||
|
ScrollMainWindowTo(veh->x_pos, veh->y_pos, veh->z_pos, true); // This also resets follow_vehicle
|
||||||
|
return; // Don't apply gamepad scroll, just like mouse scroll returns ES_NOT_HANDLED
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Apply the scroll using the same method as keyboard scrolling */
|
||||||
|
target_window->viewport->dest_scrollpos_x += ScaleByZoom(delta_x, target_window->viewport->zoom);
|
||||||
|
target_window->viewport->dest_scrollpos_y += ScaleByZoom(delta_y, target_window->viewport->zoom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue