Merge branch 'master' into jgrpp

# Conflicts:
#	media/baseset/CMakeLists.txt
#	src/build_vehicle_gui.cpp
#	src/console.cpp
#	src/debug.cpp
#	src/fontcache/freetypefontcache.cpp
#	src/network/network.cpp
#	src/openttd.cpp
#	src/os/macosx/font_osx.cpp
#	src/os/windows/font_win32.cpp
#	src/settings_gui.cpp
#	src/video/sdl2_v.cpp
#	src/widgets/settings_widget.h
#	src/window_gui.h
pull/642/head
Jonathan G Rennison 4 months ago
commit d7b75614bb

@ -56,6 +56,7 @@
- George - Canal/Lock graphics
- Andrew Parkhouse (andythenorth) - River graphics
- David Dallaston (Pikka) - Tram tracks
- Richard Wheeler (zephyris) - OpenTTD TrueType font
- All Translators - For their support to make OpenTTD a truly international game
- Bug Reporters - Thanks for all bug reports
- Chris Sawyer - For an amazing game!

@ -16,7 +16,6 @@
.Op Fl g Op Ar savegame
.Op Fl G Ar seed
.Op Fl I Ar graphicsset
.Op Fl l Ar host Ns Op : Ns Ar port
.Op Fl m Ar driver
.Op Fl M Ar musicset
.Op Fl n Ar host Ns Oo : Ns Ar port Oc Ns Op # Ns Ar company
@ -82,9 +81,6 @@ Select the graphics set
see
.Fl h
for a full list.
.It Fl l Ar host Ns Op : Ns Ar port
Redirect debug output; see
.Fl d .
.It Fl m Ar driver
Select the music driver
.Ar driver ;

@ -17,6 +17,10 @@ set(BASESET_OTHER_SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/openttd.grf
${CMAKE_CURRENT_SOURCE_DIR}/opntitle.dat
${CMAKE_CURRENT_SOURCE_DIR}/orig_extra.grf
${CMAKE_CURRENT_SOURCE_DIR}/OpenTTD-Sans.ttf
${CMAKE_CURRENT_SOURCE_DIR}/OpenTTD-Serif.ttf
${CMAKE_CURRENT_SOURCE_DIR}/OpenTTD-Small.ttf
${CMAKE_CURRENT_SOURCE_DIR}/OpenTTD-Mono.ttf
${CMAKE_CURRENT_SOURCE_DIR}/innerhighlight.grf
${CMAKE_CURRENT_SOURCE_DIR}/progsignals.grf
${CMAKE_CURRENT_SOURCE_DIR}/extra_signals.grf
@ -73,7 +77,7 @@ foreach(BASESET_OTHER_SOURCE_FILE IN LISTS BASESET_OTHER_SOURCE_FILES)
get_filename_component(BASESET_OTHER_SOURCE_FILE_NAME "${BASESET_OTHER_SOURCE_FILE}" NAME)
set(BASESET_OTHER_BINARY_FILE "${CMAKE_BINARY_DIR}/baseset/${BASESET_OTHER_SOURCE_FILE_NAME}")
add_custom_command(OUTPUT ${BASESET_OTHER_BINARY_FILE}
add_custom_command_timestamp(OUTPUT ${BASESET_OTHER_BINARY_FILE}
COMMAND ${CMAKE_COMMAND} -E copy
${BASESET_OTHER_SOURCE_FILE}
${BASESET_OTHER_BINARY_FILE}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,6 @@
# OpenTTD TrueType font
The OpenTTD TrueType font was created by Zephyris and is maintained on [Github](https://github.com/zephyris/openttd-ttf).
It is licensed under GPL-2.0.
The currently included files correspond to release v0.3.

@ -1307,7 +1307,7 @@ void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_li
* @param selected Currently selected sort criterion.
* @param button Widget button.
*/
void DisplayVehicleSortDropDown(Window *w, const VehicleType vehicle_type, const int selected, const int button)
void DisplayVehicleSortDropDown(Window *w, VehicleType vehicle_type, int selected, WidgetID button)
{
uint32_t hidden_mask = 0;
/* Disable sorting by power or tractive effort when the original acceleration model for road vehicles is being used. */

@ -96,7 +96,6 @@ void IConsolePrint(TextColour colour_code, const char *string)
{
assert(IsValidConsoleColour(colour_code));
char *str;
if (_redirect_console_to_client != INVALID_CLIENT_ID) {
/* Redirect the string to the client */
NetworkServerSendRcon(_redirect_console_to_client, colour_code, string);
@ -110,22 +109,18 @@ void IConsolePrint(TextColour colour_code, const char *string)
/* Create a copy of the string, strip it of colours and invalid
* characters and (when applicable) assign it to the console buffer */
str = stredup(string);
str_strip_colours(str);
StrMakeValidInPlace(str);
std::string str = StrMakeValid(string, SVS_NONE);
if (_network_dedicated) {
NetworkAdminConsole("console", str);
fprintf(stdout, "%s%s\n", log_prefix().GetLogPrefix(), str);
fprintf(stdout, "%s%s\n", log_prefix().GetLogPrefix(), str.c_str());
fflush(stdout);
IConsoleWriteToLogFile(str);
free(str); // free duplicated string since it's not used anymore
IConsoleWriteToLogFile(str.c_str());
return;
}
IConsoleWriteToLogFile(str);
IConsoleGUIPrint(colour_code, str);
free(str);
IConsoleWriteToLogFile(str.c_str());
IConsoleGUIPrint(colour_code, std::move(str));
}
/**

@ -528,9 +528,9 @@ static void IConsoleTabCompletion()
* @param colour_code the colour of the command. Red in case of errors, etc.
* @param str the message entered or output on the console (notice, error, etc.)
*/
void IConsoleGUIPrint(TextColour colour_code, char *str)
void IConsoleGUIPrint(TextColour colour_code, std::string str)
{
_iconsole_buffer.push_front(IConsoleLine(str, colour_code));
_iconsole_buffer.push_front(IConsoleLine(std::move(str), colour_code));
SetWindowDirty(WC_CONSOLE, 0);
}

@ -88,6 +88,6 @@ bool GetArgumentInteger(uint32_t *value, const char *arg);
void IConsoleGUIInit();
void IConsoleGUIFree();
void IConsoleGUIPrint(TextColour colour_code, char *string);
void IConsoleGUIPrint(TextColour colour_code, std::string str);
#endif /* CONSOLE_INTERNAL_H */

@ -26,7 +26,6 @@
#include "walltime_func.h"
#include "network/network_admin.h"
SOCKET _debug_socket = INVALID_SOCKET;
#if defined(RANDOM_DEBUG) && defined(UNIX) && defined(__GLIBC__)
#include <unistd.h>
@ -140,20 +139,7 @@ char *DumpDebugFacilityNames(char *buf, char *last)
*/
void debug_print(const char *dbg, const char *buf)
{
if (_debug_socket != INVALID_SOCKET) {
char buf2[1024 + 32];
seprintf(buf2, lastof(buf2), "%sdbg: [%s] %s\n", log_prefix().GetLogPrefix(), dbg, buf);
/* Prevent sending a message concurrently, as that might cause interleaved messages. */
static std::mutex _debug_socket_mutex;
std::lock_guard<std::mutex> lock(_debug_socket_mutex);
/* Sending out an error when this fails would be nice, however... the error
* would have to be send over this failing socket which won't work. */
send(_debug_socket, buf2, (int)strlen(buf2), 0);
return;
}
if (strcmp(dbg, "desync") == 0) {
static FILE *f = FioFOpenFile("commands-out.log", "wb", AUTOSAVE_DIR);
if (f != nullptr) {

@ -52,6 +52,6 @@ extern const StringID _engine_sort_listing[][14];
extern EngList_SortTypeFunction * const _engine_sort_functions[][13];
uint GetEngineListHeight(VehicleType type);
void DisplayVehicleSortDropDown(Window *w, VehicleType vehicle_type, int selected, int button);
void DisplayVehicleSortDropDown(Window *w, VehicleType vehicle_type, int selected, WidgetID button);
#endif /* ENGINE_GUI_H */

@ -18,6 +18,7 @@
#include "strings_func.h"
#include "viewport_func.h"
#include "window_func.h"
#include "fileio_func.h"
#include "safeguards.h"
@ -78,7 +79,7 @@ bool GetFontAAState(FontSize size, bool check_blitter)
/* AA is only supported for 32 bpp */
if (check_blitter && BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 32) return false;
return GetFontCacheSubSetting(size)->aa;
return _fcsettings.global_aa || GetFontCacheSubSetting(size)->aa;
}
void SetFont(FontSize fontsize, const std::string &font, uint size, bool aa)
@ -126,13 +127,52 @@ void SetFont(FontSize fontsize, const std::string &font, uint size, bool aa)
#ifdef WITH_FREETYPE
extern void LoadFreeTypeFont(FontSize fs);
extern void LoadFreeTypeFont(FontSize fs, const std::string &file_name, uint size);
extern void UninitFreeType();
#elif defined(_WIN32)
extern void LoadWin32Font(FontSize fs);
extern void LoadWin32Font(FontSize fs, const std::string &file_name, uint size);
#elif defined(WITH_COCOA)
extern void LoadCoreTextFont(FontSize fs);
extern void LoadCoreTextFont(FontSize fs, const std::string &file_name, uint size);
#endif
static void TryLoadDefaultTrueTypeFont([[maybe_unused]] FontSize fs)
{
#if defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA)
std::string font_name{};
switch (fs) {
case FS_NORMAL:
font_name = "OpenTTD-Sans.ttf";
break;
case FS_SMALL:
font_name = "OpenTTD-Small.ttf";
break;
case FS_LARGE:
font_name = "OpenTTD-Serif.ttf";
break;
case FS_MONO:
font_name = "OpenTTD-Mono.ttf";
break;
default: NOT_REACHED();
}
/* Find font file. */
std::string full_font = FioFindFullPath(BASESET_DIR, font_name);
if (!full_font.empty()) {
int size = FontCache::GetDefaultFontHeight(fs);
#ifdef WITH_FREETYPE
LoadFreeTypeFont(fs, full_font, size);
#elif defined(_WIN32)
LoadWin32Font(fs, full_font, size);
#elif defined(WITH_COCOA)
LoadCoreTextFont(fs, full_font, size);
#endif
}
#endif /* defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA) */
}
/**
* (Re)initialize the font cache related things, i.e. load the non-sprite fonts.
* @param monospace Whether to initialise the monospace or regular fonts.
@ -147,13 +187,17 @@ void InitFontCache(bool monospace)
FontCache *fc = FontCache::Get(fs);
if (fc->HasParent()) delete fc;
if (!_fcsettings.prefer_sprite && GetFontCacheSubSetting(fs)->font.empty()) {
TryLoadDefaultTrueTypeFont(fs);
} else {
#ifdef WITH_FREETYPE
LoadFreeTypeFont(fs);
LoadFreeTypeFont(fs);
#elif defined(_WIN32)
LoadWin32Font(fs);
LoadWin32Font(fs);
#elif defined(WITH_COCOA)
LoadCoreTextFont(fs);
LoadCoreTextFont(fs);
#endif
}
}
}

@ -114,9 +114,10 @@ public:
/**
* Map a character into a glyph.
* @param key The character.
* @param fallback Allow fallback to the parent font.
* @return The glyph ID used to draw the character.
*/
virtual GlyphID MapCharToGlyph(char32_t key) = 0;
virtual GlyphID MapCharToGlyph(char32_t key, bool fallback = true) = 0;
/**
* Read a font table from the font.
@ -221,6 +222,8 @@ struct FontCacheSettings {
FontCacheSubSetting medium; ///< The normal font size.
FontCacheSubSetting large; ///< The largest font; mostly used for newspapers.
FontCacheSubSetting mono; ///< The mono space font used for license/readme viewers.
bool prefer_sprite; ///< Whether to prefer the built-in sprite font over resizable fonts.
bool global_aa; ///< Whether to anti alias all font sizes.
};
extern FontCacheSettings _fcsettings;

@ -9,6 +9,7 @@
#include "../stdafx.h"
#include "../debug.h"
#include "../debug_fmt.h"
#include "../fontcache.h"
#include "../fontdetection.h"
#include "../blitter/factory.hpp"
@ -41,7 +42,7 @@ public:
FreeTypeFontCache(FontSize fs, FT_Face face, int pixels);
~FreeTypeFontCache();
void ClearFontCache() override;
GlyphID MapCharToGlyph(char32_t key) override;
GlyphID MapCharToGlyph(char32_t key, bool allow_fallback = true) override;
std::string GetFontName() override { return stdstr_fmt("%s, %s", face->family_name, face->style_name); }
bool IsBuiltInFont() override { return false; }
const void *GetOSHandle() override { return &face; }
@ -117,6 +118,42 @@ void FreeTypeFontCache::SetFontSize(FontSize, FT_Face, int pixels)
font_height_cache[this->fs] = this->GetHeight();
}
static FT_Error LoadFont(FontSize fs, FT_Face face, const char *font_name, uint size)
{
Debug(fontcache, 2, "Requested '{}', using '{} {}'", font_name, face->family_name, face->style_name);
/* Attempt to select the unicode character map */
FT_Error error = FT_Select_Charmap(face, ft_encoding_unicode);
if (error == FT_Err_Ok) goto found_face; // Success
if (error == FT_Err_Invalid_CharMap_Handle) {
/* Try to pick a different character map instead. We default to
* the first map, but platform_id 0 encoding_id 0 should also
* be unicode (strange system...) */
FT_CharMap found = face->charmaps[0];
int i;
for (i = 0; i < face->num_charmaps; i++) {
FT_CharMap charmap = face->charmaps[i];
if (charmap->platform_id == 0 && charmap->encoding_id == 0) {
found = charmap;
}
}
if (found != nullptr) {
error = FT_Set_Charmap(face, found);
if (error == FT_Err_Ok) goto found_face;
}
}
FT_Done_Face(face);
return error;
found_face:
new FreeTypeFontCache(fs, face, size);
return FT_Err_Ok;
}
/**
* Loads the freetype font.
* First type to load the fontname as if it were a path. If that fails,
@ -159,40 +196,40 @@ void LoadFreeTypeFont(FontSize fs)
if (error != FT_Err_Ok) error = GetFontByFaceName(font_name, &face);
if (error == FT_Err_Ok) {
DEBUG(fontcache, 2, "Requested '%s', using '%s %s'", font_name, face->family_name, face->style_name);
/* Attempt to select the unicode character map */
error = FT_Select_Charmap(face, ft_encoding_unicode);
if (error == FT_Err_Ok) goto found_face; // Success
if (error == FT_Err_Invalid_CharMap_Handle) {
/* Try to pick a different character map instead. We default to
* the first map, but platform_id 0 encoding_id 0 should also
* be unicode (strange system...) */
FT_CharMap found = face->charmaps[0];
int i;
for (i = 0; i < face->num_charmaps; i++) {
FT_CharMap charmap = face->charmaps[i];
if (charmap->platform_id == 0 && charmap->encoding_id == 0) {
found = charmap;
}
}
if (found != nullptr) {
error = FT_Set_Charmap(face, found);
if (error == FT_Err_Ok) goto found_face;
}
error = LoadFont(fs, face, font_name, settings->size);
if (error != FT_Err_Ok) {
ShowInfo("Unable to use '{}' for {} font, FreeType reported error 0x{:X}, using sprite font instead", font_name, FontSizeToName(fs), error);
}
} else {
FT_Done_Face(face);
}
}
FT_Done_Face(face);
/**
* Load a TrueType font from a file.
* @param fs The font size to load.
* @param file_name Path to the font file.
* @param size Requested font size.
*/
void LoadFreeTypeFont(FontSize fs, const std::string &file_name, uint size)
{
if (_library == nullptr) {
if (FT_Init_FreeType(&_library) != FT_Err_Ok) {
ShowInfo("Unable to initialize FreeType, using sprite fonts instead");
return;
}
ShowInfoF("Unable to use '%s' for %s font, FreeType reported error 0x%X, using sprite font instead", font_name, FontSizeToName(fs), error);
return;
Debug(fontcache, 2, "Initialized");
}
found_face:
new FreeTypeFontCache(fs, face, settings->size);
FT_Face face = nullptr;
int32_t index = 0;
FT_Error error = FT_New_Face(_library, file_name.c_str(), index, &face);
if (error == FT_Err_Ok) {
LoadFont(fs, face, file_name.c_str(), size);
} else {
FT_Done_Face(face);
}
}
@ -278,15 +315,17 @@ const Sprite *FreeTypeFontCache::InternalGetGlyph(GlyphID key, bool aa)
}
GlyphID FreeTypeFontCache::MapCharToGlyph(char32_t key)
GlyphID FreeTypeFontCache::MapCharToGlyph(char32_t key, bool allow_fallback)
{
assert(IsPrintable(key));
if (key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) {
FT_UInt glyph = FT_Get_Char_Index(this->face, key);
if (glyph == 0 && allow_fallback && key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) {
return this->parent->MapCharToGlyph(key);
}
return FT_Get_Char_Index(this->face, key);
return glyph;
}
const void *FreeTypeFontCache::InternalGetFontTable(uint32_t tag, size_t &length)

@ -29,7 +29,7 @@ public:
const Sprite *GetGlyph(GlyphID key) override;
uint GetGlyphWidth(GlyphID key) override;
bool GetDrawGlyphShadow() override;
GlyphID MapCharToGlyph(char32_t key) override { assert(IsPrintable(key)); return SPRITE_GLYPH | key; }
GlyphID MapCharToGlyph(char32_t key, [[maybe_unused]] bool allow_fallback = true) override { assert(IsPrintable(key)); return SPRITE_GLYPH | key; }
const void *GetFontTable(uint32_t, size_t &length) override { length = 0; return nullptr; }
std::string GetFontName() override { return "sprite"; }
bool IsBuiltInFont() override { return true; }

@ -600,6 +600,8 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left,
bool draw_shadow = false;
for (int run_index = 0; run_index < line.CountRuns(); run_index++) {
const ParagraphLayouter::VisualRun &run = line.GetVisualRun(run_index);
const auto &glyphs = run.GetGlyphs();
const auto &positions = run.GetPositions();
const Font *f = run.GetFont();
FontCache *fc = f->fc;
@ -613,14 +615,14 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left,
draw_shadow = fc->GetDrawGlyphShadow() && (colour & TC_NO_SHADE) == 0 && (colour & ~TC_FORCED) != TC_BLACK;
for (int i = 0; i < run.GetGlyphCount(); i++) {
GlyphID glyph = run.GetGlyphs()[i];
GlyphID glyph = glyphs[i];
/* Not a valid glyph (empty) */
if (glyph == 0xFFFF) continue;
int begin_x = (int)run.GetPositions()[i * 2] + left - offset_x;
int end_x = (int)run.GetPositions()[i * 2 + 2] + left - offset_x - 1;
int top = (int)run.GetPositions()[i * 2 + 1] + y;
int begin_x = (int)positions[i * 2] + left - offset_x;
int end_x = (int)positions[i * 2 + 2] + left - offset_x - 1;
int top = (int)positions[i * 2 + 1] + y;
/* Truncated away. */
if (truncation && (begin_x < min_x || end_x > max_x)) continue;
@ -2131,6 +2133,10 @@ bool ToggleFullScreen(bool fs)
void SortResolutions()
{
std::sort(_resolutions.begin(), _resolutions.end());
/* Remove any duplicates from the list. */
auto last = std::unique(_resolutions.begin(), _resolutions.end());
_resolutions.erase(last, _resolutions.end());
}
/**

@ -257,11 +257,13 @@ Point Layouter::GetCharPosition(std::string_view::const_iterator ch) const
/* Scan all runs until we've found our code point index. */
for (int run_index = 0; run_index < line->CountRuns(); run_index++) {
const ParagraphLayouter::VisualRun &run = line->GetVisualRun(run_index);
const auto &positions = run.GetPositions();
const auto &charmap = run.GetGlyphToCharMap();
for (int i = 0; i < run.GetGlyphCount(); i++) {
/* Matching glyph? Return position. */
if ((size_t)run.GetGlyphToCharMap()[i] == index) {
Point p = { (int)run.GetPositions()[i * 2], (int)run.GetPositions()[i * 2 + 1] };
if ((size_t)charmap[i] == index) {
Point p = { (int)positions[i * 2], (int)positions[i * 2 + 1] };
return p;
}
}
@ -285,17 +287,20 @@ ptrdiff_t Layouter::GetCharAtPosition(int x, size_t line_index) const
for (int run_index = 0; run_index < line->CountRuns(); run_index++) {
const ParagraphLayouter::VisualRun &run = line->GetVisualRun(run_index);
const auto &glyphs = run.GetGlyphs();
const auto &positions = run.GetPositions();
const auto &charmap = run.GetGlyphToCharMap();
for (int i = 0; i < run.GetGlyphCount(); i++) {
/* Not a valid glyph (empty). */
if (run.GetGlyphs()[i] == 0xFFFF) continue;
if (glyphs[i] == 0xFFFF) continue;
int begin_x = (int)run.GetPositions()[i * 2];
int end_x = (int)run.GetPositions()[i * 2 + 2];
int begin_x = (int)positions[i * 2];
int end_x = (int)positions[i * 2 + 2];
if (IsInsideMM(x, begin_x, end_x)) {
/* Found our glyph, now convert to UTF-8 string index. */
size_t index = run.GetGlyphToCharMap()[i];
size_t index = charmap[i];
size_t cur_idx = 0;
for (auto str = this->string.begin(); str != this->string.end();) {

@ -193,7 +193,7 @@ void ICURun::Shape(UChar *buff, size_t buff_length)
for (unsigned int i = 0; i < glyph_count; i++) {
int x_advance;
if (buff[glyph_info[i].cluster] >= SCC_SPRITE_START && buff[glyph_info[i].cluster] <= SCC_SPRITE_END) {
if (buff[glyph_info[i].cluster] >= SCC_SPRITE_START && buff[glyph_info[i].cluster] <= SCC_SPRITE_END && glyph_info[i].codepoint == 0) {
auto glyph = this->font->fc->MapCharToGlyph(buff[glyph_info[i].cluster]);
this->glyphs.push_back(glyph);

@ -43,17 +43,31 @@ void ShowHeightmapLoad();
/* misc_gui.cpp */
void ShowLandInfo(TileIndex tile);
void ShowAboutWindow();
void ShowEstimatedCostOrIncome(Money cost, int x, int y);
/* tree_gui.cpp */
void ShowBuildTreesToolbar();
/* town_gui.cpp */
void ShowTownDirectory();
void ShowFoundTownWindow();
/* industry_gui.cpp */
void ShowIndustryDirectory();
void ShowIndustryCargoesWindow();
void ShowBuildIndustryWindow();
/* subsidy_gui.cpp */
void ShowSubsidiesList();
/* goal_gui.cpp */
void ShowGoalsList(CompanyID company);
void ShowGoalQuestion(uint16_t id, byte type, uint32_t button_mask, const std::string &question);
void ShowStoryBook(CompanyID company, uint16_t page_id = INVALID_STORY_PAGE);
void ShowEstimatedCostOrIncome(Money cost, int x, int y);
/* story_gui.cpp */
void ShowStoryBook(CompanyID company, uint16_t page_id = INVALID_STORY_PAGE);
/* viewport_gui.cpp */
void ShowExtraViewportWindow(TileIndex tile = INVALID_TILE);
void ShowExtraViewportWindowForTileUnderCursor();
@ -62,8 +76,7 @@ void ShowModifierKeyToggleWindow();
/* bridge_gui.cpp */
void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, byte bridge_type);
void ShowBuildIndustryWindow();
void ShowFoundTownWindow();
/* music_gui.cpp */
void ShowMusicWindow();
#endif /* GUI_H */

@ -160,7 +160,7 @@ struct HelpWindow : public Window {
}
private:
void EnableTextfileButton(std::string_view filename, int button_widget)
void EnableTextfileButton(std::string_view filename, WidgetID button_widget)
{
this->GetWidget<NWidgetLeaf>(button_widget)->SetDisabled(!FindGameManualFilePath(filename).has_value());
}

@ -1002,6 +1002,7 @@ STR_GAME_OPTIONS_CURRENCY_HKD :Hong Kong Dolla
STR_GAME_OPTIONS_CURRENCY_INR :Indisk rupi
STR_GAME_OPTIONS_CURRENCY_IDR :Indonesisk Rupiah
STR_GAME_OPTIONS_CURRENCY_MYR :Malaysisk Ringgit
STR_GAME_OPTIONS_CURRENCY_LVL :lettiske lats
STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Automatisk gemning
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Vælg interval imellem automatisk gemning
@ -3016,7 +3017,7 @@ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Ejer af
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Lokal myndighed: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Ingen
STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinater: {LTBLUE}{NUM}x{NUM}x{NUM} ({STRING})
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Produceret: {LTBLUE}{DATE_LONG}
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Bygget/renoveret: {LTBLUE}{DATE_LONG}
STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Stationsklasse: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Stationstype: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Lufthavnsklasse: {LTBLUE}{STRING}

@ -1044,6 +1044,11 @@ STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Check th
STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Scale bevels
STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Check this box to scale bevels by interface size
STR_GAME_OPTIONS_GUI_FONT_SPRITE :{BLACK}Use traditional sprite font
STR_GAME_OPTIONS_GUI_FONT_SPRITE_TOOLTIP :{BLACK}Check this box if you prefer to use the tradition fixed-size sprite font.
STR_GAME_OPTIONS_GUI_FONT_AA :{BLACK}Anti-alias fonts
STR_GAME_OPTIONS_GUI_FONT_AA_TOOLTIP :{BLACK}Check this box to anti-alias resizable fonts.
STR_GAME_OPTIONS_GUI_SCALE_1X :1x
STR_GAME_OPTIONS_GUI_SCALE_2X :2x
STR_GAME_OPTIONS_GUI_SCALE_3X :3x

@ -3017,7 +3017,7 @@ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Railway
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Local authority: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :None
STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordinates: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING})
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Built: {LTBLUE}{DATE_LONG}
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Built/renovated: {LTBLUE}{DATE_LONG}
STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Station class: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Station type: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Airport class: {LTBLUE}{STRING}

@ -3017,7 +3017,7 @@ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Railroad
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Local authority: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :None
STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Co-ordinates: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING})
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Built: {LTBLUE}{DATE_LONG}
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Built/renovated: {LTBLUE}{DATE_LONG}
STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Station class: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Station type: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Airport class: {LTBLUE}{STRING}

@ -3017,7 +3017,7 @@ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Rautatie
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Kunta: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Ei mitään
STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinaatit: {LTBLUE}{NUM}×{NUM}×{NUM} ({STRING})
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Rakennettu: {LTBLUE}{DATE_LONG}
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Rakennettu/peruskorjattu: {LTBLUE}{DATE_LONG}
STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Aseman luokka: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Aseman tyyppi: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Lentokentän luokka: {LTBLUE}{STRING}

@ -1003,7 +1003,7 @@ STR_GAME_OPTIONS_CURRENCY_HKD :Dollar de Hong
STR_GAME_OPTIONS_CURRENCY_INR :Roupie indienne
STR_GAME_OPTIONS_CURRENCY_IDR :Roupie indonésienne
STR_GAME_OPTIONS_CURRENCY_MYR :Malaysian Ringgit
STR_GAME_OPTIONS_CURRENCY_LVL :Lats
STR_GAME_OPTIONS_CURRENCY_LVL :Lats letton
STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Sauvegarde automatique
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Sélectionner l'intervalle de temps entre les sauvegardes automatiques
@ -3018,7 +3018,7 @@ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Proprié
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Municipalité{NBSP}: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Aucune
STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordonnées{NBSP}: {LTBLUE}{NUM} × {NUM} × {NUM} ({STRING})
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Construit le{NBSP}: {LTBLUE}{DATE_LONG}
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Construit/rénové le{NBSP}: {LTBLUE}{DATE_LONG}
STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Type de station{NBSP}: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Type de station{NBSP}: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Type d'aéroport{NBSP}: {LTBLUE}{STRING}

@ -2727,7 +2727,7 @@ STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}자동
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}차량기지를 건설합니다. 차량을 구입하거나 점검을 할 수 있습니다. SHIFT 키를 누른 채로 사용하면 예상 비용을 볼 수 있습니다
STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}선로에 경유지를 설치합니다. CTRL 키를 사용하면 같은 이름의 경유지를 서로 떨어진 곳에 지을 수 있습니다. SHIFT 키를 누른 채로 사용하면 예상 비용을 볼 수 있습니다
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}철도역을 짓습니다. CTRL 키를 사용하면 같은 이름의 역을 서로 떨어진 곳에 지을 수 있습니다. SHIFT 키를 누른 채로 사용하면 예상 비용을 볼 수 있습니다
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}신호기를 설치합니다. CTRL 키를 누르면 구식/전자식으로 전환합니다.{}선로를 따라 드래그해서 설치할 수 있습니다. CTRL 키를 누른 채로 드래그하면 다음 분기점이나 다음 신호기까지 신호기를 설치합니다.{}CTRL 키를 누른 채 클릭하면 신호기 선택 창을 전환합니다. SHIFT 키를 누른 채로 사용하면 예상 비용을 볼 수 있습니다
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}선로에 신호기를 설치합니다. CTRL 키를 누르면 구식/전자식으로 전환합니다.{}선로를 따라 드래그해서 설치할 수 있습니다. CTRL 키를 누른 채로 드래그하면 다음 분기점이나 다음 신호기까지 신호기를 설치합니다.{}CTRL 키를 누른 채 클릭하면 신호기 선택 창을 전환합니다. SHIFT 키를 누른 채로 사용하면 예상 비용을 볼 수 있습니다
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE :{BLACK}철교를 짓습니다. SHIFT 키를 누른 채로 사용하면 예상 비용을 볼 수 있습니다
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL :{BLACK}터널을 짓습니다. SHIFT 키를 누른 채로 사용하면 예상 비용을 볼 수 있습니다
STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}선로, 신호기, 경유지, 역 등의 철도 시설 건설/철거 모드를 켜거나 끌 수 있습니다. CTRL 키를 누르고 있어도 선로에서 경유지와 역을 제거할 수 있습니다

@ -3018,7 +3018,7 @@ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Dono da
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Autoridade local: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Nenhum
STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordenadas: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING})
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Construído: {LTBLUE}{DATE_LONG}
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Construído/renovado: {LTBLUE}{DATE_LONG}
STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Tipo de estação: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Tipo de estação: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Tipo de aeroporto: {LTBLUE}{STRING}

@ -3192,7 +3192,7 @@ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Влад
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Администрация: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Нет
STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Координаты: {LTBLUE}{NUM} × {NUM} × {NUM} ({STRING})
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Построено: {LTBLUE}{DATE_LONG}
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Построено/обновлено: {LTBLUE}{DATE_LONG}
STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Класс станции: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Тип станции: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Класс аэропорта: {LTBLUE}{STRING.nom}

@ -350,7 +350,7 @@ STR_SORT_BY_CARGO_CAPACITY :运载能力
STR_SORT_BY_RANGE :航行距离
STR_SORT_BY_POPULATION :人口
STR_SORT_BY_RATING :评价
STR_SORT_BY_NUM_VEHICLES :交通工具数量
STR_SORT_BY_NUM_VEHICLES :具数量
STR_SORT_BY_TOTAL_PROFIT_LAST_YEAR :去年总利润
STR_SORT_BY_TOTAL_PROFIT_THIS_YEAR :今年总利润
STR_SORT_BY_AVERAGE_PROFIT_LAST_YEAR :去年平均利润
@ -1325,7 +1325,7 @@ STR_CONFIG_SETTING_PERCENTAGE :{COMMA}%
STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :汽车斜坡坡度: {STRING}
STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :设置对汽车而言,一格斜坡的坡度大小。数值越高,坡度越大,汽车越难爬上斜坡。
STR_CONFIG_SETTING_FORBID_90_DEG :禁止列车 90 度转弯{STRING}
STR_CONFIG_SETTING_FORBID_90_DEG :禁止列车直角转向{STRING}
STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :当水平方向轨道与垂直方向轨道交叉时没有采用45度的轨道组合连接而是采用轨道90度直接连接时列车通过时需要90度转弯当本设置”打开“时将禁止火车90度转弯。
STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :允许非毗邻站台合并:{STRING}
@ -1344,7 +1344,7 @@ STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH :隧道最大长
STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH_HELPTEXT :建设隧道时允许的最大长度
STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD :原料工业建设方式: {STRING}
STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_HELPTEXT :建立重工业企业的的设定. '禁止'表示不能建立; '勘探'表示可以建立但是只能在地图上一随机处, 并可能会失败; '像别的工业一样'表示采矿业也能像其它加工业那样可以随意在任何地方建立.
STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_HELPTEXT :设定原料工业的建造方式。“禁止”表示不能建造;“勘探”表示可以建立但是只能在地图上一随机处,并可能会失败;“同其他工业”表示可以和随意建造。
###length 3
STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_NONE :不允许
STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_NORMAL :同其他工业
@ -1911,7 +1911,7 @@ STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :四倍(原版
STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :线性
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :树木自动生长: {STRING}
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :控制游戏中数目的随机生长,这将影响依赖树木的工业,比如木材厂
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 :仅在雨林扩散
@ -2826,7 +2826,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}建设/
STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}转换/升级 公路类型。按住 Shift 键显示预计费用。
STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :转换/升级 电车道类型。按住 Shift 键显示预计费用。
STR_ROAD_NAME_ROAD :路
STR_ROAD_NAME_ROAD :
STR_ROAD_NAME_TRAM :电车轨道
# Road depot construction window
@ -3017,7 +3017,7 @@ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}铁路
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}地方政府:{LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :没有
STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}坐标: {LTBLUE}{NUM} × {NUM} × {NUM} ({STRING})
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}建造时间{LTBLUE}{DATE_LONG}
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}建造/翻新于{LTBLUE}{DATE_LONG}
STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}车站分类: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}车站类型: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}飞机场分类: {LTBLUE}{STRING}
@ -3246,7 +3246,7 @@ STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}%
STR_MAPGEN_TERRAIN_TYPE :{BLACK}地形特点:
STR_MAPGEN_SEA_LEVEL :{BLACK}海洋面积:
STR_MAPGEN_SEA_LEVEL_TOOLTIP :{BLACK}选择海洋覆盖率
STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}河流数量:
STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}河流数量
STR_MAPGEN_SMOOTHNESS :{BLACK}平滑程度:
STR_MAPGEN_VARIETY :{BLACK}多样地形:
STR_MAPGEN_GENERATE :{WHITE}生成
@ -3854,7 +3854,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}运河
STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}站台:
STR_COMPANY_INFRASTRUCTURE_VIEW_STATIONS :{WHITE}车站
STR_COMPANY_INFRASTRUCTURE_VIEW_AIRPORTS :{WHITE}机场
STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}每年{CURRENCY_LONG}
STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENCY_LONG}/年
# Industry directory
STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}工业设施
@ -5625,7 +5625,7 @@ STR_VEHICLE_NAME_AIRCRAFT_POWERNAUT_HELICOPTER :Powernaut 直
# Formatting of some strings
STR_FORMAT_DATE_TINY :{ZEROFILL_NUM}-{ZEROFILL_NUM}-{NUM}
STR_FORMAT_DATE_SHORT :{STRING} {NUM}
STR_FORMAT_DATE_LONG :{2:NUM}年 {1:STRING}月 {0:STRING}日
STR_FORMAT_DATE_LONG :{2:NUM} 年 {1:STRING} 月 {0:STRING}
STR_FORMAT_DATE_ISO :{2:NUM}-{1:ZEROFILL_NUM}-{0:ZEROFILL_NUM}
STR_FORMAT_COMPANY_NUM :(公司 {COMMA})

@ -24,7 +24,6 @@ static const uint16_t NETWORK_TURN_SERVER_PORT = 3974; ///< The
static const uint16_t NETWORK_CONTENT_SERVER_PORT = 3978; ///< The default port of the content server (TCP)
static const uint16_t NETWORK_DEFAULT_PORT = 3979; ///< The default port of the game server (TCP & UDP)
static const uint16_t NETWORK_ADMIN_PORT = 3977; ///< The default port for admin network
static const uint16_t NETWORK_DEFAULT_DEBUGLOG_PORT = 3982; ///< The default port debug-log is sent to (TCP)
static const uint16_t UDP_MTU = 1460; ///< Number of bytes we can pack in a single UDP packet
static const uint16_t UDP_MTU_SHORT = 1400; ///< Number of bytes we can pack in a single UDP packet (conservative)

@ -1376,32 +1376,6 @@ std::string NetworkGenerateRandomKeyString(uint bytes)
return FormatArrayAsHex({key, bytes});
}
class TCPNetworkDebugConnecter : TCPConnecter {
private:
std::string connection_string;
public:
TCPNetworkDebugConnecter(const std::string &connection_string) : TCPConnecter(connection_string, NETWORK_DEFAULT_DEBUGLOG_PORT), connection_string(connection_string) {}
void OnFailure() override
{
DEBUG(net, 0, "Failed to open connection to %s for redirecting DEBUG()", this->connection_string.c_str());
}
void OnConnect(SOCKET s) override
{
DEBUG(net, 3, "Redirecting DEBUG() to %s", this->connection_string.c_str());
extern SOCKET _debug_socket;
_debug_socket = s;
}
};
void NetworkStartDebugLog(const std::string &connection_string)
{
new TCPNetworkDebugConnecter(connection_string);
}
/** This tries to launch the network for a given OS */
void NetworkStartUp()
{

@ -51,7 +51,6 @@ void NetworkDisconnect(bool close_admins = true);
void NetworkGameLoop();
void NetworkBackgroundLoop();
std::string_view ParseFullConnectionString(const std::string &connection_string, uint16_t &port, CompanyID *company_id = nullptr);
void NetworkStartDebugLog(const std::string &connection_string);
void NetworkPopulateCompanyStats(NetworkCompanyStats *stats);
void NetworkUpdateClientInfo(ClientID client_id);

@ -290,7 +290,6 @@ static void ShowHelp()
" -p password = Password to join server\n"
" -P password = Password to join company\n"
" -D [host][:port] = Start dedicated server\n"
" -l host[:port] = Redirect DEBUG()\n"
#if !defined(_WIN32)
" -f = Fork into the background (dedicated only)\n"
#endif
@ -732,7 +731,6 @@ static const OptionData _options[] = {
GETOPT_SHORT_VALUE('b'),
GETOPT_SHORT_OPTVAL('D'),
GETOPT_SHORT_VALUE('n'),
GETOPT_SHORT_VALUE('l'),
GETOPT_SHORT_VALUE('p'),
GETOPT_SHORT_VALUE('P'),
#if !defined(_WIN32)
@ -777,7 +775,6 @@ int openttd_main(int argc, char *argv[])
Dimension resolution = {0, 0};
std::unique_ptr<AfterNewGRFScan> scanner(new AfterNewGRFScan());
bool dedicated = false;
char *debuglog_conn = nullptr;
bool only_local_path = false;
extern bool _dedicated_forks;
@ -814,9 +811,6 @@ int openttd_main(int argc, char *argv[])
case 'n':
scanner->connection_string = mgo.opt; // host:port#company parameter
break;
case 'l':
debuglog_conn = mgo.opt;
break;
case 'p':
scanner->join_server_password = mgo.opt;
break;
@ -1028,10 +1022,6 @@ int openttd_main(int argc, char *argv[])
NetworkStartUp(); // initialize network-core
if (debuglog_conn != nullptr && _network_available) {
NetworkStartDebugLog(debuglog_conn);
}
if (!HandleBootstrap()) {
ShutdownGame();
return ret;

@ -9,6 +9,7 @@
#include "../../stdafx.h"
#include "../../debug.h"
#include "../../debug_fmt.h"
#include "font_osx.h"
#include "../../core/math_func.hpp"
#include "../../blitter/factory.hpp"
@ -182,14 +183,10 @@ void CoreTextFontCache::SetFontSize(int pixels)
DEBUG(fontcache, 2, "Loaded font '%s' with size %d", this->font_name.c_str(), pixels);
}
GlyphID CoreTextFontCache::MapCharToGlyph(char32_t key)
GlyphID CoreTextFontCache::MapCharToGlyph(char32_t key, bool allow_fallback)
{
assert(IsPrintable(key));
if (key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) {
return this->parent->MapCharToGlyph(key);
}
/* Convert characters outside of the Basic Multilingual Plane into surrogate pairs. */
UniChar chars[2];
if (key >= 0x010000U) {
@ -204,6 +201,10 @@ GlyphID CoreTextFontCache::MapCharToGlyph(char32_t key)
return glyph[0];
}
if (allow_fallback && key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) {
return this->parent->MapCharToGlyph(key);
}
return 0;
}
@ -300,6 +301,40 @@ const Sprite *CoreTextFontCache::InternalGetGlyph(GlyphID key, bool use_aa)
return new_glyph.sprite;
}
static CTFontDescriptorRef LoadFontFromFile(const std::string &font_name)
{
if (!MacOSVersionIsAtLeast(10, 6, 0)) return nullptr;
/* Might be a font file name, try load it. Direct font loading is
* only supported starting on OSX 10.6. */
CFAutoRelease<CFStringRef> path;
/* See if this is an absolute path. */
if (FileExists(font_name)) {
path.reset(CFStringCreateWithCString(kCFAllocatorDefault, font_name.c_str(), kCFStringEncodingUTF8));
} else {
/* Scan the search-paths to see if it can be found. */
std::string full_font = FioFindFullPath(BASE_DIR, font_name);
if (!full_font.empty()) {
path.reset(CFStringCreateWithCString(kCFAllocatorDefault, full_font.c_str(), kCFStringEncodingUTF8));
}
}
if (path) {
/* Try getting a font descriptor to see if the system can use it. */
CFAutoRelease<CFURLRef> url(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path.get(), kCFURLPOSIXPathStyle, false));
CFAutoRelease<CFArrayRef> descs(CTFontManagerCreateFontDescriptorsFromURL(url.get()));
if (descs && CFArrayGetCount(descs.get()) > 0) {
CTFontDescriptorRef font_ref = (CTFontDescriptorRef)CFArrayGetValueAtIndex(descs.get(), 0);
CFRetain(font_ref);
return font_ref;
}
}
return nullptr;
}
/**
* Loads the TrueType font.
* If a CoreText font description is present, e.g. from the automatic font
@ -320,33 +355,9 @@ void LoadCoreTextFont(FontSize fs)
}
if (!font_ref && MacOSVersionIsAtLeast(10, 6, 0)) {
/* Might be a font file name, try load it. Direct font loading is
* only supported starting on OSX 10.6. */
CFAutoRelease<CFStringRef> path;
/* See if this is an absolute path. */
if (FileExists(settings->font)) {
path.reset(CFStringCreateWithCString(kCFAllocatorDefault, settings->font.c_str(), kCFStringEncodingUTF8));
} else {
/* Scan the search-paths to see if it can be found. */
std::string full_font = FioFindFullPath(BASE_DIR, settings->font);
if (!full_font.empty()) {
path.reset(CFStringCreateWithCString(kCFAllocatorDefault, full_font.c_str(), kCFStringEncodingUTF8));
}
}
if (path) {
/* Try getting a font descriptor to see if the system can use it. */
CFAutoRelease<CFURLRef> url(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path.get(), kCFURLPOSIXPathStyle, false));
CFAutoRelease<CFArrayRef> descs(CTFontManagerCreateFontDescriptorsFromURL(url.get()));
if (descs && CFArrayGetCount(descs.get()) > 0) {
font_ref.reset((CTFontDescriptorRef)CFArrayGetValueAtIndex(descs.get(), 0));
CFRetain(font_ref.get());
} else {
ShowInfoF("Unable to load file '%s' for %s font, using default OS font selection instead", settings->font.c_str(), FontSizeToName(fs));
}
}
/* Might be a font file name, try load it. */
font_ref.reset(LoadFontFromFile(settings->font));
if (!font_ref) ShowInfo("Unable to load file '{}' for {} font, using default OS font selection instead", settings->font, FontSizeToName(fs));
}
if (!font_ref) {
@ -374,3 +385,17 @@ void LoadCoreTextFont(FontSize fs)
new CoreTextFontCache(fs, std::move(font_ref), settings->size);
}
/**
* Load a TrueType font from a file.
* @param fs The font size to load.
* @param file_name Path to the font file.
* @param size Requested font size.
*/
void LoadCoreTextFont(FontSize fs, const std::string &file_name, uint size)
{
CFAutoRelease<CTFontDescriptorRef> font_ref{LoadFontFromFile(file_name)};
if (font_ref) {
new CoreTextFontCache(fs, std::move(font_ref), size);
}
}

@ -29,12 +29,13 @@ public:
~CoreTextFontCache() {}
void ClearFontCache() override;
GlyphID MapCharToGlyph(char32_t key) override;
GlyphID MapCharToGlyph(char32_t key, bool allow_fallback = true) override;
std::string GetFontName() override { return font_name; }
bool IsBuiltInFont() override { return false; }
const void *GetOSHandle() override { return font.get(); }
};
void LoadCoreTextFont(FontSize fs);
void LoadCoreTextFont(FontSize fs, const std::string &file_name, uint size);
#endif /* FONT_OSX_H */

@ -170,6 +170,9 @@ static CTRunDelegateCallbacks _sprite_font_callback = {
CFAutoRelease<CFStringRef> base(CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, buff, length, kCFAllocatorNull));
CFAttributedStringReplaceString(str.get(), CFRangeMake(0, 0), base.get());
const UniChar replacment_char = 0xFFFC;
CFAutoRelease<CFStringRef> replacment_str(CFStringCreateWithCharacters(kCFAllocatorDefault, &replacment_char, 1));
/* Apply font and colour ranges to our string. This is important to make sure
* that we get proper glyph boundaries on style changes. */
int last = 0;
@ -191,10 +194,12 @@ static CTRunDelegateCallbacks _sprite_font_callback = {
CFAttributedStringSetAttribute(str.get(), CFRangeMake(last, i.first - last), kCTForegroundColorAttributeName, color);
CGColorRelease(color);
/* Install a size callback for our special sprite glyphs. */
/* Install a size callback for our special private-use sprite glyphs in case the font does not provide them. */
for (ssize_t c = last; c < i.first; c++) {
if (buff[c] >= SCC_SPRITE_START && buff[c] <= SCC_SPRITE_END) {
if (buff[c] >= SCC_SPRITE_START && buff[c] <= SCC_SPRITE_END && i.second->fc->MapCharToGlyph(buff[c], false) == 0) {
CFAutoRelease<CTRunDelegateRef> del(CTRunDelegateCreate(&_sprite_font_callback, (void *)(size_t)(buff[c] | (i.second->fc->GetSize() << 24))));
/* According to the offical documentation, if a run delegate is used, the char should always be 0xFFFC. */
CFAttributedStringReplaceString(str.get(), CFRangeMake(c, 1), replacment_str.get());
CFAttributedStringSetAttribute(str.get(), CFRangeMake(c, 1), kCTRunDelegateAttributeName, del.get());
}
}
@ -244,7 +249,8 @@ CoreTextParagraphLayout::CoreTextVisualRun::CoreTextVisualRun(CTRunRef run, Font
CGGlyph gl[this->glyphs.size()];
CTRunGetGlyphs(run, CFRangeMake(0, 0), gl);
for (size_t i = 0; i < this->glyphs.size(); i++) {
if (buff[this->glyph_to_char[i]] >= SCC_SPRITE_START && buff[this->glyph_to_char[i]] <= SCC_SPRITE_END) {
if (buff[this->glyph_to_char[i]] >= SCC_SPRITE_START && buff[this->glyph_to_char[i]] <= SCC_SPRITE_END && (gl[i] == 0 || gl[i] == 3)) {
/* A glyph of 0 indidicates not found, while apparently 3 is what char 0xFFFC maps to. */
this->glyphs[i] = font->fc->MapCharToGlyph(buff[this->glyph_to_char[i]]);
this->positions[i * 2 + 0] = pts[i].x;
this->positions[i * 2 + 1] = (font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(font->fc->GetSize()))) / 2; // Align sprite font to centre

@ -9,6 +9,7 @@
#include "../../stdafx.h"
#include "../../debug.h"
#include "../../debug_fmt.h"
#include "../../blitter/factory.hpp"
#include "../../core/alloc_func.hpp"
#include "../../core/math_func.hpp"
@ -279,14 +280,10 @@ void Win32FontCache::ClearFontCache()
return new_glyph.sprite;
}
/* virtual */ GlyphID Win32FontCache::MapCharToGlyph(char32_t key)
/* virtual */ GlyphID Win32FontCache::MapCharToGlyph(char32_t key, bool allow_fallback)
{
assert(IsPrintable(key));
if (key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) {
return this->parent->MapCharToGlyph(key);
}
/* Convert characters outside of the BMP into surrogate pairs. */
WCHAR chars[2];
if (key >= 0x010000U) {
@ -299,7 +296,8 @@ void Win32FontCache::ClearFontCache()
WORD glyphs[2] = { 0, 0 };
GetGlyphIndicesW(this->dc, chars, key >= 0x010000U ? 2 : 1, glyphs, GGI_MARK_NONEXISTING_GLYPHS);
return glyphs[0] != 0xFFFF ? glyphs[0] : 0;
if (glyphs[0] != 0xFFFF) return glyphs[0];
return allow_fallback && key >= SCC_SPRITE_START && key <= SCC_SPRITE_END ? this->parent->MapCharToGlyph(key) : 0;
}
/* virtual */ const void *Win32FontCache::InternalGetFontTable(uint32_t tag, size_t &length)
@ -317,6 +315,66 @@ void Win32FontCache::ClearFontCache()
}
static bool TryLoadFontFromFile(const std::string &font_name, LOGFONT &logfont)
{
wchar_t fontPath[MAX_PATH] = {};
/* See if this is an absolute path. */
if (FileExists(font_name)) {
convert_to_fs(font_name, fontPath, lengthof(fontPath));
} else {
/* Scan the search-paths to see if it can be found. */
std::string full_font = FioFindFullPath(BASE_DIR, font_name);
if (!full_font.empty()) {
convert_to_fs(font_name, fontPath, lengthof(fontPath));
}
}
if (fontPath[0] != 0) {
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 = _gdi32.GetFunction("GetFontResourceInfoW");
if (GetFontResourceInfo != nullptr) {
/* Try to query an array of LOGFONTs that describe the file. */
DWORD len = 0;
if (GetFontResourceInfo(fontPath, &len, nullptr, 2) && len >= sizeof(LOGFONT)) {
LOGFONT *buf = (LOGFONT *)new byte[len];
if (GetFontResourceInfo(fontPath, &len, buf, 2)) {
logfont = *buf; // Just use first entry.
}
delete[](byte *)buf;
}
}
/* No dice yet. Use the file name as the font face name, hoping it matches. */
if (logfont.lfFaceName[0] == 0) {
wchar_t fname[_MAX_FNAME];
_wsplitpath(fontPath, nullptr, nullptr, fname, nullptr);
wcsncpy_s(logfont.lfFaceName, lengthof(logfont.lfFaceName), fname, _TRUNCATE);
logfont.lfWeight = strcasestr(font_name.c_str(), " bold") != nullptr || strcasestr(font_name.c_str(), "-bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts.
}
}
}
return logfont.lfFaceName[0] != 0;
}
static void LoadWin32Font(FontSize fs, const LOGFONT &logfont, uint size, const char *font_name)
{
HFONT font = CreateFontIndirect(&logfont);
if (font == nullptr) {
ShowInfo("Unable to use '{}' for {} font, Win32 reported error 0x{:X}, using sprite font instead", font_name, FontSizeToName(fs), GetLastError());
return;
}
DeleteObject(font);
new Win32FontCache(fs, logfont, size);
}
/**
* Loads the GDI font.
* If a GDI font description is present, e.g. from the automatic font
@ -341,50 +399,8 @@ void LoadWin32Font(FontSize fs)
logfont = *(const LOGFONT *)settings->os_handle;
} else if (strchr(font_name, '.') != nullptr) {
/* Might be a font file name, try load it. */
wchar_t fontPath[MAX_PATH] = {};
/* See if this is an absolute path. */
if (FileExists(settings->font)) {
convert_to_fs(font_name, fontPath, lengthof(fontPath));
} else {
/* Scan the search-paths to see if it can be found. */
std::string full_font = FioFindFullPath(BASE_DIR, font_name);
if (!full_font.empty()) {
convert_to_fs(font_name, fontPath, lengthof(fontPath));
}
}
if (fontPath[0] != 0) {
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 = _gdi32.GetFunction("GetFontResourceInfoW");
if (GetFontResourceInfo != nullptr) {
/* Try to query an array of LOGFONTs that describe the file. */
DWORD len = 0;
if (GetFontResourceInfo(fontPath, &len, nullptr, 2) && len >= sizeof(LOGFONT)) {
LOGFONT *buf = (LOGFONT *)AllocaM(byte, len);
if (GetFontResourceInfo(fontPath, &len, buf, 2)) {
logfont = *buf; // Just use first entry.
}
}
}
/* No dice yet. Use the file name as the font face name, hoping it matches. */
if (logfont.lfFaceName[0] == 0) {
wchar_t fname[_MAX_FNAME];
_wsplitpath(fontPath, nullptr, nullptr, fname, nullptr);
wcsncpy_s(logfont.lfFaceName, lengthof(logfont.lfFaceName), fname, _TRUNCATE);
logfont.lfWeight = strcasestr(font_name, " bold") != nullptr || strcasestr(font_name, "-bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts.
}
} else {
ShowInfoF("Unable to load file '%s' for %s font, using default windows font selection instead", font_name, FontSizeToName(fs));
}
if (!TryLoadFontFromFile(settings->font, logfont)) {
ShowInfo("Unable to load file '{}' for {} font, using default windows font selection instead", font_name, FontSizeToName(fs));
}
}
@ -393,12 +409,25 @@ void LoadWin32Font(FontSize fs)
convert_to_fs(font_name, logfont.lfFaceName, lengthof(logfont.lfFaceName));
}
HFONT font = CreateFontIndirect(&logfont);
if (font == nullptr) {
ShowInfoF("Unable to use '%s' for %s font, Win32 reported error 0x%lX, using sprite font instead", font_name, FontSizeToName(fs), GetLastError());
return;
}
DeleteObject(font);
LoadWin32Font(fs, logfont, settings->size, font_name);
}
/**
* Load a TrueType font from a file.
* @param fs The font size to load.
* @param file_name Path to the font file.
* @param size Requested font size.
*/
void LoadWin32Font(FontSize fs, const std::string &file_name, uint size)
{
LOGFONT logfont;
MemSetT(&logfont, 0);
logfont.lfPitchAndFamily = fs == FS_MONO ? FIXED_PITCH : VARIABLE_PITCH;
logfont.lfCharSet = DEFAULT_CHARSET;
logfont.lfOutPrecision = OUT_OUTLINE_PRECIS;
logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
new Win32FontCache(fs, logfont, settings->size);
if (TryLoadFontFromFile(file_name, logfont)) {
LoadWin32Font(fs, logfont, size, file_name.c_str());
}
}

@ -35,11 +35,12 @@ public:
Win32FontCache(FontSize fs, const LOGFONT &logfont, int pixels);
~Win32FontCache();
void ClearFontCache() override;
GlyphID MapCharToGlyph(char32_t key) override;
GlyphID MapCharToGlyph(char32_t key, bool allow_fallback = true) override;
std::string GetFontName() override { return this->fontname; }
const void *GetOSHandle() override { return &this->logfont; }
};
void LoadWin32Font(FontSize fs);
void LoadWin32Font(FontSize fs, const std::string &file_name, uint size);
#endif /* FONT_WIN32_H */

@ -195,9 +195,11 @@ static bool UniscribeShapeRun(const UniscribeParagraphLayoutFactory::CharType *b
for (int i = 0; i < range.len; i++) {
if (buff[range.pos + i] >= SCC_SPRITE_START && buff[range.pos + i] <= SCC_SPRITE_END) {
auto pos = range.char_to_glyph[i];
range.ft_glyphs[pos] = range.font->fc->MapCharToGlyph(buff[range.pos + i]);
range.offsets[pos].dv = (range.font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(range.font->fc->GetSize()))) / 2; // Align sprite font to centre
range.advances[pos] = range.font->fc->GetGlyphWidth(range.ft_glyphs[pos]);
if (range.ft_glyphs[pos] == 0) { // Font doesn't have our special glyph, so remap.
range.ft_glyphs[pos] = range.font->fc->MapCharToGlyph(buff[range.pos + i]);
range.offsets[pos].dv = (range.font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(range.font->fc->GetSize()))) / 2; // Align sprite font to centre
range.advances[pos] = range.font->fc->GetGlyphWidth(range.ft_glyphs[pos]);
}
}
}

@ -42,7 +42,7 @@ struct OskWindow : public Window {
std::string orig_str; ///< Original string.
bool shift; ///< Is the shift effectively pressed?
OskWindow(WindowDesc *desc, Window *parent, int button) : Window(desc)
OskWindow(WindowDesc *desc, Window *parent, WidgetID button) : Window(desc)
{
this->parent = parent;
assert(parent != nullptr);

@ -58,6 +58,10 @@
extern void FlushDeparturesWindowTextCaches();
#if defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA)
# define HAS_TRUETYPE_FONT
#endif
static const StringID _autosave_dropdown[] = {
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_OFF,
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_10_MINUTES,
@ -581,6 +585,31 @@ struct GameOptionsWindow : Window {
break;
}
#ifdef HAS_TRUETYPE_FONT
case WID_GO_GUI_FONT_SPRITE:
_fcsettings.prefer_sprite = !_fcsettings.prefer_sprite;
this->SetWidgetLoweredState(WID_GO_GUI_FONT_SPRITE, _fcsettings.prefer_sprite);
this->SetWidgetDisabledState(WID_GO_GUI_FONT_AA, _fcsettings.prefer_sprite);
this->SetDirty();
InitFontCache(false);
InitFontCache(true);
ClearFontCache();
SetupWidgetDimensions();
ReInitAllWindows(true);
break;
case WID_GO_GUI_FONT_AA:
_fcsettings.global_aa = !_fcsettings.global_aa;
this->SetWidgetLoweredState(WID_GO_GUI_FONT_AA, _fcsettings.global_aa);
this->SetDirty();
ClearFontCache();
break;
#endif /* HAS_TRUETYPE_FONT */
case WID_GO_GUI_SCALE_MAIN_TOOLBAR: {
_settings_client.gui.bigger_main_toolbar = !_settings_client.gui.bigger_main_toolbar;
@ -813,6 +842,12 @@ struct GameOptionsWindow : Window {
this->SetWidgetLoweredState(WID_GO_GUI_SCALE_AUTO, _gui_scale_cfg == -1);
this->SetWidgetLoweredState(WID_GO_GUI_SCALE_BEVEL_BUTTON, _settings_client.gui.scale_bevels);
#ifdef HAS_TRUETYPE_FONT
this->SetWidgetLoweredState(WID_GO_GUI_FONT_SPRITE, _fcsettings.prefer_sprite);
this->SetWidgetLoweredState(WID_GO_GUI_FONT_AA, _fcsettings.global_aa);
this->SetWidgetDisabledState(WID_GO_GUI_FONT_AA, _fcsettings.prefer_sprite);
#endif /* HAS_TRUETYPE_FONT */
this->SetWidgetLoweredState(WID_GO_GUI_SCALE_MAIN_TOOLBAR, _settings_client.gui.bigger_main_toolbar);
this->SetWidgetDisabledState(WID_GO_BASE_GRF_DROPDOWN, _game_mode != GM_MENU);
@ -892,6 +927,16 @@ static const NWidgetPart _nested_game_options_widgets[] = {
NWidget(NWID_SPACER), SetMinimalSize(1, 0), SetFill(1, 0),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_GUI_SCALE_MAIN_TOOLBAR), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_GUI_SCALE_MAIN_TOOLBAR_TOOLTIP),
EndContainer(),
#ifdef HAS_TRUETYPE_FONT
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0),
NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_GUI_FONT_SPRITE, STR_NULL),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_GUI_FONT_SPRITE), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_GUI_FONT_SPRITE_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0),
NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_GUI_FONT_AA, STR_NULL),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_GUI_FONT_AA), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_GUI_FONT_AA_TOOLTIP),
EndContainer(),
#endif /* HAS_TRUETYPE_FONT */
EndContainer(),
EndContainer(),

@ -268,6 +268,18 @@ name = ""mono_aa""
var = _fcsettings.mono.aa
def = false
[SDTG_BOOL]
ifdef = HAS_TRUETYPE_FONT
name = ""global_aa""
var = _fcsettings.global_aa
def = true
[SDTG_BOOL]
ifdef = HAS_TRUETYPE_FONT
name = ""prefer_sprite_font""
var = _fcsettings.prefer_sprite
def = false
[SDTG_VAR]
name = ""sprite_cache_size_px""
type = SLE_UINT

@ -29,7 +29,7 @@ public:
const Sprite *GetGlyph(GlyphID) override { return nullptr; }
uint GetGlyphWidth(GlyphID) override { return this->height / 2; }
bool GetDrawGlyphShadow() override { return false; }
GlyphID MapCharToGlyph(char32_t key) override { return key; }
GlyphID MapCharToGlyph(char32_t key, [[maybe_unused]] bool allow_fallback = true) override { return key; }
const void *GetFontTable(uint32_t, size_t &length) override { length = 0; return nullptr; }
std::string GetFontName() override { return "mock"; }
bool IsBuiltInFont() override { return true; }

@ -274,13 +274,15 @@ static void FindResolutions()
{
_resolutions.clear();
for (int i = 0; i < SDL_GetNumDisplayModes(0); i++) {
SDL_DisplayMode mode;
SDL_GetDisplayMode(0, i, &mode);
if (mode.w < 640 || mode.h < 480) continue;
if (std::find(_resolutions.begin(), _resolutions.end(), Dimension(mode.w, mode.h)) != _resolutions.end()) continue;
_resolutions.emplace_back(mode.w, mode.h);
for (int display = 0; display < SDL_GetNumVideoDisplays(); display++) {
for (int i = 0; i < SDL_GetNumDisplayModes(display); i++) {
SDL_DisplayMode mode;
SDL_GetDisplayMode(display, i, &mode);
if (mode.w < 640 || mode.h < 480) continue;
if (std::find(_resolutions.begin(), _resolutions.end(), Dimension(mode.w, mode.h)) != _resolutions.end()) continue;
_resolutions.emplace_back(mode.w, mode.h);
}
}
/* We have found no resolutions, show the default list */
@ -1003,7 +1005,7 @@ bool VideoDriver_SDL_Base::ToggleFullscreen(bool fullscreen)
if (fullscreen) {
/* Find fullscreen window size */
SDL_DisplayMode dm;
if (SDL_GetCurrentDisplayMode(0, &dm) < 0) {
if (SDL_GetCurrentDisplayMode(SDL_GetWindowDisplayIndex(this->sdl_window), &dm) < 0) {
DEBUG(driver, 0, "SDL_GetCurrentDisplayMode() failed: %s", SDL_GetError());
} else {
SDL_SetWindowSize(this->sdl_window, dm.w, dm.h);

@ -25,6 +25,8 @@ enum GameOptionsWidgets : WidgetID {
WID_GO_GUI_SCALE, ///< GUI Scale slider.
WID_GO_GUI_SCALE_AUTO, ///< Autodetect GUI scale button.
WID_GO_GUI_SCALE_BEVEL_BUTTON, ///< Toggle for chunky bevels.
WID_GO_GUI_FONT_SPRITE, ///< Toggle whether to prefer the sprite font over TTF fonts.
WID_GO_GUI_FONT_AA, ///< Toggle whether to anti-alias fonts.
WID_GO_GUI_SCALE_MAIN_TOOLBAR, ///< Toggle for bigger main toolbar.
WID_GO_BASE_GRF_DROPDOWN, ///< Use to select a base GRF.
WID_GO_BASE_GRF_PARAMETERS, ///< Base GRF parameters.

Loading…
Cancel
Save