ALL: Synced with ScummVM - rev: d4db631f9b

This commit is contained in:
Pawel Kolodziejski 2020-09-23 21:52:10 +02:00
parent 3505ece7ed
commit bfe58d3c77
42 changed files with 486 additions and 289 deletions

View file

@ -20,7 +20,7 @@
*
*/
#if defined(POSIX)
#if defined(POSIX) || defined(PSP2)
#define FORBIDDEN_SYMBOL_ALLOW_ALL
@ -43,8 +43,12 @@ AbstractFSNode *DrivesPOSIXFilesystemFactory::makeRootFileNode() const {
}
AbstractFSNode *DrivesPOSIXFilesystemFactory::makeCurrentDirectoryFileNode() const {
#if defined(PSP2) // The Vita does not have getcwd
return makeRootFileNode();
#else
char buf[MAXPATHLEN];
return getcwd(buf, MAXPATHLEN) ? new DrivePOSIXFilesystemNode(buf, _config) : nullptr;
return getcwd(buf, MAXPATHLEN) ? new DrivePOSIXFilesystemNode(buf, _config) : makeRootFileNode();
#endif
}
AbstractFSNode *DrivesPOSIXFilesystemFactory::makeFileNodePath(const Common::String &path) const {

View file

@ -20,7 +20,7 @@
*
*/
#if defined(POSIX)
#if defined(POSIX) || defined(PSP2)
#define FORBIDDEN_SYMBOL_ALLOW_ALL

View file

@ -42,11 +42,9 @@
#include <sys/types.h>
#endif
#ifdef PSP2
#include "backends/fs/psp2/psp2-dirent.h"
#define mkdir sceIoMkdir
#else
#include <dirent.h>
#endif
#include <dirent.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
@ -83,16 +81,6 @@ void POSIXFilesystemNode::setFlags() {
POSIXFilesystemNode::POSIXFilesystemNode(const Common::String &p) {
assert(p.size() > 0);
#ifdef PSP2
if (p == "/") {
_isDirectory = true;
_isValid = false;
_path = p;
_displayName = p;
return;
}
#endif
// Expand "~/" to the value of the HOME env variable
if (p.hasPrefix("~/") || p == "~") {
const char *home = getenv("HOME");
@ -183,15 +171,6 @@ bool POSIXFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, boo
return true;
}
#endif
#ifdef PSP2
if (_path == "/") {
POSIXFilesystemNode *entry1 = new POSIXFilesystemNode("ux0:");
myList.push_back(entry1);
POSIXFilesystemNode *entry2 = new POSIXFilesystemNode("uma0:");
myList.push_back(entry2);
return true;
}
#endif
#if defined(__ANDROID__) && !defined(ANDROIDSDL)
if (_path == "/") {
@ -287,10 +266,6 @@ AbstractFSNode *POSIXFilesystemNode::getParent() const {
// This is a root directory of a drive
return makeNode("/"); // return a virtual root for a list of drives
#endif
#ifdef PSP2
if (_path.hasSuffix(":"))
return makeNode("/");
#endif
const char *start = _path.c_str();
const char *end = start + _path.size();

View file

@ -91,6 +91,7 @@ public:
virtual void showOverlay() = 0;
virtual void hideOverlay() = 0;
virtual bool isOverlayVisible() const = 0;
virtual Graphics::PixelFormat getOverlayFormat() const = 0;
virtual void clearOverlay() = 0;
virtual void grabOverlay(void *buf, int pitch) const = 0;

View file

@ -84,6 +84,7 @@ public:
virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override;
int16 getOverlayWidth() const override;
int16 getOverlayHeight() const override;
virtual bool isOverlayVisible() const override { return _overlayVisible; }
/* Render the passed Surfaces besides the game texture.
* This is used for widescreen support in the Grim engine.

View file

@ -62,6 +62,7 @@ public:
virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override;
virtual int16 getOverlayWidth() const override { return _overlayscreen->w; }
virtual int16 getOverlayHeight() const override { return _overlayscreen->h; }
virtual bool isOverlayVisible() const override { return _overlayVisible; }
/* Render the passed Surfaces besides the game texture.
* This is used for widescreen support in the Grim engine.

View file

@ -77,6 +77,8 @@ public:
_forceRedraw = true;
}
virtual bool isOverlayVisible() const override { return _overlayVisible; }
virtual void setShakePos(int shakeXOffset, int shakeYOffset) override {
if (_gameScreenShakeXOffset != shakeXOffset || _gameScreenShakeYOffset != shakeYOffset) {
_gameScreenShakeXOffset = shakeXOffset;

View file

@ -365,10 +365,12 @@ bool Keymap::areMappingsIdentical(const Array<HardwareInput> &mappingsA, const S
// Assumes array values are not duplicated, but registerMapping and addDefaultInputMapping ensure that
uint foundCount = 0;
uint validDefaultMappings = 0;
for (uint i = 0; i < mappingsB.size(); i++) {
// We resolve the hardware input to make sure it is not a default for some hardware we don't have currently
HardwareInput mappingB = _hardwareInputSet->findHardwareInput(mappingsB[i]);
if (mappingB.type == kHardwareInputTypeInvalid) continue;
validDefaultMappings++;
for (uint j = 0; j < mappingsA.size(); j++) {
if (mappingsA[j].id == mappingB.id) {
@ -378,7 +380,7 @@ bool Keymap::areMappingsIdentical(const Array<HardwareInput> &mappingsA, const S
}
}
return foundCount == mappingsA.size();
return foundCount == mappingsA.size() && foundCount == validDefaultMappings;
}
} // End of namespace Common

View file

@ -106,6 +106,7 @@ public:
* Keymaps with the global type are always enabled
*/
void setEnabledKeymapType(Keymap::KeymapType type);
Keymap::KeymapType enabledKeymapType() const { return _enabledKeymapType; }
/**
* Enable/disable the keymapper
@ -159,6 +160,27 @@ private:
void resetInputState();
};
/**
* RAII helper to temporarily enable a keymap type
*/
class KeymapTypeEnabler {
public:
KeymapTypeEnabler(Keymapper *keymapper, Keymap::KeymapType keymapType) :
_keymapper(keymapper) {
assert(keymapper);
_previousKeymapType = keymapper->enabledKeymapType();
keymapper->setEnabledKeymapType(keymapType);
}
~KeymapTypeEnabler() {
_keymapper->setEnabledKeymapType(_previousKeymapType);
}
private:
Keymapper *_keymapper;
Keymap::KeymapType _previousKeymapType;
};
class DelayedEventSource : public EventSource {
public:
// EventSource API

View file

@ -65,7 +65,7 @@ bool VirtualMouse::pollEvent(Event &event) {
// Adjust the speed of the cursor according to the virtual screen resolution
Common::Rect screenSize;
if (g_gui.isActive()) {
if (g_system->isOverlayVisible()) {
screenSize = Common::Rect(g_system->getOverlayWidth(), g_system->getOverlayHeight());
} else {
screenSize = Common::Rect(g_system->getWidth(), g_system->getHeight());

View file

@ -219,6 +219,10 @@ void ModularGraphicsBackend::hideOverlay() {
_graphicsManager->hideOverlay();
}
bool ModularGraphicsBackend::isOverlayVisible() const {
return _graphicsManager->isOverlayVisible();
}
Graphics::PixelFormat ModularGraphicsBackend::getOverlayFormat() const {
return _graphicsManager->getOverlayFormat();
}

View file

@ -106,6 +106,7 @@ public:
virtual void showOverlay() override final;
virtual void hideOverlay() override final;
virtual bool isOverlayVisible() const override final;
virtual Graphics::PixelFormat getOverlayFormat() const override final;
virtual void clearOverlay() override final;
virtual void grabOverlay(void *buf, int pitch) override final;

View file

@ -26,6 +26,8 @@
#include "backends/vkeybd/virtual-keyboard.h"
#include "backends/keymapper/keymapper.h"
#include "backends/keymapper/keymap.h"
#include "backends/vkeybd/virtual-keyboard-gui.h"
#include "backends/vkeybd/virtual-keyboard-parser.h"
#include "backends/vkeybd/keycode-descriptions.h"
@ -230,7 +232,11 @@ void VirtualKeyboard::show() {
}
switchMode(_initialMode);
_kbdGUI->run();
{
KeymapTypeEnabler guiKeymap(_system->getEventManager()->getKeymapper(), Keymap::kKeymapTypeGui);
_kbdGUI->run();
}
if (_submitKeys) {
EventManager *eventMan = _system->getEventManager();

View file

@ -159,7 +159,9 @@ PluginList FilePluginProvider::getPlugins() {
Common::FSList pluginDirs;
// Add the default directories
#ifndef WIN32
pluginDirs.push_back(Common::FSNode("."));
#endif
pluginDirs.push_back(Common::FSNode("plugins"));
// Add the provider's custom directories

View file

@ -116,15 +116,20 @@ String MacResManager::computeResForkMD5AsString(uint32 length) const {
}
bool MacResManager::open(const String &fileName) {
return open(fileName, SearchMan);
}
bool MacResManager::open(const String &fileName, Archive &archive) {
close();
#ifdef MACOSX
// Check the actual fork on a Mac computer
String fullPath = ConfMan.get("path") + "/" + fileName + "/..namedfork/rsrc";
FSNode resFsNode = FSNode(fullPath);
if (resFsNode.exists()) {
const ArchiveMemberPtr archiveMember = archive.getMember(fileName);
const Common::FSNode *plainFsNode = dynamic_cast<const Common::FSNode *>(archiveMember.get());
if (plainFsNode) {
String fullPath = plainFsNode->getPath() + "/..namedfork/rsrc";
FSNode resFsNode = FSNode(fullPath);
SeekableReadStream *macResForkRawStream = resFsNode.createReadStream();
if (macResForkRawStream && loadFromRawFork(*macResForkRawStream)) {
_baseFileName = fileName;
return true;
@ -134,111 +139,37 @@ bool MacResManager::open(const String &fileName) {
}
#endif
File *file = new File();
// Prefer standalone files first, starting with raw forks
if (file->open(fileName + ".rsrc") && loadFromRawFork(*file)) {
SeekableReadStream *stream = archive.createReadStreamForMember(fileName + ".rsrc");
if (stream && loadFromRawFork(*stream)) {
_baseFileName = fileName;
return true;
}
file->close();
delete stream;
// Then try for AppleDouble using Apple's naming
if (file->open(constructAppleDoubleName(fileName)) && loadFromAppleDouble(*file)) {
stream = archive.createReadStreamForMember(constructAppleDoubleName(fileName));
if (stream && loadFromAppleDouble(*stream)) {
_baseFileName = fileName;
return true;
}
file->close();
delete stream;
// Check .bin for MacBinary next
if (file->open(fileName + ".bin") && loadFromMacBinary(*file)) {
stream = archive.createReadStreamForMember(fileName + ".bin");
if (stream && loadFromMacBinary(*stream)) {
_baseFileName = fileName;
return true;
}
file->close();
delete stream;
// As a last resort, see if just the data fork exists
if (file->open(fileName)) {
stream = archive.createReadStreamForMember(fileName);
if (stream) {
_baseFileName = fileName;
// Maybe file is in MacBinary but without .bin extension?
// Check it here
if (isMacBinary(*file)) {
file->seek(0);
if (loadFromMacBinary(*file))
return true;
}
file->seek(0);
_stream = file;
return true;
}
delete file;
// The file doesn't exist
return false;
}
bool MacResManager::open(const FSNode &path, const String &fileName) {
close();
#ifdef MACOSX
// Check the actual fork on a Mac computer
String fullPath = path.getPath() + "/" + fileName + "/..namedfork/rsrc";
FSNode resFsNode = FSNode(fullPath);
if (resFsNode.exists()) {
SeekableReadStream *macResForkRawStream = resFsNode.createReadStream();
if (macResForkRawStream && loadFromRawFork(*macResForkRawStream)) {
_baseFileName = fileName;
return true;
}
delete macResForkRawStream;
}
#endif
// Prefer standalone files first, starting with raw forks
FSNode fsNode = path.getChild(fileName + ".rsrc");
if (fsNode.exists() && !fsNode.isDirectory()) {
SeekableReadStream *stream = fsNode.createReadStream();
if (loadFromRawFork(*stream)) {
_baseFileName = fileName;
return true;
}
delete stream;
}
// Then try for AppleDouble using Apple's naming
fsNode = path.getChild(constructAppleDoubleName(fileName));
if (fsNode.exists() && !fsNode.isDirectory()) {
SeekableReadStream *stream = fsNode.createReadStream();
if (loadFromAppleDouble(*stream)) {
_baseFileName = fileName;
return true;
}
delete stream;
}
// Check .bin for MacBinary next
fsNode = path.getChild(fileName + ".bin");
if (fsNode.exists() && !fsNode.isDirectory()) {
SeekableReadStream *stream = fsNode.createReadStream();
if (loadFromMacBinary(*stream)) {
_baseFileName = fileName;
return true;
}
delete stream;
}
// As a last resort, see if just the data fork exists
fsNode = path.getChild(fileName);
if (fsNode.exists() && !fsNode.isDirectory()) {
SeekableReadStream *stream = fsNode.createReadStream();
_baseFileName = fileName;
// FIXME: Is this really needed?
if (isMacBinary(*stream)) {
stream->seek(0);
if (loadFromMacBinary(*stream))

View file

@ -68,14 +68,14 @@ public:
bool open(const String &fileName);
/**
* Open a Mac data/resource fork pair.
* Open a Mac data/resource fork pair from within the given archive.
*
* @param path The path that holds the forks
* @param fileName The base file name of the file
* @note This will check for the raw resource fork, MacBinary, and AppleDouble formats.
* @return True on success
*/
bool open(const FSNode &path, const String &fileName);
bool open(const String &fileName, Archive &archive);
/**
* See if a Mac data/resource fork pair exists.

View file

@ -59,6 +59,7 @@ const PlatformDescription g_platforms[] = {
{ "os2", "os2", "os2", "OS/2", kPlatformOS2 },
{ "beos", "beos", "beos", "BeOS", kPlatformBeOS },
{ "ppc", "ppc", "ppc", "PocketPC", kPlatformPocketPC },
{ "megadrive", "genesis", "md", "Mega Drive/Genesis", kPlatformMegaDrive },
{ nullptr, nullptr, nullptr, "Default", kPlatformUnknown }
};

View file

@ -64,6 +64,7 @@ enum Platform {
kPlatformOS2,
kPlatformBeOS,
kPlatformPocketPC,
kPlatformMegaDrive,
kPlatformUnknown = -1
};

View file

@ -1134,6 +1134,9 @@ public:
/** Deactivate the overlay mode. */
virtual void hideOverlay() = 0;
/** Returns true if the overlay mode is activated, false otherwise. */
virtual bool isOverlayVisible() const = 0;
/**
* Returns the pixel format description of the overlay.
* @see Graphics::PixelFormat

View file

@ -169,7 +169,7 @@ bool XMLParser::parseActiveKey(bool closed) {
if (layout->children.contains(key->name)) {
key->layout = layout->children[key->name];
StringMap localMap = key->values;
const StringMap &localMap = key->values;
int keyCount = localMap.size();
for (List<XMLKeyLayout::XMLKeyProperty>::const_iterator i = key->layout->properties.begin(); i != key->layout->properties.end(); ++i) {

61
configure vendored
View file

@ -219,6 +219,7 @@ _nasm=auto
_optimization_level=
_default_optimization_level=-O2
_nuked_opl=no
_builtin_resources=yes
# Default commands
_ranlib=ranlib
_strip=strip
@ -1032,6 +1033,8 @@ Optional Features:
--enable-tts build support for text to speech
--disable-tts don't build support for text to speech
--disable-bink don't build with Bink video support
--no-builtin-resources do not include additional resources (e.g. engine data, fonts)
into the ResidualVM binary
Optional Libraries:
--with-alsa-prefix=DIR prefix where alsa is installed (optional)
@ -1474,6 +1477,9 @@ for ac_option in $@; do
--enable-tsan)
_enable_tsan=yes
;;
--no-builtin-resources)
_builtin_resources=no
;;
--with-sdl-prefix=*)
arg=`echo $ac_option | cut -d '=' -f 2`
_sdlpath="$arg:$arg/bin"
@ -2555,6 +2561,9 @@ case $_host_os in
append_var LIBS "-lcitro3d"
;;
amigaos*)
if test "$_debug_build" = no; then
_optimization_level=-O2
fi
append_var LDFLAGS "-Wl,--export-dynamic"
append_var LDFLAGS "-L/sdk/local/newlib/lib"
# We have to use 'long' for our 4 byte typedef because AmigaOS already typedefs (u)int32
@ -2566,24 +2575,6 @@ case $_host_os in
_port_mk="backends/platform/sdl/amigaos/amigaos.mk"
_nuked_opl=no
;;
morphos*)
if test "$_debug_build" = no; then
_optimization_level=-O2
fi
append_var LDFLAGS "-Wl,--export-dynamic"
append_var LDFLAGS "-L/usr/local/lib"
append_var CXXFLAGS "-D__MORPHOS_SHAREDLIBS"
# We have to use 'long' for our 4 byte typedef because MorphOS already typedefs (u)int32
# as (unsigned) long, and consequently we'd get a compiler error otherwise.
type_4_byte='long'
# Supress format warnings as the long 4 byte causes noisy warnings.
append_var CXXFLAGS "-Wno-format"
add_line_to_config_mk 'MORPHOS = 1'
_port_mk="backends/platform/sdl/morphos/morphos.mk"
# for use SDL2
_sdlconfig=sdl2-config
_nuked_opl=no
;;
android)
case $_host in
android-arm-v7a)
@ -2647,10 +2638,13 @@ case $_host_os in
# which will allow for calls larger than 32MB. The linker
# will discard the calls if they are not needed, but we
# need to ensure the compiler emits them in the first place.
# Also the executable has grown to a size where using -Os is necessary to avoid a
# 'virtual memory exhausted' error when running the executable.
case $_host_cpu in
powerpc*)
append_var CFLAGS "-mlongcall"
append_var CXXFLAGS "-mlongcall"
_optimization_level=-Os
;;
esac
@ -2863,7 +2857,7 @@ EOF
append_var LIBS "-specs=ds_arm9.specs"
append_var LIBS "-lnds9"
;;
freebsd*)
freebsd* | openbsd*)
append_var LDFLAGS "-L/usr/local/lib"
append_var CXXFLAGS "-I/usr/local/include"
;;
@ -2923,6 +2917,24 @@ EOF
append_var DEFINES "-D_GNU_SOURCE"
append_var DEFINES "-D_ISOC11_SOURCE"
;;
morphos*)
if test "$_debug_build" = no; then
_optimization_level=-O2
fi
append_var LDFLAGS "-Wl,--export-dynamic"
append_var LDFLAGS "-L/usr/local/lib"
append_var CXXFLAGS "-D__MORPHOS_SHAREDLIBS"
# We have to use 'long' for our 4 byte typedef because MorphOS already typedefs (u)int32
# as (unsigned) long, and consequently we'd get a compiler error otherwise.
type_4_byte='long'
# Supress format warnings as the long 4 byte causes noisy warnings.
append_var CXXFLAGS "-Wno-format"
add_line_to_config_mk 'MORPHOS = 1'
_port_mk="backends/platform/sdl/morphos/morphos.mk"
# for use SDL2
_sdlconfig=sdl2-config
_nuked_opl=no
;;
msys)
echo ERROR: Using the MSYS shell in msys mode is not supported. Please use the MSYS shell in mingw mode instead.
exit 1
@ -3975,7 +3987,7 @@ _mak_plugins='
PLUGIN_LDFLAGS += -Wl,-T$(srcdir)/backends/plugins/ds/plugin.ld -mthumb-interwork -mfloat-abi=soft
'
;;
freebsd*)
freebsd* | openbsd*)
_plugin_prefix="lib"
_plugin_suffix=".so"
append_var CXXFLAGS "-fPIC"
@ -4164,7 +4176,7 @@ int main(void) { return 0; }
EOF
cc_check -lsapi -lole32 && _tts=yes
;;
linux* | freebsd*)
linux* | freebsd* | openbsd*)
cat > $TMPC << EOF
#include <speech-dispatcher/libspeechd.h>
int main(void) { return 0; }
@ -5614,7 +5626,7 @@ if test "$_tts" = "no"; then
echo "no"
else
case $_host_os in
linux* | freebsd*)
linux* | freebsd* | openbsd*)
echo "speech dispatcher"
_tts=yes
define_in_config_if_yes $_tts 'USE_SPEECH_DISPATCHER'
@ -5660,6 +5672,11 @@ else
fi
define_in_config_if_yes $_updates 'USE_UPDATES'
#
# Check whether to create a build with all resources files linked into the binary
#
define_in_config_if_yes "$_builtin_resources" 'BUILTIN_RESOURCES'
#
# Check whether to activate engines (ResidualVM specific)
#

View file

@ -122,6 +122,12 @@ int main(int argc, char *argv[]) {
}
}
if (!numLangs) {
fprintf(stderr, "ERROR: No valid translation files\n");
fprintf(stderr, "usage: create_translations lang1.po [lang2.po ...]\n");
return -1;
}
for (int i = 0; i < numLangs; i++) {
if (!translations[i]->useUTF8()) {
fprintf(stderr, "ERROR: Po Language file for: \"%s\", named as \"%s\" is not encoded in UTF-8\n", translations[i]->languageName(), translations[i]->language());

View file

@ -14,8 +14,9 @@ Mode 1:
Operate in MacBinary encoding mode
Mode 2:
$0 <file.iso>
$0 [jap] <file.iso>
Operate in disk dumping mode
Optionally specify 'jap' for using 'recode' for converting Japanese file names
Miscellaneous:
-h, --help display this help and exit
@ -23,6 +24,7 @@ EOF
}
path=
jap=
macbinarydump() {
mypath=`realpath $0`
@ -45,31 +47,52 @@ macbinarydump() {
}
hfsdump() {
IFS=$'\n'
mypath=`realpath $0`
for i in `hls -F1a`
do
if [[ jap == "jap" ]] ; then
flist=`hls -F1a|recode SJIS..utf-8`
else
flist=`hls -F1a`
fi
echo "$flist" | while read i ; do
if [[ jap == "jap" ]] ; then
macname=`echo "$i"|recode utf-8..SJIS`
else
macname="$i"
fi
# Guard empty directories
if [[ "$i" == "" ]] ; then
continue
fi
if [[ "$i" =~ ":" ]] ; then
dir="${i%?}"
hcd "$dir"
mkdir "$dir"
cd "$dir"
bash $mypath hfsutils-phase2 "$path:$i"
dir="${i%?}" # Strip trailing ':'
dir="${dir//\//:}" # Files could contain '/', replace those with ':'
macdir="${macname%?}"
hcd "$macdir"
mkdir -- "$dir"
cd -- "$dir"
bash $mypath $jap hfsutils-phase2 "$path:$i"
hcd ::
cd ..
else
echo -ne "$path$i... \r"
# Executable files have star at their end. Strip it
if [[ "$i" =~ \*$ ]] ; then
macfile="${macname%?}"
file="${i%?}"
else
macfile="$macname"
file="$i"
fi
fileunix="$file"
# Files count contain stars
file="${file//\*/\\*}"
hcopy -m "$file" "./$fileunix"
fileunix="${file//\//:}" # Files could contain '/', replace those with ':'
# Files could contain '*', '{', so backslash them to avoid globbing
macfile="${macfile//\*/\\*}"
macfile="${macfile//{/\\{}"
hcopy -m -- "$macfile" "./$fileunix"
fi
done
}
@ -82,7 +105,7 @@ for parm in "$@" ; do
done # for parm in ...
if [[ $1 == "macbinary" ]] ; then
if test ! `type macbinary >/dev/null 2>/dev/null` ; then
if ! `command -v macbinary >/dev/null 2>/dev/null` ; then
echo "macbinary not found. Exiting"
exit 1
fi
@ -104,6 +127,16 @@ if [ "$#" -lt 1 ] ; then
exit 1
fi
if [[ $1 == "jap" ]] ; then
if ! `command -v recode >/dev/null 2>/dev/null` ; then
echo "recode not found. Exiting"
exit 1
fi
jap=jap
shift
fi
if [[ $1 == "hfsutils-phase2" ]] ; then
path=$2
hfsdump

Binary file not shown.

View file

@ -35,6 +35,45 @@
#include "engines/advancedDetector.h"
#include "engines/obsolete.h"
/**
* Adapter to be able to use Common::Archive based code from the AD.
*/
class FileMapArchive : public Common::Archive {
public:
FileMapArchive(const AdvancedMetaEngine::FileMap &fileMap) : _fileMap(fileMap) {}
bool hasFile(const Common::String &name) const override {
return _fileMap.contains(name);
}
int listMembers(Common::ArchiveMemberList &list) const override {
int files = 0;
for (AdvancedMetaEngine::FileMap::const_iterator it = _fileMap.begin(); it != _fileMap.end(); ++it) {
list.push_back(Common::ArchiveMemberPtr(new Common::FSNode(it->_value)));
++files;
}
return files;
}
const Common::ArchiveMemberPtr getMember(const Common::String &name) const override {
AdvancedMetaEngine::FileMap::const_iterator it = _fileMap.find(name);
if (it == _fileMap.end()) {
return Common::ArchiveMemberPtr();
}
return Common::ArchiveMemberPtr(new Common::FSNode(it->_value));
}
Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override {
Common::FSNode fsNode = _fileMap[name];
return fsNode.createReadStream();
}
private:
const AdvancedMetaEngine::FileMap &_fileMap;
};
static Common::String sanitizeName(const char *name) {
Common::String res;
@ -355,14 +394,16 @@ void AdvancedMetaEngine::composeFileHashMap(FileMap &allFiles, const Common::FSL
}
}
bool AdvancedMetaEngine::getFileProperties(const Common::FSNode &parent, const FileMap &allFiles, const ADGameDescription &game, const Common::String fname, FileProperties &fileProps) const {
bool AdvancedMetaEngine::getFileProperties(const FileMap &allFiles, const ADGameDescription &game, const Common::String fname, FileProperties &fileProps) const {
// FIXME/TODO: We don't handle the case that a file is listed as a regular
// file and as one with resource fork.
if (game.flags & ADGF_MACRESFORK) {
FileMapArchive fileMapArchive(allFiles);
Common::MacResManager macResMan;
if (!macResMan.open(parent, fname))
if (!macResMan.open(fname, fileMapArchive))
return false;
fileProps.md5 = macResMan.computeResForkMD5AsString(_md5Bytes);
@ -407,7 +448,7 @@ ADDetectedGames AdvancedMetaEngine::detectGame(const Common::FSNode &parent, con
continue;
FileProperties tmp;
if (getFileProperties(parent, allFiles, *g, fname, tmp)) {
if (getFileProperties(allFiles, *g, fname, tmp)) {
debug(3, "> '%s': '%s'", fname.c_str(), tmp.md5.c_str());
}
@ -510,7 +551,7 @@ ADDetectedGames AdvancedMetaEngine::detectGame(const Common::FSNode &parent, con
return matched;
}
ADDetectedGame AdvancedMetaEngine::detectGameFilebased(const FileMap &allFiles, const Common::FSList &fslist, const ADFileBasedFallback *fileBasedFallback) const {
ADDetectedGame AdvancedMetaEngine::detectGameFilebased(const FileMap &allFiles, const ADFileBasedFallback *fileBasedFallback) const {
const ADFileBasedFallback *ptr;
const char* const* filenames;
@ -546,7 +587,7 @@ ADDetectedGame AdvancedMetaEngine::detectGameFilebased(const FileMap &allFiles,
for (filenames = ptr->filenames; *filenames; ++filenames) {
FileProperties tmp;
if (getFileProperties(fslist.begin()->getParent(), allFiles, *agdesc, *filenames, tmp))
if (getFileProperties(allFiles, *agdesc, *filenames, tmp))
game.matchedFiles[*filenames] = tmp;
}

View file

@ -305,7 +305,7 @@ protected:
* @param fileBasedFallback a list of ADFileBasedFallback records, zero-terminated
* @param filesProps if not 0, return a map of properties for all detected files here
*/
ADDetectedGame detectGameFilebased(const FileMap &allFiles, const Common::FSList &fslist, const ADFileBasedFallback *fileBasedFallback) const;
ADDetectedGame detectGameFilebased(const FileMap &allFiles, const ADFileBasedFallback *fileBasedFallback) const;
/**
* Compose a hashmap of all files in fslist.
@ -314,10 +314,12 @@ protected:
void composeFileHashMap(FileMap &allFiles, const Common::FSList &fslist, int depth, const Common::String &parentName = Common::String()) const;
/** Get the properties (size and MD5) of this file. */
bool getFileProperties(const Common::FSNode &parent, const FileMap &allFiles, const ADGameDescription &game, const Common::String fname, FileProperties &fileProps) const;
bool getFileProperties(const FileMap &allFiles, const ADGameDescription &game, const Common::String fname, FileProperties &fileProps) const;
/** Convert an AD game description into the shared game description format */
virtual DetectedGame toDetectedGame(const ADDetectedGame &adGame) const;
friend class FileMapArchive; // for FileMap
};
#endif

View file

@ -37,20 +37,16 @@
#include "graphics/managed_surface.h"
#include "graphics/thumbnail.h"
const char *MetaEngine::getSavegameFile(int saveGameIdx, const char *target) const {
static char buffer[200];
snprintf(buffer, sizeof(buffer), "%s.s%02d", target == nullptr ? getEngineId() : target, saveGameIdx);
return buffer;
}
const char *MetaEngine::getSavegamePattern(const char *target) const {
static char buffer[200];
snprintf(buffer, sizeof(buffer), "%s.s##", target == nullptr ? getEngineId() : target);
return buffer;
Common::String MetaEngine::getSavegameFile(int saveGameIdx, const char *target) const {
if (saveGameIdx == kSavegameFilePattern) {
// Pattern requested
const char *pattern = hasFeature(kSavesUseExtendedFormat) ? "%s.###" : "%s.s##";
return Common::String::format(pattern, target == nullptr ? getEngineId() : target);
} else {
// Specific filename requested
const char *pattern = hasFeature(kSavesUseExtendedFormat) ? "%s.%03d" : "%s.s%02d";
return Common::String::format(pattern, target == nullptr ? getEngineId() : target, saveGameIdx);
}
}
Common::KeymapArray MetaEngine::initKeymaps(const char *target) const {
@ -274,7 +270,7 @@ SaveStateList MetaEngine::listSaves(const char *target) const {
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
Common::StringArray filenames;
Common::String pattern(getSavegamePattern(target));
Common::String pattern(getSavegameFilePattern(target));
filenames = saveFileMan->listSavefiles(pattern);

View file

@ -67,6 +67,8 @@ struct ExtraGuiOption {
typedef Common::Array<ExtraGuiOption> ExtraGuiOptions;
enum { kSavegameFilePattern = -99 };
#define EXTENDED_SAVE_VERSION 4
struct ExtendedSavegameHeader {
@ -244,7 +246,8 @@ public:
* @return maximum save slot number supported
*/
virtual int getMaximumSaveSlot() const {
return 0;
// For games using the new save format, assume 99 slots by default
return hasFeature(kSavesUseExtendedFormat) ? 99 : 0;
}
/**
@ -273,19 +276,23 @@ public:
virtual SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
/**
* Returns name of the save file for given slot and optional target.
* Returns name of the save file for given slot and optional target,
* or a pattern for matching filenames against
*
* @param saveGameIdx index of the save
* @param saveGameIdx index of the save, or kSavegameFilePattern
* for returning a filename pattern
* @param target game target. If omitted, then the engine id is used
*/
virtual const char *getSavegameFile(int saveGameIdx, const char *target = nullptr) const;
virtual Common::String getSavegameFile(int saveGameIdx, const char *target = nullptr) const;
/**
* Returns pattern for save files.
*
* @param target game target. If omitted, then the engine id is used
*/
virtual const char *getSavegamePattern(const char *target = nullptr) const;
Common::String getSavegameFilePattern(const char *target = nullptr) const {
return getSavegameFile(kSavegameFilePattern, target);
}
/**
* Return the keymap used by the target.

View file

@ -29,6 +29,25 @@ namespace Graphics {
// TODO: YUV to RGB conversion function
// Function to blit a rect
void copyBlit(byte *dst, const byte *src,
const uint dstPitch, const uint srcPitch,
const uint w, const uint h,
const uint bytesPerPixel) {
if (dst == src)
return;
if (dstPitch == srcPitch && ((w * bytesPerPixel) == dstPitch)) {
memcpy(dst, src, dstPitch * h);
} else {
for (uint i = 0; i < h; ++i) {
memcpy(dst, src, w * bytesPerPixel);
dst += dstPitch;
src += srcPitch;
}
}
}
namespace {
template<typename SrcColor, typename DstColor, bool backward>
@ -111,18 +130,7 @@ bool crossBlit(byte *dst, const byte *src,
// Don't perform unnecessary conversion
if (srcFmt == dstFmt) {
if (dst != src) {
if (dstPitch == srcPitch && ((w * dstFmt.bytesPerPixel) == dstPitch)) {
memcpy(dst, src, dstPitch * h);
} else {
for (uint i = 0; i < h; ++i) {
memcpy(dst, src, w * dstFmt.bytesPerPixel);
dst += dstPitch;
src += srcPitch;
}
}
}
copyBlit(dst, src, dstPitch, srcPitch, w, h, dstFmt.bytesPerPixel);
return true;
}

View file

@ -45,6 +45,22 @@ inline static void RGB2YUV(byte r, byte g, byte b, byte &y, byte &u, byte &v) {
// TODO: generic YUV to RGB blit
/**
* Blits a rectangle.
*
* @param dst the buffer which will recieve the converted graphics data
* @param src the buffer containing the original graphics data
* @param dstPitch width in bytes of one full line of the dest buffer
* @param srcPitch width in bytes of one full line of the source buffer
* @param w the width of the graphics data
* @param h the height of the graphics data
* @param bytesPerPixel the number of bytes per pixel
*/
void copyBlit(byte *dst, const byte *src,
const uint dstPitch, const uint srcPitch,
const uint w, const uint h,
const uint bytesPerPixel);
/**
* Blits a rectangle from one graphical format to another.
*

View file

@ -28,6 +28,7 @@
#include "common/tokenizer.h"
#include "common/translation.h"
#include "graphics/conversion.h"
#include "graphics/cursorman.h"
#include "graphics/fontman.h"
#include "graphics/surface.h"
@ -224,7 +225,11 @@ ThemeEngine::ThemeEngine(Common::String id, GraphicsMode mode) :
_cursorHotspotX = _cursorHotspotY = 0;
_cursorWidth = _cursorHeight = 0;
#ifndef USE_RGB_COLOR
_cursorFormat = Graphics::PixelFormat::createFormatCLUT8();
_cursorTransparent = 255;
_cursorPalSize = 0;
#endif
// We prefer files in archive bundles over the common search paths.
_themeFiles.add("default", &SearchMan, 0, false);
@ -398,8 +403,10 @@ void ThemeEngine::refresh() {
_system->showOverlay();
if (_useCursor) {
#ifndef USE_RGB_COLOR
CursorMan.replaceCursorPalette(_cursorPal, 0, _cursorPalSize);
CursorMan.replaceCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, true);
#endif
CursorMan.replaceCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, _cursorTransparent, true, &_cursorFormat);
}
}
}
@ -518,10 +525,23 @@ bool ThemeEngine::addTextData(const Common::String &drawDataId, TextData textId,
return true;
}
bool ThemeEngine::addFont(TextData textId, const Common::String &file, const Common::String &scalableFile, const int pointsize) {
bool ThemeEngine::addFont(TextData textId, const Common::String &language, const Common::String &file, const Common::String &scalableFile, const int pointsize) {
if (textId == -1)
return false;
if (!language.empty() && !language.equals("*")) {
#ifdef USE_TRANSLATION
Common::String cl = TransMan.getCurrentLanguage();
if (!cl.matchString(language, true))
return true; // Skip
if (_texts[textId] != nullptr) // We already loaded something
return true;
#else
return true; // Safely ignore
#endif
}
if (_texts[textId] != nullptr)
delete _texts[textId];
@ -1481,20 +1501,11 @@ void ThemeEngine::applyScreenShading(ShadingStyle style) {
}
bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int hotspotY) {
if (!_system->hasFeature(OSystem::kFeatureCursorPalette))
return true;
// Try to locate the specified file among all loaded bitmaps
const Graphics::Surface *cursor = _bitmaps[filename];
if (!cursor)
return false;
#ifdef USE_RGB_COLOR
_cursorFormat.bytesPerPixel = 1;
_cursorFormat.rLoss = _cursorFormat.gLoss = _cursorFormat.bLoss = _cursorFormat.aLoss = 8;
_cursorFormat.rShift = _cursorFormat.gShift = _cursorFormat.bShift = _cursorFormat.aShift = 0;
#endif
// Set up the cursor parameters
_cursorHotspotX = hotspotX;
_cursorHotspotY = hotspotY;
@ -1502,6 +1513,23 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int
_cursorWidth = cursor->w;
_cursorHeight = cursor->h;
#ifdef USE_RGB_COLOR
_cursorFormat = cursor->format;
_cursorTransparent = _cursorFormat.RGBToColor(0xFF, 0, 0xFF);
// Allocate a new buffer for the cursor
delete[] _cursor;
_cursor = new byte[_cursorWidth * _cursorHeight * _cursorFormat.bytesPerPixel];
assert(_cursor);
Graphics::copyBlit(_cursor, (const byte *)cursor->getPixels(),
_cursorWidth * _cursorFormat.bytesPerPixel, cursor->pitch,
_cursorWidth, _cursorHeight, _cursorFormat.bytesPerPixel);
_useCursor = true;
#else
if (!_system->hasFeature(OSystem::kFeatureCursorPalette))
return true;
// Allocate a new buffer for the cursor
delete[] _cursor;
_cursor = new byte[_cursorWidth * _cursorHeight];
@ -1559,6 +1587,7 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int
_useCursor = true;
_cursorPalSize = colorsFound;
#endif
return true;
}
@ -2008,15 +2037,19 @@ Common::String ThemeEngine::getThemeId(const Common::String &filename) {
void ThemeEngine::showCursor() {
if (_useCursor) {
#ifndef USE_RGB_COLOR
CursorMan.pushCursorPalette(_cursorPal, 0, _cursorPalSize);
CursorMan.pushCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, true);
#endif
CursorMan.pushCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, _cursorTransparent, true, &_cursorFormat);
CursorMan.showMouse(true);
}
}
void ThemeEngine::hideCursor() {
if (_useCursor) {
#ifndef USE_RGB_COLOR
CursorMan.popCursorPalette();
#endif
CursorMan.popCursor();
}
}

View file

@ -37,7 +37,7 @@
#include "graphics/pixelformat.h"
#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.38"
#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.39"
class OSystem;
@ -513,11 +513,12 @@ public:
* filename.
*
* @param textId Identifier name for the font.
* @param language Wildcard for the language(s) to use.
* @param file Filename of the non-scalable font version.
* @param scalableFile Filename of the scalable version. (Optional)
* @param pointsize Point size for the scalable font. (Optional)
*/
bool addFont(TextData textId, const Common::String &file, const Common::String &scalableFile, const int pointsize);
bool addFont(TextData textId, const Common::String &language, const Common::String &file, const Common::String &scalableFile, const int pointsize);
/**
* Interface for the ThemeParser class: adds a text color value.
@ -743,9 +744,7 @@ protected:
ImagesMap _bitmaps;
AImagesMap _abitmaps;
Graphics::PixelFormat _overlayFormat;
#ifdef USE_RGB_COLOR
Graphics::PixelFormat _cursorFormat;
#endif
/** List of all the dirty screens that must be blitted to the overlay. */
Common::List<Common::Rect> _dirtyScreen;
@ -762,13 +761,16 @@ protected:
bool _useCursor;
int _cursorHotspotX, _cursorHotspotY;
uint32 _cursorTransparent;
byte *_cursor;
uint _cursorWidth, _cursorHeight;
#ifndef USE_RGB_COLOR
enum {
MAX_CURS_COLORS = 255
};
byte *_cursor;
uint _cursorWidth, _cursorHeight;
byte _cursorPal[3 * MAX_CURS_COLORS];
byte _cursorPalSize;
#endif
Common::Rect _clip;
};

View file

@ -179,16 +179,51 @@ bool ThemeParser::parserCallback_font(ParserNode *node) {
return true;
}
// Default to a point size of 12.
int pointsize = 12;
if (node->values.contains("point_size")) {
if (sscanf(node->values["point_size"].c_str(), "%d", &pointsize) != 1 || pointsize <= 0)
return parserError(Common::String::format("Font \"%s\" has invalid point size \"%s\"", node->values["id"].c_str(), node->values["point_size"].c_str()));
return true;
}
bool ThemeParser::parserCallback_language(ParserNode *node) {
if (resolutionCheck(node->values["resolution"]) == false) {
node->ignore = true;
return true;
}
TextData textDataId = parseTextDataId(node->values["id"]);
if (!_theme->addFont(textDataId, node->values["file"], node->values["scalable_file"], pointsize))
return parserError("Error loading Font in theme engine.");
TextData textDataId = parseTextDataId(getParentNode(node)->values["id"]);
// Default to a point size of 12.
int pointsize = 12;
Common::String ps;
if (node->values.contains("point_size")) {
ps = node->values["point_size"];
} else if (getParentNode(node)->values.contains("point_size")) {
ps = getParentNode(node)->values["point_size"];
}
if (!ps.empty()) {
if (sscanf(ps.c_str(), "%d", &pointsize) != 1 || pointsize <= 0)
return parserError(Common::String::format("Font \"%s\" has invalid point size \"%s\"", node->values["id"].c_str(), ps.c_str()));
}
Common::String file;
if (node->values.contains("file")) {
file = node->values["file"];
} else if (getParentNode(node)->values.contains("file")) {
file = getParentNode(node)->values["file"];
}
if (file.empty()) {
return parserError("Missing required property 'file' in either <font> or <language>");
}
Common::String scalableFile;
if (node->values.contains("scalable_file")) {
scalableFile = node->values["scalable_file"];
} else if (getParentNode(node)->values.contains("scalable_file")) {
scalableFile = getParentNode(node)->values["scalable_file"];
}
if (!_theme->addFont(textDataId, node->values["id"], file, scalableFile, pointsize))
return parserError("Error loading localized Font in theme engine.");
return true;
}

View file

@ -63,10 +63,16 @@ protected:
XML_KEY(fonts)
XML_KEY(font)
XML_PROP(id, true)
XML_PROP(file, true)
XML_PROP(file, false)
XML_PROP(resolution, false)
XML_PROP(scalable_file, false)
XML_PROP(point_size, false)
XML_KEY(language)
XML_PROP(id, true)
XML_PROP(file, false)
XML_PROP(scalable_file, false)
XML_PROP(point_size, false)
KEY_END()
KEY_END()
XML_KEY(text_color)
@ -224,6 +230,7 @@ protected:
bool parserCallback_font(ParserNode *node);
bool parserCallback_text_color(ParserNode *node);
bool parserCallback_fonts(ParserNode *node);
bool parserCallback_language(ParserNode *node);
bool parserCallback_text(ParserNode *node);
bool parserCallback_palette(ParserNode *node);
bool parserCallback_color(ParserNode *node);

View file

@ -449,6 +449,11 @@ void GuiManager::runLoop() {
#endif
}
void GuiManager::exitLoop() {
while (!_dialogStack.empty())
getTopDialog()->close();
}
#pragma mark -
void GuiManager::saveState() {

View file

@ -75,6 +75,11 @@ public:
// until no dialogs are active anymore.
void runLoop();
// If the GUI loop is running close all the dialogs causing the loop to finish.
// Typically you may want to use it after setting the ConfMan active domain to
// a game domain to cause the game to start.
void exitLoop();
void processEvent(const Common::Event &event, Dialog *const activeDialog);
Common::Keymap *getKeymap() const;
void scheduleTopDialogRedraw();

View file

@ -2459,12 +2459,12 @@ void GlobalOptionsDialog::apply() {
else {
ttsMan->setLanguage(newLang);
}
_ttsVoiceSelectionPopUp->setSelected(0);
}
#else
ttsMan->setLanguage("en");
#endif // USE_TRANSLATION
_ttsVoiceSelectionPopUp->setSelected(0);
int volume = (ConfMan.getInt("speech_volume", "residualvm") * 100) / 256;
if (ConfMan.hasKey("mute", "residualvm") && ConfMan.getBool("mute", "residualvm"))
volume = 0;
@ -2914,7 +2914,7 @@ void GlobalOptionsDialog::setupCloudTab() {
uint64 usedSpace = CloudMan.getStorageUsedSpace(_selectedStorageIndex);
Common::String usedSpaceNumber, usedSpaceUnits;
usedSpaceNumber = Common::getHumanReadableBytes(usedSpace, usedSpaceUnits);
_storageUsedSpace->setLabel(Common::U32String::format(Common::U32String("%s %S"), usedSpaceNumber.c_str(), _(usedSpaceUnits).c_str()));
_storageUsedSpace->setLabel(Common::U32String::format("%s %S", usedSpaceNumber.c_str(), _(usedSpaceUnits).c_str()));
_storageUsedSpace->setVisible(shownConnectedInfo);
}
if (_storageSyncHint) {

View file

@ -1133,14 +1133,12 @@ void SaveLoadChooserGrid::updateSaves() {
// In save mode we disable the button, when it's write protected.
// TODO: Maybe we should not display it at all then?
if (_saveMode && desc.getWriteProtectedFlag()) {
// We also disable and description the button if slot is locked
if ((_saveMode && desc.getWriteProtectedFlag()) || desc.getLocked()) {
curButton.button->setEnabled(false);
} else {
curButton.button->setEnabled(true);
}
//that would make it look "disabled" if slot is locked
curButton.button->setEnabled(!desc.getLocked());
curButton.description->setEnabled(!desc.getLocked());
}

View file

@ -22,33 +22,34 @@ const char *defaultXML1 = "<?xml version = '1.0'?>"
"/>"
"</palette>"
"<fonts>"
"<font id='text_default' "
"file='helvb12.bdf' "
"/>"
"<font id='text_default'>"
"<language id='*' file='helvb12.bdf'/>"
"</font>"
"<font resolution='y<400' "
"id='text_default' "
"file='clR6x12.bdf' "
"/>"
"<font id='text_button' "
"file='helvb12.bdf' "
"/>"
"id='text_default'>"
"<language id='*' file='clR6x12.bdf'/>"
"</font>"
"<font id='text_button'>"
"<language id='*' file='helvb12.bdf'/>"
"</font>"
"<font resolution='y<400' "
"id='text_button' "
"file='clR6x12.bdf' "
"/>"
"<font id='text_normal' "
"file='helvb12.bdf' "
"/>"
"id='text_button'>"
"<language id='*' file='clR6x12.bdf'/>"
"</font>"
"<font id='text_normal'>"
"<language id='*' file='helvb12.bdf'/>"
"</font>"
"<font resolution='y<400' "
"id='text_normal' "
"file='clR6x12.bdf' "
"/>"
"id='text_normal'>"
"<language id='*' file='clR6x12.bdf'/>"
"</font>"
"<font id='tooltip_normal' "
"file='fixed5x8.bdf' "
"/>"
"<font id='console' "
"file='builtinConsole' "
"/>"
"file='fixed5x8.bdf'>"
"<language id='*' file='fixed5x8.bdf'/>"
"</font>"
"<font id='console'>"
"<language id='*' file='builtinConsole'/>"
"</font>"
"<text_color id='color_normal' "
"color='green' "
"/>"

Binary file not shown.

View file

@ -1 +1 @@
[SCUMMVM_STX0.8.38:ResidualVM Modern Theme:No Author]
[SCUMMVM_STX0.8.39:ResidualVM Modern Theme:No Author]

View file

@ -127,57 +127,85 @@
<fonts>
<font id = 'text_default'
file = 'helvb12.bdf'
scalable_file = 'FreeSansBold.ttf'
/>
file = 'helvb12.bdf'>
<language id = 'ja' scalable_file = 'NotoSansJP-Bold.otf'/>
<language id = 'ko' scalable_file = 'NotoSansKR-Bold.otf'/>
<language id = 'zh*' scalable_file = 'NotoSansTC-Bold.otf'/>
<language id = 'hi' scalable_file = 'NotoSans-Bold.ttf'/>
<language id = '*' scalable_file = 'FreeSansBold.ttf'/>
</font>
<font resolution = 'y<400'
id = 'text_default'
id = 'text_default'
file = 'clR6x12.bdf'
scalable_file = 'FreeSans.ttf'
point_size = '11'
/>
point_size = '11'>
<language id = 'ja' scalable_file = 'NotoSansJP-Regular.otf'/>
<language id = 'ko' scalable_file = 'NotoSansKR-Regular.otf'/>
<language id = 'zh*' scalable_file = 'NotoSansTC-Regular.otf'/>
<language id = 'hi' scalable_file = 'NotoSans-Regular.ttf'/>
<language id = '*' scalable_file = 'FreeSans.ttf'/>
</font>
<font id = 'text_button'
file = 'helvb12.bdf'
scalable_file = 'FreeSansBold.ttf'
/>
file = 'helvb12.bdf'>
<language id = 'ja' scalable_file = 'NotoSansJP-Bold.otf'/>
<language id = 'ko' scalable_file = 'NotoSansKR-Bold.otf'/>
<language id = 'zh*' scalable_file = 'NotoSansTC-Bold.otf'/>
<language id = 'hi' scalable_file = 'NotoSans-Bold.ttf'/>
<language id = '*' scalable_file = 'FreeSansBold.ttf'/>
</font>
<font resolution = 'y<400'
id = 'text_button'
id = 'text_button'
file = 'clR6x12.bdf'
scalable_file = 'FreeSans.ttf'
point_size = '11'
/>
point_size = '11'>
<language id = 'ja' scalable_file = 'NotoSansJP-Regular.otf'/>
<language id = 'ko' scalable_file = 'NotoSansKR-Regular.otf'/>
<language id = 'zh*' scalable_file = 'NotoSansTC-Regular.otf'/>
<language id = 'hi' scalable_file = 'NotoSans-Regular.ttf'/>
<language id = '*' scalable_file = 'FreeSans.ttf'/>
</font>
<font id = 'text_normal'
file = 'helvb12.bdf'
scalable_file = 'FreeSans.ttf'
/>
file = 'helvb12.bdf'>
<language id = 'ja' scalable_file = 'NotoSansJP-Regular.otf'/>
<language id = 'ko' scalable_file = 'NotoSansKR-Regular.otf'/>
<language id = 'zh*' scalable_file = 'NotoSansTC-Regular.otf'/>
<language id = 'hi' scalable_file = 'NotoSans-Regular.ttf'/>
<language id = '*' scalable_file = 'FreeSans.ttf'/>
</font>
<font resolution = 'y<400'
id = 'text_normal'
id = 'text_normal'
file = 'clR6x12.bdf'
scalable_file = 'FreeSans.ttf'
point_size = '11'
/>
point_size = '11'>
<language id = 'ja' scalable_file = 'NotoSansJP-Regular.otf'/>
<language id = 'ko' scalable_file = 'NotoSansKR-Regular.otf'/>
<language id = 'zh*' scalable_file = 'NotoSansTC-Regular.otf'/>
<language id = 'hi' scalable_file = 'NotoSans-Regular.ttf'/>
<language id = '*' scalable_file = 'FreeSans.ttf'/>
</font>
<font id = 'tooltip_normal'
file = 'fixed5x8.bdf'
scalable_file = 'FreeMonoBold.ttf'
point_size = '8'
/>
point_size = '8'>
<language id = 'ja' scalable_file = 'NotoSansJP-Regular.otf'/>
<language id = 'ko' scalable_file = 'NotoSansKR-Regular.otf'/>
<language id = 'zh*' scalable_file = 'NotoSansTC-Regular.otf'/>
<language id = 'hi' scalable_file = 'NotoSans-Regular.ttf'/>
<language id = '*' scalable_file = 'FreeMonoBold.ttf'/>
</font>
<font id = 'console'
file = 'builtinConsole'
scalable_file = 'SourceCodeVariable-Roman.ttf'
point_size = '12'
/>
point_size = '12'>
<language id = '*' scalable_file = 'SourceCodeVariable-Roman.ttf'/>
</font>
<font resolution = 'y<800'
id = 'console'
file = 'builtinConsole'
scalable_file = 'SourceCodeVariable-Roman.ttf'
point_size = '10'
/>
point_size = '10'>
<language id = '*' scalable_file = 'SourceCodeVariable-Roman.ttf'/>
</font>
<font resolution = 'y<400'
id = 'console'
file = 'builtinConsole'
scalable_file = 'SourceCodeVariable-Roman.ttf'
point_size = '8'
/>
point_size = '8'>
<language id = '*' scalable_file = 'SourceCodeVariable-Roman.ttf'/>
</font>
<text_color id = 'color_normal'
color = 'black'