1
0
Fork 0

Compare commits

...

13 Commits

Author SHA1 Message Date
Peter Nelson 53fa54f8e9
Fix e1f5be62: Clear font cache when toggling sprite font. (#11780)
This is necessary for the sprite font height and ascender to be updated correctly.
2024-01-15 00:21:11 +00:00
Patric Stout 32fc740582
Fix: [SDL2] fullscreen always used the resolution of the first display (#11779) 2024-01-14 22:41:51 +00:00
Patric Stout 302ba93471
Fix: [SDL2] only resolutions of the first display were shown (#11778) 2024-01-14 22:25:54 +00:00
Michael Lutz 994bdff81e Codechange: [CMake] Use timestamps to copy non-generated baseset files. 2024-01-14 22:50:56 +01:00
Michael Lutz e1f5be6244 Add: GUI options to select sprite font and AA mode for all fonts. 2024-01-14 22:50:56 +01:00
Michael Lutz 20f1a0dc57 Fix: [OSX] Spurious log message when a sprite glyph was layouted. 2024-01-14 22:50:56 +01:00
Michael Lutz 36cf6b1d13 Feature: Scalable OpenTTD TrueType font made by Zephyris.
This uses the normal variant for the small font, not the all-caps version.
2024-01-14 22:50:56 +01:00
Michael Lutz 6e766a2e81 Change: Allow TrueType fonts to provide our private-use glyphs. 2024-01-14 22:50:56 +01:00
Loïc Guilloux 37610af0e4
Fix: Don't replace stripped characters with '?' in console (#11777) 2024-01-14 21:49:42 +00:00
Rubidium 564441e822 Remove: Debug redirect over network
It does not work for dedicated servers because upon starting the process to
resolve the address to redirect to gets killed. Also with all the async going
on in the network code, the debug redirection will start very late in the
process.
2024-01-14 22:14:31 +01:00
Peter Nelson a6873ef7dd
Codechange: Avoid repeatedly calling virtual methods in text drawing loop. (#11774) 2024-01-14 19:06:50 +00:00
translators e8d6b496c2 Update: Translations from eints
english (au): 1 change by krysclarke
english (us): 1 change by 2TallTyler
chinese (simplified): 9 changes by WenSimEHRP
korean: 1 change by telk5093
russian: 1 change by Ln-Wolf
finnish: 1 change by hpiirai
danish: 2 changes by bscargo
french: 2 changes by ottdfevr
portuguese: 1 change by azulcosta
2024-01-14 18:39:10 +00:00
Peter Nelson f219557cf2
Codechange: List functions in gui.h under correct source file. (#11775) 2024-01-14 18:12:40 +00:00
43 changed files with 437 additions and 245 deletions

View File

@ -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!

View File

@ -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 ;

View File

@ -18,6 +18,10 @@ set(BASESET_OTHER_SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/opntitle.dat
${CMAKE_CURRENT_SOURCE_DIR}/orig_extra.grf
${CMAKE_CURRENT_SOURCE_DIR}/../openttd.32.bmp
${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
)
# Done by the subdirectories, if nforenum / grfcodec is installed
@ -63,7 +67,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.

View File

@ -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.

View File

@ -106,7 +106,7 @@ void IConsolePrint(TextColour colour_code, const std::string &string)
/* Create a copy of the string, strip it of colours and invalid
* characters and (when applicable) assign it to the console buffer */
std::string str = StrMakeValid(string);
std::string str = StrMakeValid(string, SVS_NONE);
if (_network_dedicated) {
NetworkAdminConsole("console", str);

View File

@ -22,7 +22,6 @@
#include "3rdparty/fmt/chrono.h"
#include "network/network_admin.h"
SOCKET _debug_socket = INVALID_SOCKET;
#include "safeguards.h"
@ -111,18 +110,6 @@ void DumpDebugFacilityNames(std::back_insert_iterator<std::string> &output_itera
*/
void DebugPrint(const char *level, const std::string &message)
{
if (_debug_socket != INVALID_SOCKET) {
std::string msg = fmt::format("{}dbg: [{}] {}\n", GetLogPrefix(), level, message);
/* 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, msg.c_str(), (int)msg.size(), 0);
return;
}
if (strcmp(level, "desync") == 0) {
static FILE *f = FioFOpenFile("commands-out.log", "wb", AUTOSAVE_DIR);
if (f == nullptr) return;

View File

@ -18,6 +18,7 @@
#include "strings_func.h"
#include "viewport_func.h"
#include "window_func.h"
#include "fileio_func.h"
#include "safeguards.h"
@ -95,7 +96,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)
@ -143,13 +144,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.
@ -164,13 +204,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
}
}
}

View File

@ -108,9 +108,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.
@ -217,6 +218,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;

View File

@ -41,7 +41,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 fmt::format("{}, {}", face->family_name, face->style_name); }
bool IsBuiltInFont() override { return false; }
const void *GetOSHandle() override { return &face; }
@ -115,6 +115,42 @@ void FreeTypeFontCache::SetFontSize(FontSize, FT_Face, int pixels)
}
}
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,
@ -157,40 +193,40 @@ void LoadFreeTypeFont(FontSize fs)
if (error != FT_Err_Ok) error = GetFontByFaceName(font_name, &face);
if (error == FT_Err_Ok) {
Debug(fontcache, 2, "Requested '{}', using '{} {}'", 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);
}
}
/**
* 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;
}
Debug(fontcache, 2, "Initialized");
}
FT_Done_Face(face);
ShowInfo("Unable to use '{}' for {} font, FreeType reported error 0x{:X}, using sprite font instead", font_name, FontSizeToName(fs), error);
return;
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);
}
}
@ -276,15 +312,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)

View File

@ -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; }

View File

@ -579,6 +579,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;
@ -592,14 +594,14 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left,
draw_shadow = fc->GetDrawGlyphShadow() && (colour & TC_NO_SHADE) == 0 && colour != 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;
@ -1777,6 +1779,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());
}
/**

View File

@ -254,11 +254,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;
}
}
@ -281,17 +283,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();) {

View File

@ -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);

View File

@ -43,25 +43,38 @@ void ShowHeightmapLoad();
/* misc_gui.cpp */
void ShowLandInfo(TileIndex tile);
void ShowAboutWindow();
void ShowBuildTreesToolbar();
void ShowTownDirectory();
void ShowIndustryDirectory();
void ShowIndustryCargoesWindow();
void ShowSubsidiesList();
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);
/* 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);
/* 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();
/* 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 */

View File

@ -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}

View File

@ -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

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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 키를 누르고 있어도 선로에서 경유지와 역을 제거할 수 있습니다

View File

@ -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}

View File

@ -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}

View File

@ -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})

View File

@ -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

View File

@ -1218,32 +1218,6 @@ static void NetworkGenerateServerId()
_settings_client.network.network_id = GenerateUid("OpenTTD Server ID");
}
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 {} for redirecting Debug()", this->connection_string);
}
void OnConnect(SOCKET s) override
{
Debug(net, 3, "Redirecting Debug() to {}", this->connection_string);
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()
{

View File

@ -47,7 +47,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);

View File

@ -169,7 +169,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
@ -489,7 +488,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)
@ -528,7 +526,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;
@ -565,9 +562,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;
@ -762,10 +756,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;

View File

@ -180,14 +180,10 @@ void CoreTextFontCache::SetFontSize(int pixels)
Debug(fontcache, 2, "Loaded font '{}' with size {}", this->font_name, 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) {
@ -202,6 +198,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;
}
@ -298,6 +298,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
@ -318,33 +352,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 {
ShowInfo("Unable to load file '{}' for {} font, using default OS font selection instead", settings->font, 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) {
@ -372,3 +382,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);
}
}

View File

@ -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 */

View File

@ -168,6 +168,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;
@ -189,10 +192,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());
}
}
@ -242,7 +247,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

View File

@ -282,14 +282,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) {
@ -302,7 +298,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)
@ -320,6 +317,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
@ -344,51 +401,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 *)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, " bold") != nullptr || strcasestr(font_name, "-bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts.
}
} else {
ShowInfo("Unable to load file '{}' for {} 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));
}
}
@ -397,12 +411,25 @@ void LoadWin32Font(FontSize fs)
convert_to_fs(font_name, logfont.lfFaceName, lengthof(logfont.lfFaceName));
}
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, settings->size);
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;
if (TryLoadFontFromFile(file_name, logfont)) {
LoadWin32Font(fs, logfont, size, file_name.c_str());
}
}

View File

@ -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 */

View File

@ -194,9 +194,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]);
}
}
}

View File

@ -50,6 +50,10 @@
#include "safeguards.h"
#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,
@ -559,6 +563,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:
if (ClickSliderWidget(this->GetWidget<NWidgetBase>(widget)->GetCurrentRect(), pt, MIN_INTERFACE_SCALE, MAX_INTERFACE_SCALE, this->gui_scale)) {
if (!_ctrl_pressed) this->gui_scale = ((this->gui_scale + 12) / 25) * 25;
@ -750,6 +779,11 @@ 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->SetWidgetDisabledState(WID_GO_BASE_GRF_DROPDOWN, _game_mode != GM_MENU);
this->SetWidgetDisabledState(WID_GO_BASE_SFX_DROPDOWN, _game_mode != GM_MENU);
@ -823,6 +857,16 @@ static const NWidgetPart _nested_game_options_widgets[] = {
NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_GUI_SCALE_BEVELS, STR_NULL),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_GUI_SCALE_BEVEL_BUTTON), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_GUI_SCALE_BEVELS_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(),

View File

@ -258,6 +258,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

View File

@ -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; }

View File

@ -59,13 +59,15 @@ static void FindResolutions()
{
_resolutions.clear();
for (int i = 0; i < SDL_GetNumDisplayModes(0); i++) {
SDL_DisplayMode mode;
SDL_GetDisplayMode(0, i, &mode);
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);
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 */
@ -663,7 +665,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: {}", SDL_GetError());
} else {
SDL_SetWindowSize(this->sdl_window, dm.w, dm.h);

View File

@ -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_BASE_GRF_DROPDOWN, ///< Use to select a base GRF.
WID_GO_BASE_GRF_PARAMETERS, ///< Base GRF parameters.
WID_GO_BASE_GRF_OPEN_URL, ///< Open base GRF URL.