diff --git a/Makefile b/Makefile index a6f6f4c74c3..1ad720a7dd1 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ endif .PHONY: print-dists print-executables print-version print-distversion print-dists: - @echo $(DIST_FILES_DOCS) $(DIST_FILES_THEMES) $(DIST_FILES_NETWORKING) $(DIST_FILES_ENGINEDATA) $(DIST_FILES_PLATFORM) $(srcdir)/doc + @echo $(DIST_FILES_DOCS) $(DIST_FILES_THEMES) $(DIST_FILES_NETWORKING) $(DIST_FILES_VKEYBD) $(DIST_FILES_ENGINEDATA) $(DIST_FILES_PLATFORM) $(srcdir)/doc print-executables: @echo $(if $(DIST_EXECUTABLES),$(DIST_EXECUTABLES),$(EXECUTABLE) $(PLUGINS)) diff --git a/Makefile.common b/Makefile.common index 3d61d600c08..9544af255b7 100644 --- a/Makefile.common +++ b/Makefile.common @@ -138,6 +138,10 @@ ifdef CXX_UPDATE_DEP_FLAG $(QUIET)$(MKDIR) $(*D)/$(DEPDIR) $(QUIET_AS)$(CXX) $(CXX_UPDATE_DEP_FLAG) $(ASFLAGS) -c $(<) -o $*.o +base/version.o: base/version.cpp + $(QUIET)$(MKDIR) $(*D)/$(DEPDIR) + $(QUIET_CXX)$(CXX) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS) $(VERFLAGS) $(CPPFLAGS) -c $(<) -o $*.o + else # Dumb compile rule, for C++ compilers that don't allow dependency tracking or @@ -151,6 +155,9 @@ else $(QUIET)$(MKDIR) $(*D) $(QUIET_AS)$(CXX) $(ASFLAGS) -c $(<) -o $*.o +base/version.o: base/version.cpp + $(QUIET)$(MKDIR) $(*D) + $(QUIET_CXX)$(CXX) $(CXXFLAGS) $(VERFLAGS) $(CPPFLAGS) -c $(<) -o $*.o endif # Build rule for assembler files @@ -158,6 +165,12 @@ endif $(QUIET)$(MKDIR) $(*D) $(QUIET_AS)$(AS) $(ASFLAGS) $(<) -o $*.o +# Build rule for Windows resource files +# TODO: Support dependency tracking +%.o: %.rc + $(QUIET)$(MKDIR) $(*D) + $(QUIET_WINDRES)$(WINDRES) $(WINDRESFLAGS) $(CPPFLAGS) $(<) -o $*.o + ifdef USE_NASM # Build rule for NASM assembler files %.o: %.asm @@ -188,7 +201,7 @@ VER_EXTRA = $(shell echo $(VERSION) | cut -d. -f 3 | cut -c2-) ifdef AMIGAOS # Amiga needs date in specific format for the version cookie AMIGA_DATE = $(shell gdate '+%d.%m.%Y') -base/version.o: CXXFLAGS:=$(CXXFLAGS) -DAMIGA_DATE=\"$(AMIGA_DATE)\" +VERFLAGS += -DAMIGA_DATE=\"$(AMIGA_DATE)\" endif ###################################################################### @@ -211,7 +224,7 @@ endif # Define the Subversion revision if available, either autodetected or # specified by the user, but only for base/version.cpp. ifneq ($(origin VER_REV), undefined) -base/version.o: CXXFLAGS:=$(CXXFLAGS) -DSCUMMVM_REVISION=\"$(VER_REV)\" +VERFLAGS += -DSCUMMVM_REVISION=\"$(VER_REV)\" endif ###################################################################### diff --git a/audio/mixer.cpp b/audio/mixer.cpp index 274f8e9de6c..9eb3e6714ae 100644 --- a/audio/mixer.cpp +++ b/audio/mixer.cpp @@ -23,7 +23,6 @@ #include "gui/EventRecorder.h" #include "common/util.h" -#include "common/system.h" #include "common/textconsole.h" #include "audio/mixer_intern.h" @@ -173,8 +172,7 @@ private: #pragma mark --- Mixer --- #pragma mark - -// TODO: parameter "system" is unused -MixerImpl::MixerImpl(OSystem *system, uint sampleRate) +MixerImpl::MixerImpl(uint sampleRate) : _mutex(), _sampleRate(sampleRate), _mixerReady(false), _handleSeed(0), _soundTypeSettings() { assert(sampleRate > 0); diff --git a/audio/mixer_intern.h b/audio/mixer_intern.h index c7d2ac671a0..84bdbfbd064 100644 --- a/audio/mixer_intern.h +++ b/audio/mixer_intern.h @@ -73,7 +73,7 @@ private: public: - MixerImpl(OSystem *system, uint sampleRate); + MixerImpl(uint sampleRate); ~MixerImpl(); virtual bool isReady() const { return _mixerReady; } diff --git a/backends/base-backend.cpp b/backends/base-backend.cpp index 3e95c3e26ae..9164b8d7216 100644 --- a/backends/base-backend.cpp +++ b/backends/base-backend.cpp @@ -57,7 +57,7 @@ void BaseBackend::initBackend() { void BaseBackend::fillScreen(uint32 col) { Graphics::Surface *screen = lockScreen(); - if (screen && screen->getPixels()) - memset(screen->getPixels(), col, screen->h * screen->pitch); + if (screen) + screen->fillRect(Common::Rect(screen->w, screen->h), col); unlockScreen(); } diff --git a/backends/cloud/box/boxlistdirectorybyidrequest.cpp b/backends/cloud/box/boxlistdirectorybyidrequest.cpp index 0258e3e1e9e..c51c0f57c3b 100644 --- a/backends/cloud/box/boxlistdirectorybyidrequest.cpp +++ b/backends/cloud/box/boxlistdirectorybyidrequest.cpp @@ -83,7 +83,7 @@ void BoxListDirectoryByIdRequest::responseCallback(Networking::JsonResponse resp if (response.request) _date = response.request->date(); - Networking::ErrorResponse error(this); + Networking::ErrorResponse error(this, "BoxListDirectoryByIdRequest::responseCallback: unknown error"); Networking::CurlJsonRequest *rq = (Networking::CurlJsonRequest *)response.request; if (rq && rq->getNetworkReadStream()) error.httpResponseCode = rq->getNetworkReadStream()->httpResponseCode(); diff --git a/backends/cloud/box/boxstorage.cpp b/backends/cloud/box/boxstorage.cpp index 2671a77a5e7..46af2e56be4 100644 --- a/backends/cloud/box/boxstorage.cpp +++ b/backends/cloud/box/boxstorage.cpp @@ -35,142 +35,34 @@ #include "common/debug.h" #include "common/json.h" -#ifdef ENABLE_RELEASE -#include "dists/clouds/cloud_keys.h" -#endif - namespace Cloud { namespace Box { -#define BOX_OAUTH2_TOKEN "https://api.box.com/oauth2/token" #define BOX_API_FOLDERS "https://api.box.com/2.0/folders" #define BOX_API_FILES_CONTENT "https://api.box.com/2.0/files/%s/content" #define BOX_API_USERS_ME "https://api.box.com/2.0/users/me" -char *BoxStorage::KEY = nullptr; //can't use CloudConfig there yet, loading it on instance creation/auth -char *BoxStorage::SECRET = nullptr; +BoxStorage::BoxStorage(Common::String token, Common::String refreshToken, bool enabled): + IdStorage(token, refreshToken, enabled) {} -void BoxStorage::loadKeyAndSecret() { -#ifdef ENABLE_RELEASE - KEY = RELEASE_BOX_KEY; - SECRET = RELEASE_BOX_SECRET; -#else - Common::String k = ConfMan.get("BOX_KEY", ConfMan.kCloudDomain); - KEY = new char[k.size() + 1]; - memcpy(KEY, k.c_str(), k.size()); - KEY[k.size()] = 0; - - k = ConfMan.get("BOX_SECRET", ConfMan.kCloudDomain); - SECRET = new char[k.size() + 1]; - memcpy(SECRET, k.c_str(), k.size()); - SECRET[k.size()] = 0; -#endif -} - -BoxStorage::BoxStorage(Common::String token, Common::String refreshToken): - _token(token), _refreshToken(refreshToken) {} - -BoxStorage::BoxStorage(Common::String code) { - getAccessToken( - new Common::Callback(this, &BoxStorage::codeFlowComplete), - new Common::Callback(this, &BoxStorage::codeFlowFailed), - code - ); +BoxStorage::BoxStorage(Common::String code, Networking::ErrorCallback cb) { + getAccessToken(code, cb); } BoxStorage::~BoxStorage() {} -void BoxStorage::getAccessToken(BoolCallback callback, Networking::ErrorCallback errorCallback, Common::String code) { - if (!KEY || !SECRET) - loadKeyAndSecret(); - bool codeFlow = (code != ""); +Common::String BoxStorage::cloudProvider() { return "box"; } - if (!codeFlow && _refreshToken == "") { - warning("BoxStorage: no refresh token available to get new access token."); - if (callback) (*callback)(BoolResponse(nullptr, false)); - return; - } +uint32 BoxStorage::storageIndex() { return kStorageBoxId; } - Networking::JsonCallback innerCallback = new Common::CallbackBridge(this, &BoxStorage::tokenRefreshed, callback); - if (errorCallback == nullptr) - errorCallback = getErrorPrintingCallback(); +bool BoxStorage::needsRefreshToken() { return true; } - Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(innerCallback, errorCallback, BOX_OAUTH2_TOKEN); - if (codeFlow) { - request->addPostField("grant_type=authorization_code"); - request->addPostField("code=" + code); - } else { - request->addPostField("grant_type=refresh_token"); - request->addPostField("refresh_token=" + _refreshToken); - } - request->addPostField("client_id=" + Common::String(KEY)); - request->addPostField("client_secret=" + Common::String(SECRET)); - /* - if (Cloud::CloudManager::couldUseLocalServer()) { - request->addPostField("&redirect_uri=http%3A%2F%2Flocalhost%3A12345"); - } else { - request->addPostField("&redirect_uri=https%3A%2F%2Fwww.scummvm.org/c/code"); - } - */ - addRequest(request); -} - -void BoxStorage::tokenRefreshed(BoolCallback callback, Networking::JsonResponse response) { - Common::JSONValue *json = response.value; - if (!json) { - warning("BoxStorage: got NULL instead of JSON"); - if (callback) - (*callback)(BoolResponse(nullptr, false)); - delete callback; - return; - } - - if (!Networking::CurlJsonRequest::jsonIsObject(json, "BoxStorage")) { - if (callback) - (*callback)(BoolResponse(nullptr, false)); - delete json; - delete callback; - return; - } - - Common::JSONObject result = json->asObject(); - if (!Networking::CurlJsonRequest::jsonContainsString(result, "access_token", "BoxStorage") || - !Networking::CurlJsonRequest::jsonContainsString(result, "refresh_token", "BoxStorage")) { - warning("BoxStorage: bad response, no token passed"); - debug(9, "%s", json->stringify().c_str()); - if (callback) - (*callback)(BoolResponse(nullptr, false)); - } else { - _token = result.getVal("access_token")->asString(); - _refreshToken = result.getVal("refresh_token")->asString(); - CloudMan.save(); //ask CloudManager to save our new refreshToken - if (callback) - (*callback)(BoolResponse(nullptr, true)); - } - delete json; - delete callback; -} - -void BoxStorage::codeFlowComplete(BoolResponse response) { - if (!response.value) { - warning("BoxStorage: failed to get access token through code flow"); - CloudMan.removeStorage(this); - return; - } - - CloudMan.replaceStorage(this, kStorageBoxId); - ConfMan.flushToDisk(); -} - -void BoxStorage::codeFlowFailed(Networking::ErrorResponse error) { - debug(9, "BoxStorage: code flow failed (%s, %ld):", (error.failed ? "failed" : "interrupted"), error.httpResponseCode); - debug(9, "%s", error.response.c_str()); - CloudMan.removeStorage(this); -} +bool BoxStorage::canReuseRefreshToken() { return false; } void BoxStorage::saveConfig(Common::String keyPrefix) { ConfMan.set(keyPrefix + "access_token", _token, ConfMan.kCloudDomain); ConfMan.set(keyPrefix + "refresh_token", _refreshToken, ConfMan.kCloudDomain); + saveIsEnabledFlag(keyPrefix); } Common::String BoxStorage::name() const { @@ -321,8 +213,6 @@ Networking::Request *BoxStorage::info(StorageInfoCallback callback, Networking:: Common::String BoxStorage::savesDirectoryPath() { return "scummvm/saves/"; } BoxStorage *BoxStorage::loadFromConfig(Common::String keyPrefix) { - loadKeyAndSecret(); - if (!ConfMan.hasKey(keyPrefix + "access_token", ConfMan.kCloudDomain)) { warning("BoxStorage: no access_token found"); return nullptr; @@ -335,7 +225,13 @@ BoxStorage *BoxStorage::loadFromConfig(Common::String keyPrefix) { Common::String accessToken = ConfMan.get(keyPrefix + "access_token", ConfMan.kCloudDomain); Common::String refreshToken = ConfMan.get(keyPrefix + "refresh_token", ConfMan.kCloudDomain); - return new BoxStorage(accessToken, refreshToken); + return new BoxStorage(accessToken, refreshToken, loadIsEnabledFlag(keyPrefix)); +} + +void BoxStorage::removeFromConfig(Common::String keyPrefix) { + ConfMan.removeKey(keyPrefix + "access_token", ConfMan.kCloudDomain); + ConfMan.removeKey(keyPrefix + "refresh_token", ConfMan.kCloudDomain); + removeIsEnabledFlag(keyPrefix); } Common::String BoxStorage::getRootDirectoryId() { diff --git a/backends/cloud/box/boxstorage.h b/backends/cloud/box/boxstorage.h index a641669b2a6..1916c884498 100644 --- a/backends/cloud/box/boxstorage.h +++ b/backends/cloud/box/boxstorage.h @@ -30,26 +30,32 @@ namespace Cloud { namespace Box { class BoxStorage: public Id::IdStorage { - static char *KEY, *SECRET; - - static void loadKeyAndSecret(); - - Common::String _token, _refreshToken; - /** This private constructor is called from loadFromConfig(). */ - BoxStorage(Common::String token, Common::String refreshToken); - - void tokenRefreshed(BoolCallback callback, Networking::JsonResponse response); - void codeFlowComplete(BoolResponse response); - void codeFlowFailed(Networking::ErrorResponse error); + BoxStorage(Common::String token, Common::String refreshToken, bool enabled); /** Constructs StorageInfo based on JSON response from cloud. */ void infoInnerCallback(StorageInfoCallback outerCallback, Networking::JsonResponse json); void createDirectoryInnerCallback(BoolCallback outerCallback, Networking::JsonResponse response); + +protected: + /** + * @return "box" + */ + virtual Common::String cloudProvider(); + + /** + * @return kStorageBoxId + */ + virtual uint32 storageIndex(); + + virtual bool needsRefreshToken(); + + virtual bool canReuseRefreshToken(); + public: /** This constructor uses OAuth code flow to get tokens. */ - BoxStorage(Common::String code); + BoxStorage(Common::String code, Networking::ErrorCallback cb); virtual ~BoxStorage(); /** @@ -98,14 +104,12 @@ public: */ static BoxStorage *loadFromConfig(Common::String keyPrefix); - virtual Common::String getRootDirectoryId(); - /** - * Gets new access_token. If passed is "", refresh_token is used. - * Use "" in order to refresh token and pass a callback, so you could - * continue your work when new token is available. + * Remove all BoxStorage-related data from config. */ - void getAccessToken(BoolCallback callback, Networking::ErrorCallback errorCallback = nullptr, Common::String code = ""); + static void removeFromConfig(Common::String keyPrefix); + + virtual Common::String getRootDirectoryId(); Common::String accessToken() const { return _token; } }; diff --git a/backends/cloud/box/boxtokenrefresher.cpp b/backends/cloud/box/boxtokenrefresher.cpp index 5f7ad1d6110..db52672173c 100644 --- a/backends/cloud/box/boxtokenrefresher.cpp +++ b/backends/cloud/box/boxtokenrefresher.cpp @@ -41,7 +41,7 @@ void BoxTokenRefresher::tokenRefreshed(Storage::BoolResponse response) { if (!response.value) { //failed to refresh token, notify user with NULL in original callback warning("BoxTokenRefresher: failed to refresh token"); - finishError(Networking::ErrorResponse(this, false, true, "", -1)); + finishError(Networking::ErrorResponse(this, false, true, "BoxTokenRefresher::tokenRefreshed: failed to refresh token", -1)); return; } @@ -99,7 +99,7 @@ void BoxTokenRefresher::finishJson(Common::JSONValue *json) { pause(); delete json; - _parentStorage->getAccessToken(new Common::Callback(this, &BoxTokenRefresher::tokenRefreshed)); + _parentStorage->refreshAccessToken(new Common::Callback(this, &BoxTokenRefresher::tokenRefreshed)); return; } } @@ -111,7 +111,7 @@ void BoxTokenRefresher::finishJson(Common::JSONValue *json) { void BoxTokenRefresher::finishError(Networking::ErrorResponse error) { if (error.httpResponseCode == 401) { // invalid_token pause(); - _parentStorage->getAccessToken(new Common::Callback(this, &BoxTokenRefresher::tokenRefreshed)); + _parentStorage->refreshAccessToken(new Common::Callback(this, &BoxTokenRefresher::tokenRefreshed)); return; } diff --git a/backends/cloud/cloudmanager.cpp b/backends/cloud/cloudmanager.cpp index 5519e4baab3..38089db0e91 100644 --- a/backends/cloud/cloudmanager.cpp +++ b/backends/cloud/cloudmanager.cpp @@ -148,12 +148,17 @@ void CloudManager::replaceStorage(Storage *storage, uint32 index) { } _activeStorage = storage; _currentStorageIndex = index; + if (_storages[index].username == "") { + // options' Cloud tab believes Storage is connected once it has non-empty username + _storages[index].username = _(""); + _storages[index].lastSyncDate = _(""); + _storages[index].usedBytes = 0; + } save(); //do what should be done on first Storage connect if (_activeStorage) { _activeStorage->info(nullptr, nullptr); //automatically calls setStorageUsername() - _activeStorage->syncSaves(nullptr, nullptr); } } @@ -250,21 +255,21 @@ void CloudManager::setStorageLastSync(uint32 index, Common::String date) { save(); } -void CloudManager::connectStorage(uint32 index, Common::String code) { +void CloudManager::connectStorage(uint32 index, Common::String code, Networking::ErrorCallback cb) { freeStorages(); switch (index) { case kStorageDropboxId: - new Dropbox::DropboxStorage(code); + new Dropbox::DropboxStorage(code, cb); break; case kStorageOneDriveId: - new OneDrive::OneDriveStorage(code); + new OneDrive::OneDriveStorage(code, cb); break; case kStorageGoogleDriveId: - new GoogleDrive::GoogleDriveStorage(code); + new GoogleDrive::GoogleDriveStorage(code, cb); break; case kStorageBoxId: - new Box::BoxStorage(code); + new Box::BoxStorage(code, cb); break; } // in these constructors Storages request token using the passed code @@ -273,6 +278,42 @@ void CloudManager::connectStorage(uint32 index, Common::String code) { // thus, no memory leak happens } +void CloudManager::disconnectStorage(uint32 index) { + if (index >= kStorageTotal) + error("CloudManager::disconnectStorage: invalid index passed"); + + Common::String name = getStorageConfigName(index); + switch (index) { + case kStorageDropboxId: + Dropbox::DropboxStorage::removeFromConfig(kStoragePrefix + name + "_"); + break; + case kStorageOneDriveId: + OneDrive::OneDriveStorage::removeFromConfig(kStoragePrefix + name + "_"); + break; + case kStorageGoogleDriveId: + GoogleDrive::GoogleDriveStorage::removeFromConfig(kStoragePrefix + name + "_"); + break; + case kStorageBoxId: + Box::BoxStorage::removeFromConfig(kStoragePrefix + name + "_"); + break; + } + + switchStorage(kStorageNoneId); + + ConfMan.removeKey(kStoragePrefix + name + "_username", ConfMan.kCloudDomain); + ConfMan.removeKey(kStoragePrefix + name + "_lastSync", ConfMan.kCloudDomain); + ConfMan.removeKey(kStoragePrefix + name + "_usedBytes", ConfMan.kCloudDomain); + + StorageConfig config; + config.name = _(name); + config.username = ""; + config.lastSyncDate = ""; + config.usedBytes = 0; + + _storages[index] = config; +} + + Networking::Request *CloudManager::listDirectory(Common::String path, Storage::ListDirectoryCallback callback, Networking::ErrorCallback errorCallback, bool recursive) { Storage *storage = getCurrentStorage(); if (storage) { @@ -316,6 +357,28 @@ Common::String CloudManager::savesDirectoryPath() { return ""; } +bool CloudManager::canSyncFilename(const Common::String &filename) const { + if (filename == "" || filename[0] == '.') + return false; + + return true; +} + +bool CloudManager::isStorageEnabled() const { + Storage *storage = getCurrentStorage(); + if (storage) + return storage->isEnabled(); + return false; +} + +void CloudManager::enableStorage() { + Storage *storage = getCurrentStorage(); + if (storage) { + storage->enable(); + save(); + } +} + SavesSyncRequest *CloudManager::syncSaves(Storage::BoolCallback callback, Networking::ErrorCallback errorCallback) { Storage *storage = getCurrentStorage(); if (storage) { @@ -336,14 +399,6 @@ bool CloudManager::isWorking() const { return false; } -bool CloudManager::couldUseLocalServer() { -#ifdef USE_SDL_NET - return Networking::LocalWebserver::getPort() == Networking::LocalWebserver::DEFAULT_SERVER_PORT; -#else - return false; -#endif -} - ///// SavesSyncRequest-related ///// bool CloudManager::isSyncing() const { diff --git a/backends/cloud/cloudmanager.h b/backends/cloud/cloudmanager.h index f58ea8373ae..2d6c0bad435 100644 --- a/backends/cloud/cloudmanager.h +++ b/backends/cloud/cloudmanager.h @@ -204,8 +204,16 @@ public: * * @param index Storage's index * @param code OAuth2 code received from user + * @param cb callback to notify of success or error */ - void connectStorage(uint32 index, Common::String code); + void connectStorage(uint32 index, Common::String code, Networking::ErrorCallback cb = nullptr); + + /** + * Remove Storage with a given index from config. + * + * @param index Storage's index + */ + void disconnectStorage(uint32 index); /** Returns ListDirectoryResponse with list of files. */ Networking::Request *listDirectory(Common::String path, Storage::ListDirectoryCallback callback, Networking::ErrorCallback errorCallback, bool recursive = false); @@ -219,6 +227,15 @@ public: /** Returns storage's saves directory path with the trailing slash. */ Common::String savesDirectoryPath(); + /** Returns whether given filename could be uploaded to or downloaded from storage. */ + bool canSyncFilename(const Common::String &filename) const; + + /** Returns whether current Storage is manually enabled by user (or false, if there is no active Storage). */ + bool isStorageEnabled() const; + + /** Sets Storage::_isEnabled to true and updates the config. */ + void enableStorage(); + /** * Starts saves syncing process in currently active storage if there is any. */ @@ -227,9 +244,6 @@ public: /** Returns whether there are any requests running. */ bool isWorking() const; - /** Returns whether LocalWebserver is available to use for auth. */ - static bool couldUseLocalServer(); - ///// SavesSyncRequest-related ///// /** Returns whether there is a SavesSyncRequest running. */ diff --git a/backends/cloud/downloadrequest.cpp b/backends/cloud/downloadrequest.cpp index c07a23b671a..994a9b34575 100644 --- a/backends/cloud/downloadrequest.cpp +++ b/backends/cloud/downloadrequest.cpp @@ -73,13 +73,13 @@ void DownloadRequest::streamErrorCallback(Networking::ErrorResponse error) { void DownloadRequest::handle() { if (!_localFile) { warning("DownloadRequest: no file to write"); - finishError(Networking::ErrorResponse(this, false, true, "", -1)); + finishError(Networking::ErrorResponse(this, false, true, "DownloadRequest::handle: no file to write into", -1)); return; } if (!_localFile->isOpen()) { warning("DownloadRequest: failed to open file to write"); - finishError(Networking::ErrorResponse(this, false, true, "", -1)); + finishError(Networking::ErrorResponse(this, false, true, "DownloadRequest::handle: failed to open file to write", -1)); return; } @@ -93,7 +93,7 @@ void DownloadRequest::handle() { if (readBytes != 0) if (_localFile->write(_buffer, readBytes) != readBytes) { warning("DownloadRequest: unable to write all received bytes into output file"); - finishError(Networking::ErrorResponse(this, false, true, "", -1)); + finishError(Networking::ErrorResponse(this, false, true, "DownloadRequest::handle: failed to write all bytes into a file", -1)); return; } @@ -113,7 +113,7 @@ void DownloadRequest::handle() { void DownloadRequest::restart() { warning("DownloadRequest: can't restart as there are no means to reopen DumpFile"); - finishError(Networking::ErrorResponse(this, false, true, "", -1)); + finishError(Networking::ErrorResponse(this, false, true, "DownloadRequest::restart: can't restart as there are no means to reopen DumpFile", -1)); //start(); } diff --git a/backends/cloud/dropbox/dropboxcreatedirectoryrequest.cpp b/backends/cloud/dropbox/dropboxcreatedirectoryrequest.cpp index d6937d9cb2a..e410f0a5c4c 100644 --- a/backends/cloud/dropbox/dropboxcreatedirectoryrequest.cpp +++ b/backends/cloud/dropbox/dropboxcreatedirectoryrequest.cpp @@ -74,7 +74,7 @@ void DropboxCreateDirectoryRequest::responseCallback(Networking::JsonResponse re } if (response.request) _date = response.request->date(); - Networking::ErrorResponse error(this); + Networking::ErrorResponse error(this, "DropboxCreateDirectoryRequest::responseCallback: unknown error"); Networking::CurlJsonRequest *rq = (Networking::CurlJsonRequest *)response.request; if (rq && rq->getNetworkReadStream()) error.httpResponseCode = rq->getNetworkReadStream()->httpResponseCode(); diff --git a/backends/cloud/dropbox/dropboxinforequest.cpp b/backends/cloud/dropbox/dropboxinforequest.cpp index ebf2d12170e..08f5ca52231 100644 --- a/backends/cloud/dropbox/dropboxinforequest.cpp +++ b/backends/cloud/dropbox/dropboxinforequest.cpp @@ -71,7 +71,7 @@ void DropboxInfoRequest::userResponseCallback(Networking::JsonResponse response) return; } - Networking::ErrorResponse error(this); + Networking::ErrorResponse error(this, "DropboxInfoRequest::userResponseCallback: unknown error"); Networking::CurlJsonRequest *rq = (Networking::CurlJsonRequest *)response.request; if (rq && rq->getNetworkReadStream()) error.httpResponseCode = rq->getNetworkReadStream()->httpResponseCode(); @@ -125,7 +125,7 @@ void DropboxInfoRequest::quotaResponseCallback(Networking::JsonResponse response return; } - Networking::ErrorResponse error(this); + Networking::ErrorResponse error(this, "DropboxInfoRequest::quotaResponseCallback: unknown error"); Networking::CurlJsonRequest *rq = (Networking::CurlJsonRequest *)response.request; if (rq && rq->getNetworkReadStream()) error.httpResponseCode = rq->getNetworkReadStream()->httpResponseCode(); diff --git a/backends/cloud/dropbox/dropboxlistdirectoryrequest.cpp b/backends/cloud/dropbox/dropboxlistdirectoryrequest.cpp index 0b90ec6d2cf..84a1918eff0 100644 --- a/backends/cloud/dropbox/dropboxlistdirectoryrequest.cpp +++ b/backends/cloud/dropbox/dropboxlistdirectoryrequest.cpp @@ -84,7 +84,7 @@ void DropboxListDirectoryRequest::responseCallback(Networking::JsonResponse resp if (response.request) _date = response.request->date(); - Networking::ErrorResponse error(this); + Networking::ErrorResponse error(this, "DropboxListDirectoryRequest::responseCallback: unknown error"); Networking::CurlJsonRequest *rq = (Networking::CurlJsonRequest *)response.request; if (rq && rq->getNetworkReadStream()) error.httpResponseCode = rq->getNetworkReadStream()->httpResponseCode(); diff --git a/backends/cloud/dropbox/dropboxstorage.cpp b/backends/cloud/dropbox/dropboxstorage.cpp index b856c6cb2ca..7edc609969c 100644 --- a/backends/cloud/dropbox/dropboxstorage.cpp +++ b/backends/cloud/dropbox/dropboxstorage.cpp @@ -35,103 +35,30 @@ #include "common/debug.h" #include "common/json.h" -#ifdef ENABLE_RELEASE -#include "dists/clouds/cloud_keys.h" -#endif - namespace Cloud { namespace Dropbox { -#define DROPBOX_OAUTH2_TOKEN "https://api.dropboxapi.com/oauth2/token" #define DROPBOX_API_FILES_DOWNLOAD "https://content.dropboxapi.com/2/files/download" -char *DropboxStorage::KEY = nullptr; //can't use CloudConfig there yet, loading it on instance creation/auth -char *DropboxStorage::SECRET = nullptr; +DropboxStorage::DropboxStorage(Common::String accessToken, bool enabled): BaseStorage(accessToken, "", enabled) {} -void DropboxStorage::loadKeyAndSecret() { -#ifdef ENABLE_RELEASE - KEY = RELEASE_DROPBOX_KEY; - SECRET = RELEASE_DROPBOX_SECRET; -#else - Common::String k = ConfMan.get("DROPBOX_KEY", ConfMan.kCloudDomain); - KEY = new char[k.size() + 1]; - memcpy(KEY, k.c_str(), k.size()); - KEY[k.size()] = 0; - - k = ConfMan.get("DROPBOX_SECRET", ConfMan.kCloudDomain); - SECRET = new char[k.size() + 1]; - memcpy(SECRET, k.c_str(), k.size()); - SECRET[k.size()] = 0; -#endif -} - -DropboxStorage::DropboxStorage(Common::String accessToken, Common::String userId): _token(accessToken), _uid(userId) {} - -DropboxStorage::DropboxStorage(Common::String code) { - getAccessToken(code); +DropboxStorage::DropboxStorage(Common::String code, Networking::ErrorCallback cb): BaseStorage() { + getAccessToken(code, cb); } DropboxStorage::~DropboxStorage() {} -void DropboxStorage::getAccessToken(Common::String code) { - if (!KEY || !SECRET) - loadKeyAndSecret(); - Networking::JsonCallback callback = new Common::Callback(this, &DropboxStorage::codeFlowComplete); - Networking::ErrorCallback errorCallback = new Common::Callback(this, &DropboxStorage::codeFlowFailed); - Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(callback, errorCallback, DROPBOX_OAUTH2_TOKEN); - request->addPostField("code=" + code); - request->addPostField("grant_type=authorization_code"); - request->addPostField("client_id=" + Common::String(KEY)); - request->addPostField("client_secret=" + Common::String(SECRET)); - if (Cloud::CloudManager::couldUseLocalServer()) { - request->addPostField("&redirect_uri=http%3A%2F%2Flocalhost%3A12345%2F"); - } else { - request->addPostField("&redirect_uri=https%3A%2F%2Fwww.scummvm.org/c/code"); - } - addRequest(request); -} +Common::String DropboxStorage::cloudProvider() { return "dropbox"; } -void DropboxStorage::codeFlowComplete(Networking::JsonResponse response) { - Common::JSONValue *json = (Common::JSONValue *)response.value; - if (json == nullptr) { - debug(9, "DropboxStorage::codeFlowComplete: got NULL instead of JSON!"); - CloudMan.removeStorage(this); - return; - } +uint32 DropboxStorage::storageIndex() { return kStorageDropboxId; } - if (!json->isObject()) { - debug(9, "DropboxStorage::codeFlowComplete: Passed JSON is not an object!"); - CloudMan.removeStorage(this); - delete json; - return; - } +bool DropboxStorage::needsRefreshToken() { return false; } - Common::JSONObject result = json->asObject(); - if (!Networking::CurlJsonRequest::jsonContainsString(result, "access_token", "DropboxStorage::codeFlowComplete") || - !Networking::CurlJsonRequest::jsonContainsString(result, "uid", "DropboxStorage::codeFlowComplete")) { - warning("DropboxStorage: bad response, no token/uid passed"); - debug(9, "%s", json->stringify(true).c_str()); - CloudMan.removeStorage(this); - } else { - _token = result.getVal("access_token")->asString(); - _uid = result.getVal("uid")->asString(); - ConfMan.removeKey("dropbox_code", ConfMan.kCloudDomain); - CloudMan.replaceStorage(this, kStorageDropboxId); - ConfMan.flushToDisk(); - } - - delete json; -} - -void DropboxStorage::codeFlowFailed(Networking::ErrorResponse error) { - debug(9, "DropboxStorage: code flow failed (%s, %ld):", (error.failed ? "failed" : "interrupted"), error.httpResponseCode); - debug(9, "%s", error.response.c_str()); - CloudMan.removeStorage(this); -} +bool DropboxStorage::canReuseRefreshToken() { return false; } void DropboxStorage::saveConfig(Common::String keyPrefix) { ConfMan.set(keyPrefix + "access_token", _token, ConfMan.kCloudDomain); - ConfMan.set(keyPrefix + "user_id", _uid, ConfMan.kCloudDomain); + saveIsEnabledFlag(keyPrefix); } Common::String DropboxStorage::name() const { @@ -177,22 +104,18 @@ Networking::Request *DropboxStorage::info(StorageInfoCallback callback, Networki Common::String DropboxStorage::savesDirectoryPath() { return "/saves/"; } DropboxStorage *DropboxStorage::loadFromConfig(Common::String keyPrefix) { - loadKeyAndSecret(); - if (!ConfMan.hasKey(keyPrefix + "access_token", ConfMan.kCloudDomain)) { warning("DropboxStorage: no access_token found"); return nullptr; } - if (!ConfMan.hasKey(keyPrefix + "user_id", ConfMan.kCloudDomain)) { - warning("DropboxStorage: no user_id found"); - return nullptr; - } + Common::String accessToken = ConfMan.get(keyPrefix + "access_token", ConfMan.kCloudDomain); + return new DropboxStorage(accessToken, loadIsEnabledFlag(keyPrefix)); +} - Common::String accessToken = ConfMan.get(keyPrefix + "access_token", ConfMan.kCloudDomain); - Common::String userId = ConfMan.get(keyPrefix + "user_id", ConfMan.kCloudDomain); - - return new DropboxStorage(accessToken, userId); +void DropboxStorage::removeFromConfig(Common::String keyPrefix) { + ConfMan.removeKey(keyPrefix + "access_token", ConfMan.kCloudDomain); + removeIsEnabledFlag(keyPrefix); } } // End of namespace Dropbox diff --git a/backends/cloud/dropbox/dropboxstorage.h b/backends/cloud/dropbox/dropboxstorage.h index 44fb8a34758..c6a13743570 100644 --- a/backends/cloud/dropbox/dropboxstorage.h +++ b/backends/cloud/dropbox/dropboxstorage.h @@ -23,30 +23,35 @@ #ifndef BACKENDS_CLOUD_DROPBOX_STORAGE_H #define BACKENDS_CLOUD_DROPBOX_STORAGE_H -#include "backends/cloud/storage.h" +#include "backends/cloud/basestorage.h" #include "common/callback.h" #include "backends/networking/curl/curljsonrequest.h" namespace Cloud { namespace Dropbox { -class DropboxStorage: public Cloud::Storage { - static char *KEY, *SECRET; - - static void loadKeyAndSecret(); - - Common::String _token, _uid; - +class DropboxStorage: public Cloud::BaseStorage { /** This private constructor is called from loadFromConfig(). */ - DropboxStorage(Common::String token, Common::String uid); + DropboxStorage(Common::String token, bool enabled); - void getAccessToken(Common::String code); - void codeFlowComplete(Networking::JsonResponse response); - void codeFlowFailed(Networking::ErrorResponse error); +protected: + /** + * @return "dropbox" + */ + virtual Common::String cloudProvider(); + + /** + * @return kStorageDropboxId + */ + virtual uint32 storageIndex(); + + virtual bool needsRefreshToken(); + + virtual bool canReuseRefreshToken(); public: /** This constructor uses OAuth code flow to get tokens. */ - DropboxStorage(Common::String code); + DropboxStorage(Common::String code, Networking::ErrorCallback cb); virtual ~DropboxStorage(); /** @@ -93,6 +98,11 @@ public: * @return pointer to the newly created DropboxStorage or 0 if some problem occured. */ static DropboxStorage *loadFromConfig(Common::String keyPrefix); + + /** + * Remove all DropboxStorage-related data from config. + */ + static void removeFromConfig(Common::String keyPrefix); }; } // End of namespace Dropbox diff --git a/backends/cloud/dropbox/dropboxuploadrequest.cpp b/backends/cloud/dropbox/dropboxuploadrequest.cpp index 361d8acd978..7330bae1fb2 100644 --- a/backends/cloud/dropbox/dropboxuploadrequest.cpp +++ b/backends/cloud/dropbox/dropboxuploadrequest.cpp @@ -54,12 +54,12 @@ void DropboxUploadRequest::start() { _workingRequest->finish(); if (!_contentsStream) { warning("DropboxUploadRequest: cannot start because stream is invalid"); - finishError(Networking::ErrorResponse(this, false, true, "", -1)); + finishError(Networking::ErrorResponse(this, false, true, "DropboxUploadRequest::start: cannot start because stream is invalid", -1)); return; } if (!_contentsStream->seek(0)) { warning("DropboxUploadRequest: cannot restart because stream couldn't seek(0)"); - finishError(Networking::ErrorResponse(this, false, true, "", -1)); + finishError(Networking::ErrorResponse(this, false, true, "DropboxUploadRequest::start: cannot restart because stream couldn't seek(0)", -1)); return; } _ignoreCallback = false; diff --git a/backends/cloud/folderdownloadrequest.cpp b/backends/cloud/folderdownloadrequest.cpp index 3d31beba4b0..c3b9eece876 100644 --- a/backends/cloud/folderdownloadrequest.cpp +++ b/backends/cloud/folderdownloadrequest.cpp @@ -26,6 +26,7 @@ #include "common/debug.h" #include "gui/downloaddialog.h" #include +#include "cloudmanager.h" namespace Cloud { @@ -73,8 +74,9 @@ void FolderDownloadRequest::directoryListedCallback(Storage::ListDirectoryRespon // remove all directories // non-empty directories would be created by DumpFile, and empty ones are just ignored + // also skip all hidden files (with names starting with '.') or with other names that are forbidden to sync in CloudManager for (Common::Array::iterator i = _pendingFiles.begin(); i != _pendingFiles.end();) - if (i->isDirectory()) + if (i->isDirectory() || !CloudMan.canSyncFilename(i->name())) _pendingFiles.erase(i); else { _totalBytes += i->size(); diff --git a/backends/cloud/googledrive/googledrivelistdirectorybyidrequest.cpp b/backends/cloud/googledrive/googledrivelistdirectorybyidrequest.cpp index 24db75b077f..caa6486f424 100644 --- a/backends/cloud/googledrive/googledrivelistdirectorybyidrequest.cpp +++ b/backends/cloud/googledrive/googledrivelistdirectorybyidrequest.cpp @@ -81,7 +81,7 @@ void GoogleDriveListDirectoryByIdRequest::responseCallback(Networking::JsonRespo if (response.request) _date = response.request->date(); - Networking::ErrorResponse error(this); + Networking::ErrorResponse error(this, "GoogleDriveListDirectoryByIdRequest::responseCallback"); Networking::CurlJsonRequest *rq = (Networking::CurlJsonRequest *)response.request; if (rq && rq->getNetworkReadStream()) error.httpResponseCode = rq->getNetworkReadStream()->httpResponseCode(); diff --git a/backends/cloud/googledrive/googledrivestorage.cpp b/backends/cloud/googledrive/googledrivestorage.cpp index 4a870c01b6e..2049d808c43 100644 --- a/backends/cloud/googledrive/googledrivestorage.cpp +++ b/backends/cloud/googledrive/googledrivestorage.cpp @@ -36,142 +36,34 @@ #include "common/json.h" #include "common/debug.h" -#ifdef ENABLE_RELEASE -#include "dists/clouds/cloud_keys.h" -#endif - namespace Cloud { namespace GoogleDrive { -#define GOOGLEDRIVE_OAUTH2_TOKEN "https://accounts.google.com/o/oauth2/token" #define GOOGLEDRIVE_API_FILES_ALT_MEDIA "https://www.googleapis.com/drive/v3/files/%s?alt=media" #define GOOGLEDRIVE_API_FILES "https://www.googleapis.com/drive/v3/files" #define GOOGLEDRIVE_API_ABOUT "https://www.googleapis.com/drive/v3/about?fields=storageQuota,user" -char *GoogleDriveStorage::KEY = nullptr; //can't use CloudConfig there yet, loading it on instance creation/auth -char *GoogleDriveStorage::SECRET = nullptr; +GoogleDriveStorage::GoogleDriveStorage(Common::String token, Common::String refreshToken, bool enabled): + IdStorage(token, refreshToken, enabled) {} -void GoogleDriveStorage::loadKeyAndSecret() { -#ifdef ENABLE_RELEASE - KEY = RELEASE_GOOGLE_DRIVE_KEY; - SECRET = RELEASE_GOOGLE_DRIVE_SECRET; -#else - Common::String k = ConfMan.get("GOOGLE_DRIVE_KEY", ConfMan.kCloudDomain); - KEY = new char[k.size() + 1]; - memcpy(KEY, k.c_str(), k.size()); - KEY[k.size()] = 0; - - k = ConfMan.get("GOOGLE_DRIVE_SECRET", ConfMan.kCloudDomain); - SECRET = new char[k.size() + 1]; - memcpy(SECRET, k.c_str(), k.size()); - SECRET[k.size()] = 0; -#endif -} - -GoogleDriveStorage::GoogleDriveStorage(Common::String token, Common::String refreshToken): - _token(token), _refreshToken(refreshToken) {} - -GoogleDriveStorage::GoogleDriveStorage(Common::String code) { - getAccessToken( - new Common::Callback(this, &GoogleDriveStorage::codeFlowComplete), - new Common::Callback(this, &GoogleDriveStorage::codeFlowFailed), - code - ); +GoogleDriveStorage::GoogleDriveStorage(Common::String code, Networking::ErrorCallback cb) { + getAccessToken(code, cb); } GoogleDriveStorage::~GoogleDriveStorage() {} -void GoogleDriveStorage::getAccessToken(BoolCallback callback, Networking::ErrorCallback errorCallback, Common::String code) { - if (!KEY || !SECRET) loadKeyAndSecret(); - bool codeFlow = (code != ""); +Common::String GoogleDriveStorage::cloudProvider() { return "gdrive"; } - if (!codeFlow && _refreshToken == "") { - warning("GoogleDriveStorage: no refresh token available to get new access token."); - if (callback) - (*callback)(BoolResponse(nullptr, false)); - return; - } +uint32 GoogleDriveStorage::storageIndex() { return kStorageGoogleDriveId; } - Networking::JsonCallback innerCallback = new Common::CallbackBridge(this, &GoogleDriveStorage::tokenRefreshed, callback); - if (errorCallback == nullptr) - errorCallback = getErrorPrintingCallback(); - Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(innerCallback, errorCallback, GOOGLEDRIVE_OAUTH2_TOKEN); - if (codeFlow) { - request->addPostField("code=" + code); - request->addPostField("grant_type=authorization_code"); - } else { - request->addPostField("refresh_token=" + _refreshToken); - request->addPostField("grant_type=refresh_token"); - } - request->addPostField("client_id=" + Common::String(KEY)); - request->addPostField("client_secret=" + Common::String(SECRET)); - if (Cloud::CloudManager::couldUseLocalServer()) { - request->addPostField("&redirect_uri=http%3A%2F%2Flocalhost%3A12345"); - } else { - request->addPostField("&redirect_uri=https%3A%2F%2Fwww.scummvm.org/c/code"); - } - addRequest(request); -} +bool GoogleDriveStorage::needsRefreshToken() { return true; } -void GoogleDriveStorage::tokenRefreshed(BoolCallback callback, Networking::JsonResponse response) { - Common::JSONValue *json = response.value; - if (!json) { - warning("GoogleDriveStorage: got NULL instead of JSON"); - if (callback) - (*callback)(BoolResponse(nullptr, false)); - delete callback; - return; - } - - if (!Networking::CurlJsonRequest::jsonIsObject(json, "GoogleDriveStorage")) { - if (callback) - (*callback)(BoolResponse(nullptr, false)); - delete json; - delete callback; - return; - } - - Common::JSONObject result = json->asObject(); - if (!Networking::CurlJsonRequest::jsonContainsString(result, "access_token", "GoogleDriveStorage")) { - warning("GoogleDriveStorage: bad response, no token passed"); - debug(9, "%s", json->stringify().c_str()); - if (callback) - (*callback)(BoolResponse(nullptr, false)); - } else { - _token = result.getVal("access_token")->asString(); - if (!Networking::CurlJsonRequest::jsonContainsString(result, "refresh_token", "GoogleDriveStorage")) - warning("GoogleDriveStorage: no refresh_token passed"); - else - _refreshToken = result.getVal("refresh_token")->asString(); - CloudMan.save(); //ask CloudManager to save our new refreshToken - if (callback) - (*callback)(BoolResponse(nullptr, true)); - } - delete json; - delete callback; -} - -void GoogleDriveStorage::codeFlowComplete(BoolResponse response) { - if (!response.value) { - warning("GoogleDriveStorage: failed to get access token through code flow"); - CloudMan.removeStorage(this); - return; - } - - ConfMan.removeKey("googledrive_code", ConfMan.kCloudDomain); - CloudMan.replaceStorage(this, kStorageGoogleDriveId); - ConfMan.flushToDisk(); -} - -void GoogleDriveStorage::codeFlowFailed(Networking::ErrorResponse error) { - debug(9, "GoogleDriveStorage: code flow failed (%s, %ld):", (error.failed ? "failed" : "interrupted"), error.httpResponseCode); - debug(9, "%s", error.response.c_str()); - CloudMan.removeStorage(this); -} +bool GoogleDriveStorage::canReuseRefreshToken() { return true; } void GoogleDriveStorage::saveConfig(Common::String keyPrefix) { ConfMan.set(keyPrefix + "access_token", _token, ConfMan.kCloudDomain); ConfMan.set(keyPrefix + "refresh_token", _refreshToken, ConfMan.kCloudDomain); + saveIsEnabledFlag(keyPrefix); } Common::String GoogleDriveStorage::name() const { @@ -325,8 +217,6 @@ Networking::Request *GoogleDriveStorage::info(StorageInfoCallback callback, Netw Common::String GoogleDriveStorage::savesDirectoryPath() { return "scummvm/saves/"; } GoogleDriveStorage *GoogleDriveStorage::loadFromConfig(Common::String keyPrefix) { - loadKeyAndSecret(); - if (!ConfMan.hasKey(keyPrefix + "access_token", ConfMan.kCloudDomain)) { warning("GoogleDriveStorage: no access_token found"); return nullptr; @@ -339,7 +229,13 @@ GoogleDriveStorage *GoogleDriveStorage::loadFromConfig(Common::String keyPrefix) Common::String accessToken = ConfMan.get(keyPrefix + "access_token", ConfMan.kCloudDomain); Common::String refreshToken = ConfMan.get(keyPrefix + "refresh_token", ConfMan.kCloudDomain); - return new GoogleDriveStorage(accessToken, refreshToken); + return new GoogleDriveStorage(accessToken, refreshToken, loadIsEnabledFlag(keyPrefix)); +} + +void GoogleDriveStorage::removeFromConfig(Common::String keyPrefix) { + ConfMan.removeKey(keyPrefix + "access_token", ConfMan.kCloudDomain); + ConfMan.removeKey(keyPrefix + "refresh_token", ConfMan.kCloudDomain); + removeIsEnabledFlag(keyPrefix); } Common::String GoogleDriveStorage::getRootDirectoryId() { diff --git a/backends/cloud/googledrive/googledrivestorage.h b/backends/cloud/googledrive/googledrivestorage.h index d0585bc403b..792c30a99fd 100644 --- a/backends/cloud/googledrive/googledrivestorage.h +++ b/backends/cloud/googledrive/googledrivestorage.h @@ -30,18 +30,8 @@ namespace Cloud { namespace GoogleDrive { class GoogleDriveStorage: public Id::IdStorage { - static char *KEY, *SECRET; - - static void loadKeyAndSecret(); - - Common::String _token, _refreshToken; - /** This private constructor is called from loadFromConfig(). */ - GoogleDriveStorage(Common::String token, Common::String refreshToken); - - void tokenRefreshed(BoolCallback callback, Networking::JsonResponse response); - void codeFlowComplete(BoolResponse response); - void codeFlowFailed(Networking::ErrorResponse error); + GoogleDriveStorage(Common::String token, Common::String refreshToken, bool enabled); /** Constructs StorageInfo based on JSON response from cloud. */ void infoInnerCallback(StorageInfoCallback outerCallback, Networking::JsonResponse json); @@ -50,9 +40,25 @@ class GoogleDriveStorage: public Id::IdStorage { void createDirectoryInnerCallback(BoolCallback outerCallback, Networking::JsonResponse json); void printInfo(StorageInfoResponse response); + +protected: + /** + * @return "gdrive" + */ + virtual Common::String cloudProvider(); + + /** + * @return kStorageGoogleDriveId + */ + virtual uint32 storageIndex(); + + virtual bool needsRefreshToken(); + + virtual bool canReuseRefreshToken(); + public: /** This constructor uses OAuth code flow to get tokens. */ - GoogleDriveStorage(Common::String code); + GoogleDriveStorage(Common::String code, Networking::ErrorCallback cb); virtual ~GoogleDriveStorage(); /** @@ -100,14 +106,12 @@ public: */ static GoogleDriveStorage *loadFromConfig(Common::String keyPrefix); - virtual Common::String getRootDirectoryId(); - /** - * Gets new access_token. If passed is "", refresh_token is used. - * Use "" in order to refresh token and pass a callback, so you could - * continue your work when new token is available. + * Remove all GoogleDriveStorage-related data from config. */ - void getAccessToken(BoolCallback callback, Networking::ErrorCallback errorCallback = nullptr, Common::String code = ""); + static void removeFromConfig(Common::String keyPrefix); + + virtual Common::String getRootDirectoryId(); Common::String accessToken() const { return _token; } }; diff --git a/backends/cloud/googledrive/googledrivetokenrefresher.cpp b/backends/cloud/googledrive/googledrivetokenrefresher.cpp index a32a7fcbed7..089b46e1f97 100644 --- a/backends/cloud/googledrive/googledrivetokenrefresher.cpp +++ b/backends/cloud/googledrive/googledrivetokenrefresher.cpp @@ -41,7 +41,7 @@ void GoogleDriveTokenRefresher::tokenRefreshed(Storage::BoolResponse response) { if (!response.value) { //failed to refresh token, notify user with NULL in original callback warning("GoogleDriveTokenRefresher: failed to refresh token"); - finishError(Networking::ErrorResponse(this, false, true, "", -1)); + finishError(Networking::ErrorResponse(this, false, true, "GoogleDriveTokenRefresher::tokenRefreshed: failed to refresh token", -1)); return; } @@ -77,7 +77,7 @@ void GoogleDriveTokenRefresher::finishJson(Common::JSONValue *json) { Common::JSONObject error = result.getVal("error")->asObject(); bool irrecoverable = true; - uint32 code = -1; + uint32 code = 0xFFFFFFFF; // Invalid Common::String message; if (jsonContainsIntegerNumber(error, "code", "GoogleDriveTokenRefresher")) { code = error.getVal("code")->asIntegerNumber(); @@ -100,7 +100,7 @@ void GoogleDriveTokenRefresher::finishJson(Common::JSONValue *json) { pause(); delete json; - _parentStorage->getAccessToken(new Common::Callback(this, &GoogleDriveTokenRefresher::tokenRefreshed)); + _parentStorage->refreshAccessToken(new Common::Callback(this, &GoogleDriveTokenRefresher::tokenRefreshed)); return; } } diff --git a/backends/cloud/googledrive/googledriveuploadrequest.cpp b/backends/cloud/googledrive/googledriveuploadrequest.cpp index f921f5c96d8..1a533e13600 100644 --- a/backends/cloud/googledrive/googledriveuploadrequest.cpp +++ b/backends/cloud/googledrive/googledriveuploadrequest.cpp @@ -55,7 +55,7 @@ void GoogleDriveUploadRequest::start() { _workingRequest->finish(); if (_contentsStream == nullptr || !_contentsStream->seek(0)) { warning("GoogleDriveUploadRequest: cannot restart because stream couldn't seek(0)"); - finishError(Networking::ErrorResponse(this, false, true, "", -1)); + finishError(Networking::ErrorResponse(this, false, true, "GoogleDriveUploadRequest::start: couldn't restart because failed to seek(0)", -1)); return; } _resolvedId = ""; //used to update file contents @@ -146,33 +146,31 @@ void GoogleDriveUploadRequest::startUploadCallback(Networking::JsonResponse resp if (_ignoreCallback) return; - Networking::ErrorResponse error(this, false, true, "", -1); + Networking::ErrorResponse error(this, false, true, "GoogleDriveUploadRequest::startUploadCallback", -1); Networking::CurlJsonRequest *rq = (Networking::CurlJsonRequest *)response.request; if (rq) { const Networking::NetworkReadStream *stream = rq->getNetworkReadStream(); if (stream) { long code = stream->httpResponseCode(); - Common::String headers = stream->responseHeaders(); if (code == 200) { - const char *cstr = headers.c_str(); - const char *position = strstr(cstr, "Location: "); - - if (position) { - Common::String result = ""; - char c; - for (const char *i = position + 10; c = *i, c != 0; ++i) { - if (c == '\n' || c == '\r') - break; - result += c; - } - _uploadUrl = result; + Common::HashMap headers = stream->responseHeadersMap(); + if (headers.contains("location")) { + _uploadUrl = headers["location"]; uploadNextPart(); return; + } else { + error.response += ": response must provide Location header, but it's not there"; } + } else { + error.response += ": response is not 200 OK"; } error.httpResponseCode = code; + } else { + error.response += ": missing response stream [improbable]"; } + } else { + error.response += ": missing request object [improbable]"; } Common::JSONValue *json = response.value; @@ -202,7 +200,7 @@ void GoogleDriveUploadRequest::uploadNextPart() { if (oldPos != _serverReceivedBytes) { if (!_contentsStream->seek(_serverReceivedBytes)) { warning("GoogleDriveUploadRequest: cannot upload because stream couldn't seek(%lu)", _serverReceivedBytes); - finishError(Networking::ErrorResponse(this, false, true, "", -1)); + finishError(Networking::ErrorResponse(this, false, true, "GoogleDriveUploadRequest::uploadNextPart: seek() didn't work", -1)); return; } oldPos = _serverReceivedBytes; @@ -230,25 +228,19 @@ bool GoogleDriveUploadRequest::handleHttp308(const Networking::NetworkReadStream if (stream->httpResponseCode() != 308) return false; //seriously - Common::String headers = stream->responseHeaders(); - const char *cstr = headers.c_str(); - for (int rangeTry = 0; rangeTry < 2; ++rangeTry) { - const char *needle = (rangeTry == 0 ? "Range: 0-" : "Range: bytes=0-"); - uint32 needleLength = (rangeTry == 0 ? 9 : 15); + Common::HashMap headers = stream->responseHeadersMap(); + if (headers.contains("range")) { + Common::String range = headers["range"]; + for (int rangeTry = 0; rangeTry < 2; ++rangeTry) { + const char *needle = (rangeTry == 0 ? "0-" : "bytes=0-"); //if it lost the first part, I refuse to talk with it + uint32 needleLength = (rangeTry == 0 ? 2 : 8); - const char *position = strstr(cstr, needle); //if it lost the first part, I refuse to talk with it - - if (position) { - Common::String result = ""; - char c; - for (const char *i = position + needleLength; c = *i, c != 0; ++i) { - if (c == '\n' || c == '\r') - break; - result += c; + if (range.hasPrefix(needle)) { + range.erase(0, needleLength); + _serverReceivedBytes = range.asUint64() + 1; + uploadNextPart(); + return true; } - _serverReceivedBytes = result.asUint64() + 1; - uploadNextPart(); - return true; } } diff --git a/backends/cloud/id/idstorage.cpp b/backends/cloud/id/idstorage.cpp index 44427ac4d20..78c3facc2ca 100644 --- a/backends/cloud/id/idstorage.cpp +++ b/backends/cloud/id/idstorage.cpp @@ -33,6 +33,11 @@ namespace Cloud { namespace Id { +IdStorage::IdStorage() {} + +IdStorage::IdStorage(Common::String token, Common::String refreshToken, bool enabled): + BaseStorage(token, refreshToken, enabled) {} + IdStorage::~IdStorage() {} void IdStorage::printFiles(FileArrayResponse response) { diff --git a/backends/cloud/id/idstorage.h b/backends/cloud/id/idstorage.h index 946a792b42b..26d2618508b 100644 --- a/backends/cloud/id/idstorage.h +++ b/backends/cloud/id/idstorage.h @@ -23,7 +23,7 @@ #ifndef BACKENDS_CLOUD_ID_IDSTORAGE_H #define BACKENDS_CLOUD_ID_IDSTORAGE_H -#include "backends/cloud/storage.h" +#include "backends/cloud/basestorage.h" #include "backends/networking/curl/curljsonrequest.h" /* @@ -43,7 +43,7 @@ namespace Cloud { namespace Id { -class IdStorage: public Cloud::Storage { +class IdStorage: public Cloud::BaseStorage { protected: void printFiles(FileArrayResponse response); void printBool(BoolResponse response); @@ -52,6 +52,8 @@ protected: ListDirectoryCallback getPrintFilesCallback(); public: + IdStorage(); + IdStorage(Common::String token, Common::String refreshToken, bool enabled); virtual ~IdStorage(); /** Public Cloud API comes down there. */ diff --git a/backends/cloud/onedrive/onedrivecreatedirectoryrequest.cpp b/backends/cloud/onedrive/onedrivecreatedirectoryrequest.cpp index 74cf3208e38..e38d278559e 100644 --- a/backends/cloud/onedrive/onedrivecreatedirectoryrequest.cpp +++ b/backends/cloud/onedrive/onedrivecreatedirectoryrequest.cpp @@ -31,7 +31,7 @@ namespace Cloud { namespace OneDrive { -#define ONEDRIVE_API_SPECIAL_APPROOT "https://api.onedrive.com/v1.0/drive/special/approot" +#define ONEDRIVE_API_SPECIAL_APPROOT "https://graph.microsoft.com/v1.0/drive/special/approot" OneDriveCreateDirectoryRequest::OneDriveCreateDirectoryRequest(OneDriveStorage *storage, Common::String path, Storage::BoolCallback cb, Networking::ErrorCallback ecb): Networking::Request(nullptr, ecb), _storage(storage), _path(path), _boolCallback(cb), @@ -96,7 +96,7 @@ void OneDriveCreateDirectoryRequest::responseCallback(Networking::JsonResponse r if (response.request) _date = response.request->date(); - Networking::ErrorResponse error(this); + Networking::ErrorResponse error(this, "OneDriveCreateDirectoryRequest::responseCallback: unknown error"); Networking::CurlJsonRequest *rq = (Networking::CurlJsonRequest *)response.request; if (rq && rq->getNetworkReadStream()) error.httpResponseCode = rq->getNetworkReadStream()->httpResponseCode(); diff --git a/backends/cloud/onedrive/onedrivelistdirectoryrequest.cpp b/backends/cloud/onedrive/onedrivelistdirectoryrequest.cpp index 953845d3432..0bf57a63176 100644 --- a/backends/cloud/onedrive/onedrivelistdirectoryrequest.cpp +++ b/backends/cloud/onedrive/onedrivelistdirectoryrequest.cpp @@ -31,7 +31,8 @@ namespace Cloud { namespace OneDrive { -#define ONEDRIVE_API_SPECIAL_APPROOT_CHILDREN "https://api.onedrive.com/v1.0/drive/special/approot:/%s:/children" +#define ONEDRIVE_API_SPECIAL_APPROOT_CHILDREN "https://graph.microsoft.com/v1.0/drive/special/approot:/%s:/children" +#define ONEDRIVE_API_SPECIAL_APPROOT_CHILDREN_ROOT_ITSELF "https://graph.microsoft.com/v1.0/drive/special/approot/children" OneDriveListDirectoryRequest::OneDriveListDirectoryRequest(OneDriveStorage *storage, Common::String path, Storage::ListDirectoryCallback cb, Networking::ErrorCallback ecb, bool recursive): Networking::Request(nullptr, ecb), @@ -77,6 +78,7 @@ void OneDriveListDirectoryRequest::listNextDirectory() { Common::String dir = _currentDirectory; dir.deleteLastChar(); Common::String url = Common::String::format(ONEDRIVE_API_SPECIAL_APPROOT_CHILDREN, ConnMan.urlEncode(dir).c_str()); + if (dir == "") url = Common::String(ONEDRIVE_API_SPECIAL_APPROOT_CHILDREN_ROOT_ITSELF); makeRequest(url); } @@ -84,7 +86,7 @@ void OneDriveListDirectoryRequest::makeRequest(Common::String url) { Networking::JsonCallback callback = new Common::Callback(this, &OneDriveListDirectoryRequest::listedDirectoryCallback); Networking::ErrorCallback failureCallback = new Common::Callback(this, &OneDriveListDirectoryRequest::listedDirectoryErrorCallback); Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(_storage, callback, failureCallback, url.c_str()); - request->addHeader("Authorization: Bearer " + _storage->accessToken()); + request->addHeader("Authorization: bearer " + _storage->accessToken()); _workingRequest = ConnMan.addRequest(request); } @@ -100,7 +102,7 @@ void OneDriveListDirectoryRequest::listedDirectoryCallback(Networking::JsonRespo if (response.request) _date = response.request->date(); - Networking::ErrorResponse error(this); + Networking::ErrorResponse error(this, "OneDriveListDirectoryRequest::listedDirectoryCallback: unknown error"); Networking::CurlJsonRequest *rq = (Networking::CurlJsonRequest *)response.request; if (rq && rq->getNetworkReadStream()) error.httpResponseCode = rq->getNetworkReadStream()->httpResponseCode(); diff --git a/backends/cloud/onedrive/onedrivestorage.cpp b/backends/cloud/onedrive/onedrivestorage.cpp index 9f7cad2e01f..e7ac5b70f55 100644 --- a/backends/cloud/onedrive/onedrivestorage.cpp +++ b/backends/cloud/onedrive/onedrivestorage.cpp @@ -36,143 +36,33 @@ #include "common/debug.h" #include "common/json.h" -#ifdef ENABLE_RELEASE -#include "dists/clouds/cloud_keys.h" -#endif - namespace Cloud { namespace OneDrive { -#define ONEDRIVE_OAUTH2_TOKEN "https://login.live.com/oauth20_token.srf" -#define ONEDRIVE_API_SPECIAL_APPROOT_ID "https://api.onedrive.com/v1.0/drive/special/approot:/" -#define ONEDRIVE_API_SPECIAL_APPROOT "https://api.onedrive.com/v1.0/drive/special/approot" +#define ONEDRIVE_API_SPECIAL_APPROOT_ID "https://graph.microsoft.com/v1.0/drive/special/approot:/" +#define ONEDRIVE_API_SPECIAL_APPROOT "https://graph.microsoft.com/v1.0/drive/special/approot" -char *OneDriveStorage::KEY = nullptr; //can't use CloudConfig there yet, loading it on instance creation/auth -char *OneDriveStorage::SECRET = nullptr; +OneDriveStorage::OneDriveStorage(Common::String token, Common::String refreshToken, bool enabled): + BaseStorage(token, refreshToken, enabled) {} -void OneDriveStorage::loadKeyAndSecret() { -#ifdef ENABLE_RELEASE - KEY = RELEASE_ONEDRIVE_KEY; - SECRET = RELEASE_ONEDRIVE_SECRET; -#else - Common::String k = ConfMan.get("ONEDRIVE_KEY", ConfMan.kCloudDomain); - KEY = new char[k.size() + 1]; - memcpy(KEY, k.c_str(), k.size()); - KEY[k.size()] = 0; - - k = ConfMan.get("ONEDRIVE_SECRET", ConfMan.kCloudDomain); - SECRET = new char[k.size() + 1]; - memcpy(SECRET, k.c_str(), k.size()); - SECRET[k.size()] = 0; -#endif -} - -OneDriveStorage::OneDriveStorage(Common::String token, Common::String uid, Common::String refreshToken): - _token(token), _uid(uid), _refreshToken(refreshToken) {} - -OneDriveStorage::OneDriveStorage(Common::String code) { - getAccessToken( - new Common::Callback(this, &OneDriveStorage::codeFlowComplete), - new Common::Callback(this, &OneDriveStorage::codeFlowFailed), - code - ); +OneDriveStorage::OneDriveStorage(Common::String code, Networking::ErrorCallback cb) { + getAccessToken(code, cb); } OneDriveStorage::~OneDriveStorage() {} -void OneDriveStorage::getAccessToken(BoolCallback callback, Networking::ErrorCallback errorCallback, Common::String code) { - if (!KEY || !SECRET) - loadKeyAndSecret(); - bool codeFlow = (code != ""); +Common::String OneDriveStorage::cloudProvider() { return "onedrive"; } - if (!codeFlow && _refreshToken == "") { - warning("OneDriveStorage: no refresh token available to get new access token."); - if (callback) - (*callback)(BoolResponse(nullptr, false)); - return; - } +uint32 OneDriveStorage::storageIndex() { return kStorageOneDriveId; } - Networking::JsonCallback innerCallback = new Common::CallbackBridge(this, &OneDriveStorage::tokenRefreshed, callback); - if (errorCallback == nullptr) - errorCallback = getErrorPrintingCallback(); - Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(innerCallback, errorCallback, ONEDRIVE_OAUTH2_TOKEN); - if (codeFlow) { - request->addPostField("code=" + code); - request->addPostField("grant_type=authorization_code"); - } else { - request->addPostField("refresh_token=" + _refreshToken); - request->addPostField("grant_type=refresh_token"); - } - request->addPostField("client_id=" + Common::String(KEY)); - request->addPostField("client_secret=" + Common::String(SECRET)); - if (Cloud::CloudManager::couldUseLocalServer()) { - request->addPostField("&redirect_uri=http%3A%2F%2Flocalhost%3A12345%2F"); - } else { - request->addPostField("&redirect_uri=https%3A%2F%2Fwww.scummvm.org/c/code"); - } - addRequest(request); -} +bool OneDriveStorage::needsRefreshToken() { return true; } -void OneDriveStorage::tokenRefreshed(BoolCallback callback, Networking::JsonResponse response) { - Common::JSONValue *json = response.value; - if (!json) { - warning("OneDriveStorage: got NULL instead of JSON"); - if (callback) - (*callback)(BoolResponse(nullptr, false)); - delete callback; - return; - } - - if (!Networking::CurlJsonRequest::jsonIsObject(json, "OneDriveStorage")) { - if (callback) - (*callback)(BoolResponse(nullptr, false)); - delete json; - delete callback; - return; - } - - Common::JSONObject result = json->asObject(); - if (!Networking::CurlJsonRequest::jsonContainsString(result, "access_token", "OneDriveStorage") || - !Networking::CurlJsonRequest::jsonContainsString(result, "user_id", "OneDriveStorage") || - !Networking::CurlJsonRequest::jsonContainsString(result, "refresh_token", "OneDriveStorage")) { - warning("OneDriveStorage: bad response, no token or user_id passed"); - debug(9, "%s", json->stringify().c_str()); - if (callback) - (*callback)(BoolResponse(nullptr, false)); - } else { - _token = result.getVal("access_token")->asString(); - _uid = result.getVal("user_id")->asString(); - _refreshToken = result.getVal("refresh_token")->asString(); - CloudMan.save(); //ask CloudManager to save our new refreshToken - if (callback) - (*callback)(BoolResponse(nullptr, true)); - } - delete json; - delete callback; -} - -void OneDriveStorage::codeFlowComplete(BoolResponse response) { - if (!response.value) { - warning("OneDriveStorage: failed to get access token through code flow"); - CloudMan.removeStorage(this); - return; - } - - ConfMan.removeKey("onedrive_code", ConfMan.kCloudDomain); - CloudMan.replaceStorage(this, kStorageOneDriveId); - ConfMan.flushToDisk(); -} - -void OneDriveStorage::codeFlowFailed(Networking::ErrorResponse error) { - debug(9, "OneDriveStorage: code flow failed (%s, %ld):", (error.failed ? "failed" : "interrupted"), error.httpResponseCode); - debug(9, "%s", error.response.c_str()); - CloudMan.removeStorage(this); -} +bool OneDriveStorage::canReuseRefreshToken() { return false; } void OneDriveStorage::saveConfig(Common::String keyPrefix) { ConfMan.set(keyPrefix + "access_token", _token, ConfMan.kCloudDomain); - ConfMan.set(keyPrefix + "user_id", _uid, ConfMan.kCloudDomain); ConfMan.set(keyPrefix + "refresh_token", _refreshToken, ConfMan.kCloudDomain); + saveIsEnabledFlag(keyPrefix); } Common::String OneDriveStorage::name() const { @@ -247,7 +137,7 @@ void OneDriveStorage::fileInfoCallback(Networking::NetworkReadStreamCallback out } Common::JSONObject result = response.value->asObject(); - if (!Networking::CurlJsonRequest::jsonContainsString(result, "@content.downloadUrl", "OneDriveStorage::fileInfoCallback")) { + if (!Networking::CurlJsonRequest::jsonContainsString(result, "@microsoft.graph.downloadUrl", "OneDriveStorage::fileInfoCallback")) { warning("OneDriveStorage: downloadUrl not found in passed JSON"); debug(9, "%s", response.value->stringify().c_str()); if (outerCallback) @@ -257,7 +147,7 @@ void OneDriveStorage::fileInfoCallback(Networking::NetworkReadStreamCallback out return; } - const char *url = result.getVal("@content.downloadUrl")->asString().c_str(); + const char *url = result.getVal("@microsoft.graph.downloadUrl")->asString().c_str(); if (outerCallback) (*outerCallback)(Networking::NetworkReadStreamResponse( response.request, @@ -269,28 +159,33 @@ void OneDriveStorage::fileInfoCallback(Networking::NetworkReadStreamCallback out } Networking::Request *OneDriveStorage::listDirectory(Common::String path, ListDirectoryCallback callback, Networking::ErrorCallback errorCallback, bool recursive) { + debug(9, "OneDrive: `ls \"%s\"`", path.c_str()); return addRequest(new OneDriveListDirectoryRequest(this, path, callback, errorCallback, recursive)); } Networking::Request *OneDriveStorage::upload(Common::String path, Common::SeekableReadStream *contents, UploadCallback callback, Networking::ErrorCallback errorCallback) { + debug(9, "OneDrive: `upload \"%s\"`", path.c_str()); return addRequest(new OneDriveUploadRequest(this, path, contents, callback, errorCallback)); } Networking::Request *OneDriveStorage::streamFileById(Common::String path, Networking::NetworkReadStreamCallback outerCallback, Networking::ErrorCallback errorCallback) { + debug(9, "OneDrive: `download \"%s\"`", path.c_str()); Common::String url = ONEDRIVE_API_SPECIAL_APPROOT_ID + ConnMan.urlEncode(path); Networking::JsonCallback innerCallback = new Common::CallbackBridge(this, &OneDriveStorage::fileInfoCallback, outerCallback); Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(this, innerCallback, errorCallback, url.c_str()); - request->addHeader("Authorization: Bearer " + _token); + request->addHeader("Authorization: bearer " + _token); return addRequest(request); } Networking::Request *OneDriveStorage::createDirectory(Common::String path, BoolCallback callback, Networking::ErrorCallback errorCallback) { + debug(9, "OneDrive: `mkdir \"%s\"`", path.c_str()); if (!errorCallback) errorCallback = getErrorPrintingCallback(); return addRequest(new OneDriveCreateDirectoryRequest(this, path, callback, errorCallback)); } Networking::Request *OneDriveStorage::info(StorageInfoCallback callback, Networking::ErrorCallback errorCallback) { + debug(9, "OneDrive: `info`"); Networking::JsonCallback innerCallback = new Common::CallbackBridge(this, &OneDriveStorage::infoInnerCallback, callback); Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(this, innerCallback, errorCallback, ONEDRIVE_API_SPECIAL_APPROOT); request->addHeader("Authorization: bearer " + _token); @@ -300,27 +195,25 @@ Networking::Request *OneDriveStorage::info(StorageInfoCallback callback, Network Common::String OneDriveStorage::savesDirectoryPath() { return "saves/"; } OneDriveStorage *OneDriveStorage::loadFromConfig(Common::String keyPrefix) { - loadKeyAndSecret(); - if (!ConfMan.hasKey(keyPrefix + "access_token", ConfMan.kCloudDomain)) { warning("OneDriveStorage: no access_token found"); return nullptr; } - if (!ConfMan.hasKey(keyPrefix + "user_id", ConfMan.kCloudDomain)) { - warning("OneDriveStorage: no user_id found"); - return nullptr; - } - if (!ConfMan.hasKey(keyPrefix + "refresh_token", ConfMan.kCloudDomain)) { warning("OneDriveStorage: no refresh_token found"); return nullptr; } Common::String accessToken = ConfMan.get(keyPrefix + "access_token", ConfMan.kCloudDomain); - Common::String userId = ConfMan.get(keyPrefix + "user_id", ConfMan.kCloudDomain); Common::String refreshToken = ConfMan.get(keyPrefix + "refresh_token", ConfMan.kCloudDomain); - return new OneDriveStorage(accessToken, userId, refreshToken); + return new OneDriveStorage(accessToken, refreshToken, loadIsEnabledFlag(keyPrefix)); +} + +void OneDriveStorage::removeFromConfig(Common::String keyPrefix) { + ConfMan.removeKey(keyPrefix + "access_token", ConfMan.kCloudDomain); + ConfMan.removeKey(keyPrefix + "refresh_token", ConfMan.kCloudDomain); + removeIsEnabledFlag(keyPrefix); } } // End of namespace OneDrive diff --git a/backends/cloud/onedrive/onedrivestorage.h b/backends/cloud/onedrive/onedrivestorage.h index 5d24eb2c2e0..edf6a5f53f3 100644 --- a/backends/cloud/onedrive/onedrivestorage.h +++ b/backends/cloud/onedrive/onedrivestorage.h @@ -23,33 +23,39 @@ #ifndef BACKENDS_CLOUD_ONEDRIVE_ONEDRIVESTORAGE_H #define BACKENDS_CLOUD_ONEDRIVE_ONEDRIVESTORAGE_H -#include "backends/cloud/storage.h" +#include "backends/cloud/basestorage.h" #include "backends/networking/curl/curljsonrequest.h" namespace Cloud { namespace OneDrive { -class OneDriveStorage: public Cloud::Storage { - static char *KEY, *SECRET; - - static void loadKeyAndSecret(); - - Common::String _token, _uid, _refreshToken; - +class OneDriveStorage: public Cloud::BaseStorage { /** This private constructor is called from loadFromConfig(). */ - OneDriveStorage(Common::String token, Common::String uid, Common::String refreshToken); - - void tokenRefreshed(BoolCallback callback, Networking::JsonResponse response); - void codeFlowComplete(BoolResponse response); - void codeFlowFailed(Networking::ErrorResponse error); + OneDriveStorage(Common::String token, Common::String refreshToken, bool enabled); /** Constructs StorageInfo based on JSON response from cloud. */ void infoInnerCallback(StorageInfoCallback outerCallback, Networking::JsonResponse json); void fileInfoCallback(Networking::NetworkReadStreamCallback outerCallback, Networking::JsonResponse response); + +protected: + /** + * @return "onedrive" + */ + virtual Common::String cloudProvider(); + + /** + * @return kStorageOneDriveId + */ + virtual uint32 storageIndex(); + + virtual bool needsRefreshToken(); + + virtual bool canReuseRefreshToken(); + public: /** This constructor uses OAuth code flow to get tokens. */ - OneDriveStorage(Common::String code); + OneDriveStorage(Common::String code, Networking::ErrorCallback cb); virtual ~OneDriveStorage(); /** @@ -98,11 +104,9 @@ public: static OneDriveStorage *loadFromConfig(Common::String keyPrefix); /** - * Gets new access_token. If passed is "", refresh_token is used. - * Use "" in order to refresh token and pass a callback, so you could - * continue your work when new token is available. + * Remove all OneDriveStorage-related data from config. */ - void getAccessToken(BoolCallback callback, Networking::ErrorCallback errorCallback = nullptr, Common::String code = ""); + static void removeFromConfig(Common::String keyPrefix); Common::String accessToken() const { return _token; } }; diff --git a/backends/cloud/onedrive/onedrivetokenrefresher.cpp b/backends/cloud/onedrive/onedrivetokenrefresher.cpp index be6de402581..b456732233c 100644 --- a/backends/cloud/onedrive/onedrivetokenrefresher.cpp +++ b/backends/cloud/onedrive/onedrivetokenrefresher.cpp @@ -41,7 +41,7 @@ void OneDriveTokenRefresher::tokenRefreshed(Storage::BoolResponse response) { if (!response.value) { //failed to refresh token, notify user with NULL in original callback warning("OneDriveTokenRefresher: failed to refresh token"); - finishError(Networking::ErrorResponse(this, false, true, "", -1)); + finishError(Networking::ErrorResponse(this, false, true, "OneDriveTokenRefresher::tokenRefreshed: failed to refresh token", -1)); return; } @@ -94,18 +94,19 @@ void OneDriveTokenRefresher::finishJson(Common::JSONValue *json) { irrecoverable = false; } - if (code == "unauthenticated") + if (code == "unauthenticated" || code == "InvalidAuthenticationToken") irrecoverable = false; if (irrecoverable) { - finishError(Networking::ErrorResponse(this, false, true, json->stringify(true), httpResponseCode)); + Common::String errorContents = " " + json->stringify(true); + finishError(Networking::ErrorResponse(this, false, true, errorContents, httpResponseCode)); delete json; return; } pause(); delete json; - _parentStorage->getAccessToken(new Common::Callback(this, &OneDriveTokenRefresher::tokenRefreshed)); + _parentStorage->refreshAccessToken(new Common::Callback(this, &OneDriveTokenRefresher::tokenRefreshed)); return; } } @@ -114,6 +115,29 @@ void OneDriveTokenRefresher::finishJson(Common::JSONValue *json) { CurlJsonRequest::finishJson(json); } +void OneDriveTokenRefresher::finishError(Networking::ErrorResponse error) { + if (error.failed) { + Common::JSONValue *value = Common::JSON::parse(error.response.c_str()); + + //somehow OneDrive returns JSON with '.' in unexpected places, try fixing it + if (!value) { + Common::String fixedResponse = error.response; + for (uint32 i = 0; i < fixedResponse.size(); ++i) { + if (fixedResponse[i] == '.') + fixedResponse.replace(i, 1, " "); + } + value = Common::JSON::parse(fixedResponse.c_str()); + } + + if (value) { + finishJson(value); + return; + } + } + + Request::finishError(error); //call closest base class's method +} + void OneDriveTokenRefresher::setHeaders(Common::Array &headers) { _headers = headers; curl_slist_free_all(_headersList); diff --git a/backends/cloud/onedrive/onedrivetokenrefresher.h b/backends/cloud/onedrive/onedrivetokenrefresher.h index d190bc46660..b4473798cd5 100644 --- a/backends/cloud/onedrive/onedrivetokenrefresher.h +++ b/backends/cloud/onedrive/onedrivetokenrefresher.h @@ -38,6 +38,7 @@ class OneDriveTokenRefresher: public Networking::CurlJsonRequest { void tokenRefreshed(Storage::BoolResponse response); virtual void finishJson(Common::JSONValue *json); + virtual void finishError(Networking::ErrorResponse error); public: OneDriveTokenRefresher(OneDriveStorage *parent, Networking::JsonCallback callback, Networking::ErrorCallback ecb, const char *url); virtual ~OneDriveTokenRefresher(); diff --git a/backends/cloud/onedrive/onedriveuploadrequest.cpp b/backends/cloud/onedrive/onedriveuploadrequest.cpp index ebf387fca24..5e7011a6e92 100644 --- a/backends/cloud/onedrive/onedriveuploadrequest.cpp +++ b/backends/cloud/onedrive/onedriveuploadrequest.cpp @@ -33,8 +33,8 @@ namespace Cloud { namespace OneDrive { -#define ONEDRIVE_API_SPECIAL_APPROOT_UPLOAD "https://api.onedrive.com/v1.0/drive/special/approot:/%s:/upload.createSession" -#define ONEDRIVE_API_SPECIAL_APPROOT_CONTENT "https://api.onedrive.com/v1.0/drive/special/approot:/%s:/content" +#define ONEDRIVE_API_SPECIAL_APPROOT_UPLOAD "https://graph.microsoft.com/v1.0/drive/special/approot:/%s:/upload.createSession" +#define ONEDRIVE_API_SPECIAL_APPROOT_CONTENT "https://graph.microsoft.com/v1.0/drive/special/approot:/%s:/content" OneDriveUploadRequest::OneDriveUploadRequest(OneDriveStorage *storage, Common::String path, Common::SeekableReadStream *contents, Storage::UploadCallback callback, Networking::ErrorCallback ecb): Networking::Request(nullptr, ecb), _storage(storage), _savePath(path), _contentsStream(contents), _uploadCallback(callback), @@ -56,12 +56,12 @@ void OneDriveUploadRequest::start() { _workingRequest->finish(); if (_contentsStream == nullptr) { warning("OneDriveUploadRequest: cannot restart because no stream given"); - finishError(Networking::ErrorResponse(this, false, true, "No stream given", -1)); + finishError(Networking::ErrorResponse(this, false, true, "OneDriveUploadRequest::start: can't restart, because no stream given", -1)); return; } if (!_contentsStream->seek(0)) { warning("OneDriveUploadRequest: cannot restart because stream couldn't seek(0)"); - finishError(Networking::ErrorResponse(this, false, true, "", -1)); + finishError(Networking::ErrorResponse(this, false, true, "OneDriveUploadRequest::start: can't restart, because seek(0) didn't work", -1)); return; } _ignoreCallback = false; diff --git a/backends/cloud/savessyncrequest.cpp b/backends/cloud/savessyncrequest.cpp index f9b16b355bd..439642b45ce 100644 --- a/backends/cloud/savessyncrequest.cpp +++ b/backends/cloud/savessyncrequest.cpp @@ -72,7 +72,7 @@ void SavesSyncRequest::start() { new Common::Callback(this, &SavesSyncRequest::directoryListedCallback), new Common::Callback(this, &SavesSyncRequest::directoryListedErrorCallback) ); - if (!_workingRequest) finishError(Networking::ErrorResponse(this)); + if (!_workingRequest) finishError(Networking::ErrorResponse(this, "SavesSyncRequest::start: Storage couldn't create Request to list directory")); } void SavesSyncRequest::directoryListedCallback(Storage::ListDirectoryResponse response) { @@ -90,17 +90,19 @@ void SavesSyncRequest::directoryListedCallback(Storage::ListDirectoryResponse re //determine which files to download and which files to upload Common::Array &remoteFiles = response.value; uint64 totalSize = 0; + debug(9, "SavesSyncRequest decisions:"); for (uint32 i = 0; i < remoteFiles.size(); ++i) { StorageFile &file = remoteFiles[i]; if (file.isDirectory()) continue; totalSize += file.size(); - if (file.name() == DefaultSaveFileManager::TIMESTAMPS_FILENAME) + if (file.name() == DefaultSaveFileManager::TIMESTAMPS_FILENAME || !CloudMan.canSyncFilename(file.name())) continue; Common::String name = file.name(); if (!_localFilesTimestamps.contains(name)) { _filesToDownload.push_back(file); + debug(9, "- downloading file %s, because it is not present on local", name.c_str()); } else { localFileNotAvailableInCloud[name] = false; @@ -113,6 +115,13 @@ void SavesSyncRequest::directoryListedCallback(Storage::ListDirectoryResponse re _filesToUpload.push_back(file.name()); else _filesToDownload.push_back(file); + + if (_localFilesTimestamps[name] == DefaultSaveFileManager::INVALID_TIMESTAMP) + debug(9, "- uploading file %s, because it is has invalid timestamp", name.c_str()); + else if (_localFilesTimestamps[name] > file.timestamp()) + debug(9, "- uploading file %s, because it is %d seconds newer than remote\n\tlocal = %d; \tremote = %d", name.c_str(), _localFilesTimestamps[name] - file.timestamp(), _localFilesTimestamps[name], file.timestamp()); + else + debug(9, "- downloading file %s, because it is %d seconds older than remote\n\tlocal = %d; \tremote = %d", name.c_str(), file.timestamp() - _localFilesTimestamps[name], _localFilesTimestamps[name], file.timestamp()); } } @@ -120,24 +129,41 @@ void SavesSyncRequest::directoryListedCallback(Storage::ListDirectoryResponse re //upload files which are unavailable in cloud for (Common::HashMap::iterator i = localFileNotAvailableInCloud.begin(); i != localFileNotAvailableInCloud.end(); ++i) { - if (i->_key == DefaultSaveFileManager::TIMESTAMPS_FILENAME) + if (i->_key == DefaultSaveFileManager::TIMESTAMPS_FILENAME || !CloudMan.canSyncFilename(i->_key)) continue; - if (i->_value) + if (i->_value) { _filesToUpload.push_back(i->_key); + debug(9, "- uploading file %s, because it is not present on remote", i->_key.c_str()); + } } - debug(9, "\nSavesSyncRequest: download files:"); - for (uint32 i = 0; i < _filesToDownload.size(); ++i) { - debug(9, "%s", _filesToDownload[i].name().c_str()); + debug(9, "\nSavesSyncRequest: "); + if (_filesToDownload.size() > 0) { + debug(9, "download files:"); + for (uint32 i = 0; i < _filesToDownload.size(); ++i) { + debug(9, " %s", _filesToDownload[i].name().c_str()); + } + debug(9, "%s", ""); + } else { + debug(9, "nothing to download"); } - debug(9, "\nSavesSyncRequest: upload files:"); - for (uint32 i = 0; i < _filesToUpload.size(); ++i) { - debug(9, "%s", _filesToUpload[i].c_str()); + debug(9, "SavesSyncRequest: "); + if (_filesToUpload.size() > 0) { + debug(9, "upload files:"); + for (uint32 i = 0; i < _filesToUpload.size(); ++i) { + debug(9, " %s", _filesToUpload[i].c_str()); + } + } else { + debug(9, "nothing to upload"); } _totalFilesToHandle = _filesToDownload.size() + _filesToUpload.size(); //start downloading files - downloadNextFile(); + if (!_filesToDownload.empty()) { + downloadNextFile(); + } else { + uploadNextFile(); + } } void SavesSyncRequest::directoryListedErrorCallback(Networking::ErrorResponse error) { @@ -145,9 +171,22 @@ void SavesSyncRequest::directoryListedErrorCallback(Networking::ErrorResponse er if (_ignoreCallback) return; + if (error.failed) debug(9, "%s", error.response.c_str()); + bool irrecoverable = error.interrupted || error.failed; if (error.failed) { Common::JSONValue *value = Common::JSON::parse(error.response.c_str()); + + // somehow OneDrive returns JSON with '.' in unexpected places, try fixing it + if (!value) { + Common::String fixedResponse = error.response; + for (uint32 i = 0; i < fixedResponse.size(); ++i) { + if (fixedResponse[i] == '.') + fixedResponse.replace(i, 1, " "); + } + value = Common::JSON::parse(fixedResponse.c_str()); + } + if (value) { if (value->isObject()) { Common::JSONObject object = value->asObject(); @@ -174,11 +213,13 @@ void SavesSyncRequest::directoryListedErrorCallback(Networking::ErrorResponse er delete value; } - //Google Drive and Box-related ScummVM-based error + //Google Drive, Box and OneDrive-related ScummVM-based error if (error.response.contains("subdirectory not found")) { irrecoverable = false; //base "/ScummVM/" folder not found } else if (error.response.contains("no such file found in its parent directory")) { irrecoverable = false; //"Saves" folder within "/ScummVM/" not found + } else if (error.response.contains("itemNotFound") && error.response.contains("Item does not exist")) { + irrecoverable = false; //"saves" folder within application folder is not found } } @@ -191,14 +232,14 @@ void SavesSyncRequest::directoryListedErrorCallback(Networking::ErrorResponse er Common::String dir = _storage->savesDirectoryPath(); if (dir.lastChar() == '/') dir.deleteLastChar(); - debug(9, "SavesSyncRequest: creating %s", dir.c_str()); + debug(9, "\nSavesSyncRequest: creating %s", dir.c_str()); _workingRequest = _storage->createDirectory( dir, new Common::Callback(this, &SavesSyncRequest::directoryCreatedCallback), new Common::Callback(this, &SavesSyncRequest::directoryCreatedErrorCallback) ); if (!_workingRequest) - finishError(Networking::ErrorResponse(this)); + finishError(Networking::ErrorResponse(this, "SavesSyncRequest::directoryListedErrorCallback: Storage couldn't create Request to create remote directory")); } void SavesSyncRequest::directoryCreatedCallback(Storage::BoolResponse response) { @@ -208,7 +249,7 @@ void SavesSyncRequest::directoryCreatedCallback(Storage::BoolResponse response) //stop syncing if failed to create saves directory if (!response.value) { - finishError(Networking::ErrorResponse(this, false, true, "", -1)); + finishError(Networking::ErrorResponse(this, false, true, "SavesSyncRequest::directoryCreatedCallback: failed to create remote directory", -1)); return; } @@ -239,7 +280,7 @@ void SavesSyncRequest::downloadNextFile() { sendCommand(GUI::kSavesSyncProgressCmd, (int)(getDownloadingProgress() * 100)); - debug(9, "SavesSyncRequest: downloading %s (%d %%)", _currentDownloadingFile.name().c_str(), (int)(getProgress() * 100)); + debug(9, "\nSavesSyncRequest: downloading %s (%d %%)", _currentDownloadingFile.name().c_str(), (int)(getProgress() * 100)); _workingRequest = _storage->downloadById( _currentDownloadingFile.id(), DefaultSaveFileManager::concatWithSavesPath(_currentDownloadingFile.name()), @@ -247,7 +288,7 @@ void SavesSyncRequest::downloadNextFile() { new Common::Callback(this, &SavesSyncRequest::fileDownloadedErrorCallback) ); if (!_workingRequest) - finishError(Networking::ErrorResponse(this)); + finishError(Networking::ErrorResponse(this, "SavesSyncRequest::downloadNextFile: Storage couldn't create Request to download a file")); } void SavesSyncRequest::fileDownloadedCallback(Storage::BoolResponse response) { @@ -259,7 +300,7 @@ void SavesSyncRequest::fileDownloadedCallback(Storage::BoolResponse response) { if (!response.value) { //delete the incomplete file g_system->getSavefileManager()->removeSavefile(_currentDownloadingFile.name()); - finishError(Networking::ErrorResponse(this, false, true, "", -1)); + finishError(Networking::ErrorResponse(this, false, true, "SavesSyncRequest::fileDownloadedCallback: failed to download a file", -1)); return; } @@ -290,7 +331,7 @@ void SavesSyncRequest::uploadNextFile() { _currentUploadingFile = _filesToUpload.back(); _filesToUpload.pop_back(); - debug(9, "SavesSyncRequest: uploading %s (%d %%)", _currentUploadingFile.c_str(), (int)(getProgress() * 100)); + debug(9, "\nSavesSyncRequest: uploading %s (%d %%)", _currentUploadingFile.c_str(), (int)(getProgress() * 100)); if (_storage->uploadStreamSupported()) { _workingRequest = _storage->upload( _storage->savesDirectoryPath() + _currentUploadingFile, @@ -306,7 +347,7 @@ void SavesSyncRequest::uploadNextFile() { new Common::Callback(this, &SavesSyncRequest::fileUploadedErrorCallback) ); } - if (!_workingRequest) finishError(Networking::ErrorResponse(this)); + if (!_workingRequest) finishError(Networking::ErrorResponse(this, "SavesSyncRequest::uploadNextFile: Storage couldn't create Request to upload a file")); } void SavesSyncRequest::fileUploadedCallback(Storage::UploadResponse response) { diff --git a/backends/cloud/storage.cpp b/backends/cloud/storage.cpp index 3a9ae53a430..753c26c03df 100644 --- a/backends/cloud/storage.cpp +++ b/backends/cloud/storage.cpp @@ -34,10 +34,18 @@ namespace Cloud { Storage::Storage(): _runningRequestsCount(0), _savesSyncRequest(nullptr), _syncRestartRequestsed(false), - _downloadFolderRequest(nullptr) {} + _downloadFolderRequest(nullptr), _isEnabled(false) {} Storage::~Storage() {} +bool Storage::isEnabled() const { + return _isEnabled; +} + +void Storage::enable() { + _isEnabled = true; +} + Networking::ErrorCallback Storage::getErrorPrintingCallback() { return new Common::Callback(this, &Storage::printErrorResponse); } @@ -121,6 +129,12 @@ Networking::Request *Storage::downloadById(Common::String remoteId, Common::Stri } Networking::Request *Storage::downloadFolder(Common::String remotePath, Common::String localPath, FileArrayCallback callback, Networking::ErrorCallback errorCallback, bool recursive) { + if (!_isEnabled) { + warning("Storage::downloadFolder: cannot be run while Storage is disabled"); + if (errorCallback) + (*errorCallback)(Networking::ErrorResponse(nullptr, false, true, "Storage is disabled.", -1)); + return nullptr; + } if (!errorCallback) errorCallback = getErrorPrintingCallback(); return addRequest(new FolderDownloadRequest(this, callback, errorCallback, remotePath, localPath, recursive)); @@ -128,6 +142,13 @@ Networking::Request *Storage::downloadFolder(Common::String remotePath, Common:: SavesSyncRequest *Storage::syncSaves(BoolCallback callback, Networking::ErrorCallback errorCallback) { _runningRequestsMutex.lock(); + if (!_isEnabled) { + warning("Storage::syncSaves: cannot be run while Storage is disabled"); + if (errorCallback) + (*errorCallback)(Networking::ErrorResponse(nullptr, false, true, "Storage is disabled.", -1)); + _runningRequestsMutex.unlock(); + return nullptr; + } if (_savesSyncRequest) { warning("Storage::syncSaves: there is a sync in progress already"); _syncRestartRequestsed = true; @@ -208,7 +229,6 @@ void Storage::savesSyncDefaultCallback(BoolResponse response) { if (!response.value) warning("SavesSyncRequest called success callback with `false` argument"); - Common::OSDMessageQueue::instance().addMessage(_("Saved games sync complete.")); } void Storage::savesSyncDefaultErrorCallback(Networking::ErrorResponse error) { diff --git a/backends/cloud/storage.h b/backends/cloud/storage.h index e914834daea..aa6455b8419 100644 --- a/backends/cloud/storage.h +++ b/backends/cloud/storage.h @@ -70,6 +70,9 @@ protected: /** FolderDownloadRequest-related */ FolderDownloadRequest *_downloadFolderRequest; + /** Whether user manually enabled the Storage. */ + bool _isEnabled; + /** Returns default error callback (printErrorResponse). */ virtual Networking::ErrorCallback getErrorPrintingCallback(); @@ -115,6 +118,16 @@ public: */ virtual Common::String name() const = 0; + /** + * Return whether Storage has been manually enabled by user. + */ + bool isEnabled() const; + + /** + * Set _isEnabled to true. + */ + void enable(); + /** * Public Cloud API comes down there. * diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp index 2b8151d579d..90834420248 100644 --- a/backends/events/sdl/sdl-events.cpp +++ b/backends/events/sdl/sdl-events.cpp @@ -661,6 +661,10 @@ bool SdlEventSource::dispatchSDLEvent(SDL_Event &ev, Common::Event &event) { event.path = Common::String(ev.drop.file); SDL_free(ev.drop.file); return true; + + case SDL_CLIPBOARDUPDATE: + event.type = Common::EVENT_CLIPBOARD_UPDATE; + return true; #else case SDL_VIDEOEXPOSE: if (_graphicsManager) diff --git a/backends/fs/abstract-fs.h b/backends/fs/abstract-fs.h index 28ea3bbecd7..8b2c1c107de 100644 --- a/backends/fs/abstract-fs.h +++ b/backends/fs/abstract-fs.h @@ -193,13 +193,11 @@ public: virtual Common::WriteStream *createWriteStream() = 0; /** - * Creates a file referred by this node. + * Creates a directory referred by this node. * - * @param isDirectoryFlag true if created file must be a directory - * - * @return true if file is created successfully + * @return true if the directory is created successfully */ - virtual bool create(bool isDirectoryFlag) = 0; + virtual bool createDirectory() = 0; }; diff --git a/backends/fs/amigaos4/amigaos4-fs.cpp b/backends/fs/amigaos4/amigaos4-fs.cpp index 134193a65b0..3561303b6db 100644 --- a/backends/fs/amigaos4/amigaos4-fs.cpp +++ b/backends/fs/amigaos4/amigaos4-fs.cpp @@ -443,9 +443,9 @@ Common::WriteStream *AmigaOSFilesystemNode::createWriteStream() { return StdioStream::makeFromPath(getPath(), true); } -bool AmigaOSFilesystemNode::create(bool isDirectoryFlag) { - error("Not supported"); - return false; +bool AmigaOSFilesystemNode::createDirectory() { + warning("AmigaOSFilesystemNode::createDirectory(): Not supported"); + return _bIsValid && _bIsDirectory; } #endif //defined(__amigaos4__) diff --git a/backends/fs/amigaos4/amigaos4-fs.h b/backends/fs/amigaos4/amigaos4-fs.h index c86bb4c57a5..75d8d013627 100644 --- a/backends/fs/amigaos4/amigaos4-fs.h +++ b/backends/fs/amigaos4/amigaos4-fs.h @@ -116,7 +116,7 @@ public: virtual Common::SeekableReadStream *createReadStream(); virtual Common::WriteStream *createWriteStream(); - virtual bool create(bool isDirectoryFlag); + virtual bool createDirectory(); }; diff --git a/backends/fs/chroot/chroot-fs.cpp b/backends/fs/chroot/chroot-fs.cpp index c10cc0b880d..bd1f93ae775 100644 --- a/backends/fs/chroot/chroot-fs.cpp +++ b/backends/fs/chroot/chroot-fs.cpp @@ -22,16 +22,6 @@ #if defined(POSIX) -// Re-enable some forbidden symbols to avoid clashes with stat.h and unistd.h. -// Also with clock() in sys/time.h in some Mac OS X SDKs. -#define FORBIDDEN_SYMBOL_EXCEPTION_time_h -#define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h -#define FORBIDDEN_SYMBOL_EXCEPTION_mkdir -#define FORBIDDEN_SYMBOL_EXCEPTION_getenv -#define FORBIDDEN_SYMBOL_EXCEPTION_exit //Needed for IRIX's unistd.h -#define FORBIDDEN_SYMBOL_EXCEPTION_random -#define FORBIDDEN_SYMBOL_EXCEPTION_srandom - #include "backends/fs/chroot/chroot-fs.h" ChRootFilesystemNode::ChRootFilesystemNode(const Common::String &root, POSIXFilesystemNode *node) { @@ -110,9 +100,8 @@ Common::WriteStream *ChRootFilesystemNode::createWriteStream() { return _realNode->createWriteStream(); } -bool ChRootFilesystemNode::create(bool isDirectoryFlag) { - error("Not supported"); - return false; +bool ChRootFilesystemNode::createDirectory() { + return _realNode->createDirectory(); } Common::String ChRootFilesystemNode::addPathComponent(const Common::String &path, const Common::String &component) { diff --git a/backends/fs/chroot/chroot-fs.h b/backends/fs/chroot/chroot-fs.h index 76902bc92a8..66cbcbe700f 100644 --- a/backends/fs/chroot/chroot-fs.h +++ b/backends/fs/chroot/chroot-fs.h @@ -49,7 +49,7 @@ public: virtual Common::SeekableReadStream *createReadStream(); virtual Common::WriteStream *createWriteStream(); - virtual bool create(bool isDirectoryFlag); + virtual bool createDirectory(); private: static Common::String addPathComponent(const Common::String &path, const Common::String &component); diff --git a/backends/fs/posix/posix-fs.cpp b/backends/fs/posix/posix-fs.cpp index c99505cc4da..e16c5e6e8f2 100644 --- a/backends/fs/posix/posix-fs.cpp +++ b/backends/fs/posix/posix-fs.cpp @@ -33,7 +33,7 @@ #define FORBIDDEN_SYMBOL_EXCEPTION_srandom #include "backends/fs/posix/posix-fs.h" -#include "backends/fs/stdiostream.h" +#include "backends/fs/posix/posix-iostream.h" #include "common/algorithm.h" #include @@ -91,13 +91,13 @@ POSIXFilesystemNode::POSIXFilesystemNode(const Common::String &p) { #endif // Expand "~/" to the value of the HOME env variable - if (p.hasPrefix("~/")) { + if (p.hasPrefix("~/") || p == "~") { const char *home = getenv("HOME"); if (home != NULL && strlen(home) < MAXPATHLEN) { _path = home; - // Skip over the tilda. We know that p contains at least - // two chars, so this is safe: - _path += p.c_str() + 1; + // Skip over the tilda. + if (p.size() > 1) + _path += p.c_str() + 1; } } else { _path = p; @@ -292,40 +292,18 @@ AbstractFSNode *POSIXFilesystemNode::getParent() const { } Common::SeekableReadStream *POSIXFilesystemNode::createReadStream() { - return StdioStream::makeFromPath(getPath(), false); + return PosixIoStream::makeFromPath(getPath(), false); } Common::WriteStream *POSIXFilesystemNode::createWriteStream() { - return StdioStream::makeFromPath(getPath(), true); + return PosixIoStream::makeFromPath(getPath(), true); } -bool POSIXFilesystemNode::create(bool isDirectoryFlag) { - bool success; - - if (isDirectoryFlag) { - success = mkdir(_path.c_str(), 0755) == 0; - } else { - int fd = open(_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0755); - success = fd >= 0; - - if (fd >= 0) { - close(fd); - } - } - - if (success) { +bool POSIXFilesystemNode::createDirectory() { + if (mkdir(_path.c_str(), 0755) == 0) setFlags(); - if (_isValid) { - if (_isDirectory != isDirectoryFlag) warning("failed to create %s: got %s", isDirectoryFlag ? "directory" : "file", _isDirectory ? "directory" : "file"); - return _isDirectory == isDirectoryFlag; - } - warning("POSIXFilesystemNode: %s() was a success, but stat indicates there is no such %s", - isDirectoryFlag ? "mkdir" : "creat", isDirectoryFlag ? "directory" : "file"); - return false; - } - - return false; + return _isValid && _isDirectory; } namespace Posix { diff --git a/backends/fs/posix/posix-fs.h b/backends/fs/posix/posix-fs.h index 5ad26ff0275..9751ab74f65 100644 --- a/backends/fs/posix/posix-fs.h +++ b/backends/fs/posix/posix-fs.h @@ -68,7 +68,7 @@ public: virtual Common::SeekableReadStream *createReadStream(); virtual Common::WriteStream *createWriteStream(); - virtual bool create(bool isDirectoryFlag); + virtual bool createDirectory(); private: /** diff --git a/backends/fs/posix/posix-iostream.cpp b/backends/fs/posix/posix-iostream.cpp new file mode 100644 index 00000000000..59f14142b58 --- /dev/null +++ b/backends/fs/posix/posix-iostream.cpp @@ -0,0 +1,56 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "backends/fs/posix/posix-iostream.h" + +#include + +PosixIoStream *PosixIoStream::makeFromPath(const Common::String &path, bool writeMode) { + FILE *handle = fopen(path.c_str(), writeMode ? "wb" : "rb"); + + if (handle) + return new PosixIoStream(handle); + + return nullptr; +} + +PosixIoStream::PosixIoStream(void *handle) : + StdioStream(handle) { +} + +int32 PosixIoStream::size() const { + int fd = fileno((FILE *)_handle); + if (fd == -1) { + return StdioStream::size(); + } + + // Using fstat to obtain the file size is generally faster than fseek / ftell + // because it does not affect the IO buffer. + struct stat st; + if (fstat(fd, &st) == -1) { + return StdioStream::size(); + } + + return st.st_size; +} diff --git a/backends/fs/posix/posix-iostream.h b/backends/fs/posix/posix-iostream.h new file mode 100644 index 00000000000..638d7b17cd1 --- /dev/null +++ b/backends/fs/posix/posix-iostream.h @@ -0,0 +1,39 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef BACKENDS_FS_POSIX_POSIXIOSTREAM_H +#define BACKENDS_FS_POSIX_POSIXIOSTREAM_H + +#include "backends/fs/stdiostream.h" + +/** + * A file input / output stream using POSIX interfaces + */ +class PosixIoStream : public StdioStream { +public: + static PosixIoStream *makeFromPath(const Common::String &path, bool writeMode); + PosixIoStream(void *handle); + + int32 size() const override; +}; + +#endif diff --git a/backends/fs/riscos/riscos-fs-factory.cpp b/backends/fs/riscos/riscos-fs-factory.cpp index b698bcb9082..7069ea92b82 100644 --- a/backends/fs/riscos/riscos-fs-factory.cpp +++ b/backends/fs/riscos/riscos-fs-factory.cpp @@ -20,11 +20,13 @@ * */ -#if defined(RISCOS) - // Re-enable some forbidden symbols to avoid clashes with stat.h and unistd.h. #define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h +#include "common/scummsys.h" + +#if defined(RISCOS) + #include "backends/fs/riscos/riscos-fs-factory.h" #include "backends/fs/riscos/riscos-fs.h" diff --git a/backends/fs/riscos/riscos-fs.cpp b/backends/fs/riscos/riscos-fs.cpp index 6f195691a05..5979ee4a5f0 100644 --- a/backends/fs/riscos/riscos-fs.cpp +++ b/backends/fs/riscos/riscos-fs.cpp @@ -20,23 +20,21 @@ * */ -#if defined(RISCOS) - // Re-enable some forbidden symbols to avoid clashes with stat.h and unistd.h. #define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h -#define FORBIDDEN_SYMBOL_EXCEPTION_mkdir + +#include "common/scummsys.h" + +#if defined(RISCOS) #include "backends/platform/sdl/riscos/riscos-utils.h" #include "backends/fs/riscos/riscos-fs.h" #include "backends/fs/stdiostream.h" #include "common/algorithm.h" -#include -#include +// TODO: Replace use of access() #include -#include -#include #include #include @@ -52,23 +50,33 @@ bool RISCOSFilesystemNode::isWritable() const { return access(_path.c_str(), W_OK) == 0; } -RISCOSFilesystemNode::RISCOSFilesystemNode(const Common::String &p) { - _path = p; - if (p == "/") { +void RISCOSFilesystemNode::setFlags() { + _kernel_swi_regs regs; + regs.r[0] = 23; + regs.r[1] = (int)_nativePath.c_str(); + _kernel_swi(OS_File, ®s, ®s); + + if (regs.r[0] == 0) { + _isDirectory = false; + _isValid = false; + } else if (regs.r[0] == 2) { _isDirectory = true; _isValid = true; } else { - int type = _swi(OS_File, _INR(0,1)|_RETURN(0), 20, RISCOS_Utils::toRISCOS(_path).c_str()); - if (type == 0) { - _isDirectory = false; - _isValid = false; - } else if (type == 2) { - _isDirectory = true; - _isValid = true; - } else { - _isDirectory = false; - _isValid = true; - } + _isDirectory = false; + _isValid = true; + } +} + +RISCOSFilesystemNode::RISCOSFilesystemNode(const Common::String &p) { + _path = p; + if (p == "/") { + _nativePath = ""; + _isDirectory = true; + _isValid = true; + } else { + _nativePath = RISCOS_Utils::toRISCOS(p); + setFlags(); } } @@ -94,47 +102,60 @@ bool RISCOSFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bo if (_path == "/") { // Special case for the root dir: List all drives - char fsname[PATH_MAX] = ""; + char fsname[MAXPATHLEN] = ""; for (int fsNum = 0; fsNum < 256; fsNum += 1) { - _swi(OS_FSControl, _INR(0,3), 33, fsNum, fsname, sizeof(fsname)); - if (strcmp(fsname, "") != 0) { - if (!(fsNum == 46 || fsNum == 53 || fsNum == 99)) { - int drives = 9; - if (fsNum == 193) - drives = 23; + if (fsNum == 33 || fsNum == 46 || fsNum == 53 || fsNum == 99) + continue; - for (int discnum = 0; discnum <= drives; discnum += 1) { - const Common::String path = Common::String::format("%s::%d.$", fsname, discnum); - char outpath[PATH_MAX] = ""; - if(_swix(OS_FSControl, _INR(0,2)|_IN(5), 37, path.c_str(), outpath, sizeof(outpath)) == NULL) { - int exist; - if (_swix(OS_File, _INR(0,1)|_OUT(0), 23, outpath, &exist) != NULL || exist != 2) - continue; + _kernel_swi_regs regs; + regs.r[0] = 33; + regs.r[1] = fsNum; + regs.r[2] = (int)fsname; + regs.r[3] = sizeof(fsname); + _kernel_swi(OS_FSControl, ®s, ®s); + if (fsname[0] == 0) + continue; - RISCOSFilesystemNode *entry = new RISCOSFilesystemNode(); - entry->_isDirectory = true; - entry->_isValid = true; - entry->_path = Common::String::format("/%s", outpath); - entry->_displayName = outpath; - myList.push_back(entry); - } - } - } + int drives = (fsNum == 193) ? 23 : 9; + + for (int discnum = 0; discnum <= drives; discnum += 1) { + const Common::String path = Common::String::format("%s::%d.$", fsname, discnum); + char outpath[MAXPATHLEN] = ""; + regs.r[0] = 37; + regs.r[1] = (int)path.c_str(); + regs.r[2] = (int)outpath; + regs.r[3] = 0; + regs.r[4] = 0; + regs.r[5] = sizeof(outpath); + if (_kernel_swi(OS_FSControl, ®s, ®s) != NULL) + continue; + + RISCOSFilesystemNode *entry = new RISCOSFilesystemNode(); + entry->_nativePath = outpath; + entry->_path = Common::String('/') + outpath; + entry->_displayName = outpath; + entry->setFlags(); + if (entry->_isDirectory) + myList.push_back(entry); } } return true; } - int count = 0; - int read = 0; - char file[PATH_MAX]; - Common::String dir = _path; + char file[MAXPATHLEN]; + _kernel_swi_regs regs; + regs.r[0] = 9; + regs.r[1] = (int)_nativePath.c_str(); + regs.r[2] = (int)file; + regs.r[3] = 1; + regs.r[4] = 0; + regs.r[5] = sizeof(file); + regs.r[6] = 0; + while (regs.r[4] != -1) { + _kernel_swi(OS_GBPB, ®s, ®s); - while (count != -1) { - _swix(OS_GBPB, _INR(0,5)|_OUTR(3,4), 9, RISCOS_Utils::toRISCOS(dir).c_str(), file, 1, count, sizeof(file), &read, &count); - - if (count == -1) - continue; + if (regs.r[4] == -1) + break; // Start with a clone of this node, with the correct path set RISCOSFilesystemNode entry(*this); @@ -143,15 +164,10 @@ bool RISCOSFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bo if (_path.lastChar() != '/') entry._path += '/'; entry._path += entry._displayName; - - int type = _swi(OS_File, _INR(0,1)|_RETURN(0), 20, RISCOS_Utils::toRISCOS(entry._path).c_str()); - if (type == 0) { + entry._nativePath = RISCOS_Utils::toRISCOS(entry._path); + entry.setFlags(); + if (!entry._isValid) continue; - } else if (type == 2) { - entry._isDirectory = true; - } else { - entry._isDirectory = false; - } // Honor the chosen mode if ((mode == Common::FSNode::kListFilesOnly && entry._isDirectory) || @@ -198,33 +214,14 @@ Common::WriteStream *RISCOSFilesystemNode::createWriteStream() { return StdioStream::makeFromPath(getPath(), true); } -bool RISCOSFilesystemNode::create(bool isDirectoryFlag) { - bool success; +bool RISCOSFilesystemNode::createDirectory() { + _kernel_swi_regs regs; + regs.r[0] = 8; + regs.r[1] = (int)_nativePath.c_str(); + if (_kernel_swi(OS_File, ®s, ®s) == NULL) + setFlags(); - if (isDirectoryFlag) { - success = _swix(OS_File, _INR(0,1), 8, RISCOS_Utils::toRISCOS(_path).c_str()) == NULL; - } else { - int fd = open(_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0755); - success = fd >= 0; - - if (fd >= 0) { - close(fd); - } - } - - if (success) { - if (exists()) { - _isDirectory = _swi(OS_File, _INR(0,1)|_RETURN(0), 20, RISCOS_Utils::toRISCOS(_path).c_str()) == 2; - if (_isDirectory != isDirectoryFlag) warning("failed to create %s: got %s", isDirectoryFlag ? "directory" : "file", _isDirectory ? "directory" : "file"); - return _isDirectory == isDirectoryFlag; - } - - warning("RISCOSFilesystemNode: Attempting to create a %s was a success, but access indicates there is no such %s", - isDirectoryFlag ? "directory" : "file", isDirectoryFlag ? "directory" : "file"); - return false; - } - - return false; + return _isValid && _isDirectory; } namespace Riscos { @@ -270,7 +267,7 @@ bool assureDirectoryExists(const Common::String &dir, const char *prefix) { } node = new RISCOSFilesystemNode(path); - if (!node->create(true)) { + if (!node->createDirectory()) { if (node->exists()) { if (!node->isDirectory()) { return false; diff --git a/backends/fs/riscos/riscos-fs.h b/backends/fs/riscos/riscos-fs.h index 99fa1d59bed..e3640e57caa 100644 --- a/backends/fs/riscos/riscos-fs.h +++ b/backends/fs/riscos/riscos-fs.h @@ -33,6 +33,7 @@ class RISCOSFilesystemNode : public AbstractFSNode { protected: Common::String _displayName; + Common::String _nativePath; Common::String _path; bool _isDirectory; bool _isValid; @@ -67,7 +68,12 @@ public: virtual Common::SeekableReadStream *createReadStream(); virtual Common::WriteStream *createWriteStream(); - virtual bool create(bool isDirectoryFlag); + virtual bool createDirectory(); +private: + /** + * Tests and sets the _isValid and _isDirectory flags, using OS_File 20. + */ + virtual void setFlags(); }; namespace Riscos { diff --git a/backends/fs/windows/windows-fs.cpp b/backends/fs/windows/windows-fs.cpp index caf0e31360b..e69e72a7464 100644 --- a/backends/fs/windows/windows-fs.cpp +++ b/backends/fs/windows/windows-fs.cpp @@ -134,6 +134,12 @@ WindowsFilesystemNode::WindowsFilesystemNode(const Common::String &p, const bool _displayName = lastPathComponent(_path, '\\'); + setFlags(); + + _isPseudoRoot = false; +} + +void WindowsFilesystemNode::setFlags() { // Check whether it is a directory, and whether the file actually exists DWORD fileAttribs = GetFileAttributes(toUnicode(_path.c_str())); @@ -148,7 +154,6 @@ WindowsFilesystemNode::WindowsFilesystemNode(const Common::String &p, const bool _path += '\\'; } } - _isPseudoRoot = false; } AbstractFSNode *WindowsFilesystemNode::getChild(const Common::String &n) const { @@ -244,36 +249,11 @@ Common::WriteStream *WindowsFilesystemNode::createWriteStream() { return StdioStream::makeFromPath(getPath(), true); } -bool WindowsFilesystemNode::create(bool isDirectoryFlag) { - bool success; +bool WindowsFilesystemNode::createDirectory() { + if (CreateDirectory(toUnicode(_path.c_str()), NULL) != 0) + setFlags(); - if (isDirectoryFlag) { - success = CreateDirectory(toUnicode(_path.c_str()), NULL) != 0; - } else { - success = CreateFile(toUnicode(_path.c_str()), GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) != INVALID_HANDLE_VALUE; - } - - if (success) { - //this piece is copied from constructor, it checks that file exists and detects whether it's a directory - DWORD fileAttribs = GetFileAttributes(toUnicode(_path.c_str())); - if (fileAttribs != INVALID_FILE_ATTRIBUTES) { - _isDirectory = ((fileAttribs & FILE_ATTRIBUTE_DIRECTORY) != 0); - _isValid = true; - // Add a trailing slash, if necessary. - if (_isDirectory && _path.lastChar() != '\\') { - _path += '\\'; - } - - if (_isDirectory != isDirectoryFlag) warning("failed to create %s: got %s", isDirectoryFlag ? "directory" : "file", _isDirectory ? "directory" : "file"); - return _isDirectory == isDirectoryFlag; - } - - warning("WindowsFilesystemNode: Create%s() was a success, but GetFileAttributes() indicates there is no such %s", - isDirectoryFlag ? "Directory" : "File", isDirectoryFlag ? "directory" : "file"); - return false; - } - - return false; + return _isValid && _isDirectory; } #endif //#ifdef WIN32 diff --git a/backends/fs/windows/windows-fs.h b/backends/fs/windows/windows-fs.h index f907a4d0473..e2404dacbc3 100644 --- a/backends/fs/windows/windows-fs.h +++ b/backends/fs/windows/windows-fs.h @@ -84,7 +84,7 @@ public: virtual Common::SeekableReadStream *createReadStream(); virtual Common::WriteStream *createWriteStream(); - virtual bool create(bool isDirectoryFlag); + virtual bool createDirectory(); private: /** @@ -114,6 +114,11 @@ private: * @return str in Unicode format. */ static const TCHAR* toUnicode(const char *str); + + /** + * Tests and sets the _isValid and _isDirectory flags, using the GetFileAttributes() function. + */ + virtual void setFlags(); }; #endif diff --git a/backends/mixer/sdl/sdl-mixer.cpp b/backends/mixer/sdl/sdl-mixer.cpp index 0af0748a2aa..2a46d877b22 100644 --- a/backends/mixer/sdl/sdl-mixer.cpp +++ b/backends/mixer/sdl/sdl-mixer.cpp @@ -81,7 +81,7 @@ void SdlMixerManager::init() { warning("Could not open audio device: %s", SDL_GetError()); // The mixer is not marked as ready - _mixer = new Audio::MixerImpl(g_system, desired.freq); + _mixer = new Audio::MixerImpl(desired.freq); return; } @@ -96,7 +96,7 @@ void SdlMixerManager::init() { warning("Could not open audio device: %s", SDL_GetError()); // The mixer is not marked as ready - _mixer = new Audio::MixerImpl(g_system, desired.freq); + _mixer = new Audio::MixerImpl(desired.freq); return; } @@ -118,7 +118,7 @@ void SdlMixerManager::init() { error("SDL mixer output requires stereo output device"); #endif - _mixer = new Audio::MixerImpl(g_system, _obtained.freq); + _mixer = new Audio::MixerImpl(_obtained.freq); assert(_mixer); _mixer->setReady(true); diff --git a/backends/modular-backend.cpp b/backends/modular-backend.cpp index 0c3b83f8962..100457cecf0 100644 --- a/backends/modular-backend.cpp +++ b/backends/modular-backend.cpp @@ -20,8 +20,6 @@ * */ -#define FORBIDDEN_SYMBOL_EXCEPTION_exit - #include "backends/modular-backend.h" #include "backends/graphics/graphics.h" @@ -302,7 +300,3 @@ void ModularBackend::displayMessageOnOSD(const char *msg) { void ModularBackend::displayActivityIconOnOSD(const Graphics::Surface *icon) { _graphicsManager->displayActivityIconOnOSD(icon); } - -void ModularBackend::quit() { - exit(0); -} diff --git a/backends/modular-backend.h b/backends/modular-backend.h index 25004f0573c..911257ccbc1 100644 --- a/backends/modular-backend.h +++ b/backends/modular-backend.h @@ -40,6 +40,7 @@ class MutexManager; * OSystem::getMillis() * OSystem::delayMillis() * OSystem::getTimeAndDate() + * OSystem::quit() * * And, it should also initialize all the managers variables * declared in this class, or override their related functions. @@ -138,7 +139,6 @@ public: /** @name Miscellaneous */ //@{ - virtual void quit() override; virtual void displayMessageOnOSD(const char *msg) override; virtual void displayActivityIconOnOSD(const Graphics::Surface *icon) override; diff --git a/backends/module.mk b/backends/module.mk index df195f83172..b5a21d6cac6 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -17,6 +17,7 @@ ifdef USE_CLOUD ifdef USE_LIBCURL MODULE_OBJS += \ + cloud/basestorage.o \ cloud/cloudicon.o \ cloud/cloudmanager.o \ cloud/iso8601.o \ @@ -58,6 +59,7 @@ MODULE_OBJS += \ networking/curl/networkreadstream.o \ networking/curl/curlrequest.o \ networking/curl/curljsonrequest.o \ + networking/curl/postrequest.o \ networking/curl/request.o endif @@ -141,6 +143,7 @@ ifdef POSIX MODULE_OBJS += \ fs/posix/posix-fs.o \ fs/posix/posix-fs-factory.o \ + fs/posix/posix-iostream.o \ fs/chroot/chroot-fs-factory.o \ fs/chroot/chroot-fs.o \ plugins/posix/posix-provider.o \ @@ -191,6 +194,7 @@ ifdef PLAYSTATION3 MODULE_OBJS += \ fs/posix/posix-fs.o \ fs/posix/posix-fs-factory.o \ + fs/posix/posix-iostream.o \ fs/ps3/ps3-fs-factory.o \ events/ps3sdl/ps3sdl-events.o endif @@ -269,6 +273,7 @@ endif ifeq ($(BACKEND),psp2) MODULE_OBJS += \ fs/posix/posix-fs.o \ + fs/posix/posix-iostream.o \ fs/psp2/psp2-fs-factory.o \ fs/psp2/psp2-dirent.o \ events/psp2sdl/psp2sdl-events.o \ diff --git a/backends/networking/curl/connectionmanager.cpp b/backends/networking/curl/connectionmanager.cpp index 7698ddad144..21381d9a3d5 100644 --- a/backends/networking/curl/connectionmanager.cpp +++ b/backends/networking/curl/connectionmanager.cpp @@ -26,6 +26,7 @@ #include "backends/networking/curl/connectionmanager.h" #include "backends/networking/curl/networkreadstream.h" #include "common/debug.h" +#include "common/fs.h" #include "common/system.h" #include "common/timer.h" @@ -98,6 +99,29 @@ uint32 ConnectionManager::getCloudRequestsPeriodInMicroseconds() { return TIMER_INTERVAL * CLOUD_PERIOD; } +const char *ConnectionManager::getCaCertPath() { +#if defined(DATA_PATH) + static enum { + kNotInitialized, + kFileNotFound, + kFileExists + } state = kNotInitialized; + + if (state == kNotInitialized) { + Common::FSNode node(DATA_PATH"/cacert.pem"); + state = node.exists() ? kFileExists : kFileNotFound; + } + + if (state == kFileExists) { + return DATA_PATH"/cacert.pem"; + } else { + return nullptr; + } +#else + return nullptr; +#endif +} + //private goes here: void connectionsThread(void *ignored) { @@ -151,7 +175,8 @@ void ConnectionManager::interateRequests() { _addedRequestsMutex.unlock(); //call handle() of all running requests (so they can do their work) - debug(9, "handling %d request(s)", _requests.size()); + if (_frame % DEBUG_PRINT_PERIOD == 0) + debug(9, "handling %d request(s)", _requests.size()); for (Common::Array::iterator i = _requests.begin(); i != _requests.end();) { Request *request = i->request; if (request) { @@ -183,20 +208,19 @@ void ConnectionManager::processTransfers() { int messagesInQueue; CURLMsg *curlMsg; while ((curlMsg = curl_multi_info_read(_multi, &messagesInQueue))) { - CURL *easyHandle = curlMsg->easy_handle; - - NetworkReadStream *stream; - curl_easy_getinfo(easyHandle, CURLINFO_PRIVATE, &stream); - if (stream) - stream->finished(); - if (curlMsg->msg == CURLMSG_DONE) { - debug(9, "ConnectionManager: SUCCESS (%d - %s)", curlMsg->data.result, curl_easy_strerror(curlMsg->data.result)); - } else { - warning("ConnectionManager: FAILURE (CURLMsg (%d))", curlMsg->msg); - } + CURL *easyHandle = curlMsg->easy_handle; - curl_multi_remove_handle(_multi, easyHandle); + NetworkReadStream *stream = nullptr; + curl_easy_getinfo(easyHandle, CURLINFO_PRIVATE, &stream); + + if (stream) + stream->finished(curlMsg->data.result); + + curl_multi_remove_handle(_multi, easyHandle); + } else { + warning("Unknown libcurl message type %d", curlMsg->msg); + } } } diff --git a/backends/networking/curl/connectionmanager.h b/backends/networking/curl/connectionmanager.h index f6a9fcb36fc..a01d115c2c9 100644 --- a/backends/networking/curl/connectionmanager.h +++ b/backends/networking/curl/connectionmanager.h @@ -38,10 +38,11 @@ namespace Networking { class NetworkReadStream; class ConnectionManager : public Common::Singleton { - static const uint32 FRAMES_PER_SECOND = 20; + static const uint32 FRAMES_PER_SECOND = 25; static const uint32 TIMER_INTERVAL = 1000000 / FRAMES_PER_SECOND; - static const uint32 CLOUD_PERIOD = 20; //every 20th frame + static const uint32 CLOUD_PERIOD = 1; //every frame static const uint32 CURL_PERIOD = 1; //every frame + static const uint32 DEBUG_PRINT_PERIOD = FRAMES_PER_SECOND; // once per second friend void connectionsThread(void *); //calls handle() @@ -117,6 +118,9 @@ public: Common::String urlEncode(Common::String s) const; static uint32 getCloudRequestsPeriodInMicroseconds(); + + /** Return the path to the CA certificates bundle. */ + static const char *getCaCertPath(); }; /** Shortcut for accessing the connection manager. */ diff --git a/backends/networking/curl/curljsonrequest.h b/backends/networking/curl/curljsonrequest.h index 11c6bc81eaf..e462d5890fd 100644 --- a/backends/networking/curl/curljsonrequest.h +++ b/backends/networking/curl/curljsonrequest.h @@ -31,6 +31,7 @@ namespace Networking { typedef Response JsonResponse; typedef Common::BaseCallback *JsonCallback; +typedef Common::BaseCallback *JSONValueCallback; #define CURL_JSON_REQUEST_BUFFER_SIZE 512 * 1024 diff --git a/backends/networking/curl/curlrequest.cpp b/backends/networking/curl/curlrequest.cpp index a9de30cfe97..f7d169cdca5 100644 --- a/backends/networking/curl/curlrequest.cpp +++ b/backends/networking/curl/curlrequest.cpp @@ -53,7 +53,7 @@ void CurlRequest::handle() { if (_stream && _stream->eos()) { if (_stream->httpResponseCode() != 200) { warning("CurlRequest: HTTP response code is not 200 OK (it's %ld)", _stream->httpResponseCode()); - ErrorResponse error(this, false, true, "", _stream->httpResponseCode()); + ErrorResponse error(this, false, true, "HTTP response code is not 200 OK", _stream->httpResponseCode()); finishError(error); return; } @@ -71,20 +71,9 @@ void CurlRequest::restart() { Common::String CurlRequest::date() const { if (_stream) { - Common::String headers = _stream->responseHeaders(); - const char *cstr = headers.c_str(); - const char *position = strstr(cstr, "Date: "); - - if (position) { - Common::String result = ""; - char c; - for (const char *i = position + 6; c = *i, c != 0; ++i) { - if (c == '\n' || c == '\r') - break; - result += c; - } - return result; - } + Common::HashMap headers = _stream->responseHeadersMap(); + if (headers.contains("date")) + return headers["date"]; } return ""; } diff --git a/backends/networking/curl/networkreadstream.cpp b/backends/networking/curl/networkreadstream.cpp index ac8800b22a4..f7d2b5aa803 100644 --- a/backends/networking/curl/networkreadstream.cpp +++ b/backends/networking/curl/networkreadstream.cpp @@ -26,6 +26,7 @@ #include "backends/networking/curl/networkreadstream.h" #include "backends/networking/curl/connectionmanager.h" #include "base/version.h" +#include "common/debug.h" namespace Networking { @@ -64,6 +65,7 @@ int NetworkReadStream::curlProgressCallbackOlder(void *p, double dltotal, double void NetworkReadStream::init(const char *url, curl_slist *headersList, const byte *buffer, uint32 bufferSize, bool uploading, bool usingPatch, bool post) { _eos = _requestComplete = false; + _errorBuffer = (char *)calloc(CURL_ERROR_SIZE, 1); _sendingContentsBuffer = nullptr; _sendingContentsSize = _sendingContentsPos = 0; _progressDownloaded = _progressTotal = 0; @@ -77,6 +79,7 @@ void NetworkReadStream::init(const char *url, curl_slist *headersList, const byt curl_easy_setopt(_easy, CURLOPT_HEADERDATA, this); curl_easy_setopt(_easy, CURLOPT_HEADERFUNCTION, curlHeadersCallback); curl_easy_setopt(_easy, CURLOPT_URL, url); + curl_easy_setopt(_easy, CURLOPT_ERRORBUFFER, _errorBuffer); curl_easy_setopt(_easy, CURLOPT_VERBOSE, 0L); curl_easy_setopt(_easy, CURLOPT_FOLLOWLOCATION, 1L); //probably it's OK to have it always on curl_easy_setopt(_easy, CURLOPT_HTTPHEADER, headersList); @@ -84,6 +87,12 @@ void NetworkReadStream::init(const char *url, curl_slist *headersList, const byt curl_easy_setopt(_easy, CURLOPT_NOPROGRESS, 0L); curl_easy_setopt(_easy, CURLOPT_PROGRESSFUNCTION, curlProgressCallbackOlder); curl_easy_setopt(_easy, CURLOPT_PROGRESSDATA, this); + + const char *caCertPath = ConnMan.getCaCertPath(); + if (caCertPath) { + curl_easy_setopt(_easy, CURLOPT_CAINFO, caCertPath); + } + #if LIBCURL_VERSION_NUM >= 0x072000 // CURLOPT_XFERINFOFUNCTION introduced in libcurl 7.32.0 // CURLOPT_PROGRESSFUNCTION is used as a backup plan in case older version is used @@ -116,6 +125,7 @@ void NetworkReadStream::init(const char *url, curl_slist *headersList, const byt void NetworkReadStream::init(const char *url, curl_slist *headersList, Common::HashMap formFields, Common::HashMap formFiles) { _eos = _requestComplete = false; + _errorBuffer = (char *)calloc(CURL_ERROR_SIZE, 1); _sendingContentsBuffer = nullptr; _sendingContentsSize = _sendingContentsPos = 0; _progressDownloaded = _progressTotal = 0; @@ -129,6 +139,7 @@ void NetworkReadStream::init(const char *url, curl_slist *headersList, Common::H curl_easy_setopt(_easy, CURLOPT_HEADERDATA, this); curl_easy_setopt(_easy, CURLOPT_HEADERFUNCTION, curlHeadersCallback); curl_easy_setopt(_easy, CURLOPT_URL, url); + curl_easy_setopt(_easy, CURLOPT_ERRORBUFFER, _errorBuffer); curl_easy_setopt(_easy, CURLOPT_VERBOSE, 0L); curl_easy_setopt(_easy, CURLOPT_FOLLOWLOCATION, 1L); //probably it's OK to have it always on curl_easy_setopt(_easy, CURLOPT_HTTPHEADER, headersList); @@ -136,6 +147,12 @@ void NetworkReadStream::init(const char *url, curl_slist *headersList, Common::H curl_easy_setopt(_easy, CURLOPT_NOPROGRESS, 0L); curl_easy_setopt(_easy, CURLOPT_PROGRESSFUNCTION, curlProgressCallbackOlder); curl_easy_setopt(_easy, CURLOPT_PROGRESSDATA, this); + + const char *caCertPath = ConnMan.getCaCertPath(); + if (caCertPath) { + curl_easy_setopt(_easy, CURLOPT_CAINFO, caCertPath); + } + #if LIBCURL_VERSION_NUM >= 0x072000 // CURLOPT_XFERINFOFUNCTION introduced in libcurl 7.32.0 // CURLOPT_PROGRESSFUNCTION is used as a backup plan in case older version is used @@ -197,6 +214,7 @@ NetworkReadStream::~NetworkReadStream() { if (_easy) curl_easy_cleanup(_easy); free(_bufferCopy); + free(_errorBuffer); } bool NetworkReadStream::eos() const { @@ -215,8 +233,18 @@ uint32 NetworkReadStream::read(void *dataPtr, uint32 dataSize) { return actuallyRead; } -void NetworkReadStream::finished() { +void NetworkReadStream::finished(uint32 errorCode) { _requestComplete = true; + + char *url = nullptr; + curl_easy_getinfo(_easy, CURLINFO_EFFECTIVE_URL, &url); + + if (errorCode == CURLE_OK) { + debug(9, "NetworkReadStream: %s - Request succeeded", url); + } else { + warning("NetworkReadStream: %s - Request failed (%d - %s)", url, errorCode, + strlen(_errorBuffer) ? _errorBuffer : curl_easy_strerror((CURLcode)errorCode)); + } } long NetworkReadStream::httpResponseCode() const { @@ -240,6 +268,78 @@ Common::String NetworkReadStream::responseHeaders() const { return _responseHeaders; } +Common::HashMap NetworkReadStream::responseHeadersMap() const { + // HTTP headers are described at RFC 2616: https://tools.ietf.org/html/rfc2616#section-4.2 + // this implementation tries to follow it, but for simplicity it does not support multi-line header values + + Common::HashMap headers; + Common::String headerName, headerValue, trailingWhitespace; + char c; + bool readingName = true; + + for (uint i = 0; i < _responseHeaders.size(); ++i) { + c = _responseHeaders[i]; + + if (readingName) { + if (c == ' ' || c == '\r' || c == '\n' || c == '\t') { + // header names should not contain any whitespace, this is invalid + // ignore what's been before + headerName = ""; + continue; + } + if (c == ':') { + if (!headerName.empty()) { + readingName = false; + } + continue; + } + headerName += c; + continue; + } + + // reading value: + if (c == ' ' || c == '\t') { + if (headerValue.empty()) { + // skip leading whitespace + continue; + } else { + // accumulate trailing whitespace + trailingWhitespace += c; + continue; + } + } + + if (c == '\r' || c == '\n') { + // not sure if RFC allows empty values, we'll ignore such + if (!headerName.empty() && !headerValue.empty()) { + // add header value + // RFC allows header with the same name to be sent multiple times + // and requires it to be equivalent of just listing all header values separated with comma + // so if header already was met, we'll add new value to the old one + headerName.toLowercase(); + if (headers.contains(headerName)) { + headers[headerName] += "," + headerValue; + } else { + headers[headerName] = headerValue; + } + } + + headerName = ""; + headerValue = ""; + trailingWhitespace = ""; + readingName = true; + continue; + } + + // if we meet non-whitespace character, turns out those "trailing" whitespace characters were not so trailing + headerValue += trailingWhitespace; + trailingWhitespace = ""; + headerValue += c; + } + + return headers; +} + uint32 NetworkReadStream::fillWithSendingContents(char *bufferToFill, uint32 maxSize) { uint32 sendSize = _sendingContentsSize - _sendingContentsPos; if (sendSize > maxSize) diff --git a/backends/networking/curl/networkreadstream.h b/backends/networking/curl/networkreadstream.h index b83ab27400c..468fce70a4c 100644 --- a/backends/networking/curl/networkreadstream.h +++ b/backends/networking/curl/networkreadstream.h @@ -38,6 +38,7 @@ class NetworkReadStream: public Common::ReadStream { CURL *_easy; Common::MemoryReadWriteStream _backingStream; bool _eos, _requestComplete; + char *_errorBuffer; const byte *_sendingContentsBuffer; uint32 _sendingContentsSize; uint32 _sendingContentsPos; @@ -111,7 +112,7 @@ public: * * @note It's called on failure too. */ - void finished(); + void finished(uint32 errorCode); /** * Returns HTTP response code from inner CURL handle. @@ -136,6 +137,14 @@ public: */ Common::String responseHeaders() const; + /** + * Return response headers as HashMap. All header names in + * it are lowercase. + * + * @note This method should be called when eos() == true. + */ + Common::HashMap responseHeadersMap() const; + /** Returns a number in range [0, 1], where 1 is "complete". */ double getProgress() const; diff --git a/backends/networking/curl/request.cpp b/backends/networking/curl/request.cpp index 398af04f4b0..b8393f71383 100644 --- a/backends/networking/curl/request.cpp +++ b/backends/networking/curl/request.cpp @@ -24,8 +24,8 @@ namespace Networking { -ErrorResponse::ErrorResponse(Request *rq): - request(rq), interrupted(false), failed(true), response(""), httpResponseCode(-1) {} +ErrorResponse::ErrorResponse(Request *rq, Common::String resp): + request(rq), interrupted(false), failed(true), response(resp), httpResponseCode(-1) {} ErrorResponse::ErrorResponse(Request *rq, bool interrupt, bool failure, Common::String resp, long httpCode): request(rq), interrupted(interrupt), failed(failure), response(resp), httpResponseCode(httpCode) {} @@ -50,7 +50,7 @@ void Request::handleRetry() { void Request::pause() { _state = PAUSED; } void Request::finish() { - ErrorResponse error(this, true, false, "", -1); + ErrorResponse error(this, true, false, "Request::finish() was called (i.e. interrupted)", -1); finishError(error); } diff --git a/backends/networking/curl/request.h b/backends/networking/curl/request.h index b1261f23ee3..efddd150754 100644 --- a/backends/networking/curl/request.h +++ b/backends/networking/curl/request.h @@ -78,12 +78,12 @@ struct ErrorResponse { Common::String response; long httpResponseCode; - ErrorResponse(Request *rq); + ErrorResponse(Request *rq, Common::String resp); ErrorResponse(Request *rq, bool interrupt, bool failure, Common::String resp, long httpCode); }; -typedef Response DataReponse; -typedef Common::BaseCallback *DataCallback; +typedef Response DataResponse; +typedef Common::BaseCallback *DataCallback; typedef Common::BaseCallback *ErrorCallback; /** diff --git a/backends/networking/sdl_net/getclienthandler.cpp b/backends/networking/sdl_net/getclienthandler.cpp index ef085c60820..8e940a1a9cc 100644 --- a/backends/networking/sdl_net/getclienthandler.cpp +++ b/backends/networking/sdl_net/getclienthandler.cpp @@ -107,7 +107,7 @@ const char *GetClientHandler::responseMessage(long responseCode) { void GetClientHandler::prepareHeaders() { if (!_specialHeaders.contains("Content-Type")) - setHeader("Content-Type", "text/html"); + setHeader("Content-Type", "text/html; charset=UTF-8"); if (!_specialHeaders.contains("Content-Length") && _stream) setHeader("Content-Length", Common::String::format("%u", _stream->size())); diff --git a/backends/networking/sdl_net/handlers/createdirectoryhandler.cpp b/backends/networking/sdl_net/handlers/createdirectoryhandler.cpp index d315ad2ee3a..a1d1d9b7fc0 100644 --- a/backends/networking/sdl_net/handlers/createdirectoryhandler.cpp +++ b/backends/networking/sdl_net/handlers/createdirectoryhandler.cpp @@ -57,35 +57,35 @@ void CreateDirectoryHandler::handle(Client &client) { // check that is not an absolute root if (path == "" || path == "/") { - handleError(client, _("Can't create directory here!")); + handleError(client, HandlerUtils::toUtf8(_("Can't create directory here!"))); return; } // check that contains no '../' if (HandlerUtils::hasForbiddenCombinations(path)) { - handleError(client, _("Invalid path!")); + handleError(client, HandlerUtils::toUtf8(_("Invalid path!"))); return; } // transform virtual path to actual file system one Common::String prefixToRemove = "", prefixToAdd = ""; if (!transformPath(path, prefixToRemove, prefixToAdd) || path.empty()) { - handleError(client, _("Invalid path!")); + handleError(client, HandlerUtils::toUtf8(_("Invalid path!"))); return; } // check that exists, is directory and isn't forbidden AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(path); if (!HandlerUtils::permittedPath(node->getPath())) { - handleError(client, _("Invalid path!")); + handleError(client, HandlerUtils::toUtf8(_("Invalid path!"))); return; } if (!node->exists()) { - handleError(client, _("Parent directory doesn't exists!")); + handleError(client, HandlerUtils::toUtf8(_("Parent directory doesn't exists!"))); return; } if (!node->isDirectory()) { - handleError(client, _("Can't create a directory within a file!")); + handleError(client, HandlerUtils::toUtf8(_("Can't create a directory within a file!"))); return; } @@ -95,20 +95,20 @@ void CreateDirectoryHandler::handle(Client &client) { node = g_system->getFilesystemFactory()->makeFileNodePath(path + name); if (node->exists()) { if (!node->isDirectory()) { - handleError(client, _("There is a file with that name in the parent directory!")); + handleError(client, HandlerUtils::toUtf8(_("There is a file with that name in the parent directory!"))); return; } } else { // create the in - if (!node->create(true)) { - handleError(client, _("Failed to create the directory!")); + if (!node->createDirectory()) { + handleError(client, HandlerUtils::toUtf8(_("Failed to create the directory!"))); return; } } // if json requested, respond with it if (client.queryParameter("answer_json") == "true") { - setJsonResponseHandler(client, "success", _("Directory created successfully!")); + setJsonResponseHandler(client, "success", HandlerUtils::toUtf8(_("Directory created successfully!"))); return; } @@ -117,9 +117,9 @@ void CreateDirectoryHandler::handle(Client &client) { client, Common::String::format( "%s
%s", - _("Directory created successfully!"), + HandlerUtils::toUtf8(_("Directory created successfully!")).c_str(), client.queryParameter("path").c_str(), - _("Back to parent directory") + HandlerUtils::toUtf8(_("Back to parent directory")).c_str() ), (client.queryParameter("ajax") == "true" ? "/filesAJAX?path=" : "/files?path=") + LocalWebserver::urlEncodeQueryParameterValue(client.queryParameter("path")) diff --git a/backends/networking/sdl_net/handlers/downloadfilehandler.cpp b/backends/networking/sdl_net/handlers/downloadfilehandler.cpp index 281be2d27f6..8f434ed75e9 100644 --- a/backends/networking/sdl_net/handlers/downloadfilehandler.cpp +++ b/backends/networking/sdl_net/handlers/downloadfilehandler.cpp @@ -40,40 +40,40 @@ void DownloadFileHandler::handle(Client &client) { // check that is not an absolute root if (path == "" || path == "/") { - HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Invalid path!")); + HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("Invalid path!"))); return; } // check that contains no '../' if (HandlerUtils::hasForbiddenCombinations(path)) { - HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Invalid path!")); + HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("Invalid path!"))); return; } // transform virtual path to actual file system one Common::String prefixToRemove = "", prefixToAdd = ""; if (!transformPath(path, prefixToRemove, prefixToAdd, false) || path.empty()) { - HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Invalid path!")); + HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("Invalid path!"))); return; } // check that exists, is directory and isn't forbidden AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(path); if (!HandlerUtils::permittedPath(node->getPath())) { - HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Invalid path!")); + HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("Invalid path!"))); return; } if (!node->exists()) { - HandlerUtils::setFilesManagerErrorMessageHandler(client, _("The file doesn't exist!")); + HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("The file doesn't exist!"))); return; } if (node->isDirectory()) { - HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Can't download a directory!")); + HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("Can't download a directory!"))); return; } Common::SeekableReadStream *stream = node->createReadStream(); if (stream == nullptr) { - HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Failed to read the file!")); + HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("Failed to read the file!"))); return; } diff --git a/backends/networking/sdl_net/handlers/filesajaxpagehandler.cpp b/backends/networking/sdl_net/handlers/filesajaxpagehandler.cpp index 55b7a62dd15..525418f09e0 100644 --- a/backends/networking/sdl_net/handlers/filesajaxpagehandler.cpp +++ b/backends/networking/sdl_net/handlers/filesajaxpagehandler.cpp @@ -56,7 +56,7 @@ void FilesAjaxPageHandler::handle(Client &client) { // load stylish response page from the archive Common::SeekableReadStream *const stream = HandlerUtils::getArchiveFile(FILES_PAGE_NAME); if (stream == nullptr) { - HandlerUtils::setFilesManagerErrorMessageHandler(client, _("The page is not available without the resources.")); + HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("The page is not available without the resources. Make sure file wwwroot.zip from ResidualVM distribution is available in 'themepath'."))); return; } @@ -64,16 +64,16 @@ void FilesAjaxPageHandler::handle(Client &client) { Common::String path = client.queryParameter("path"); //these occur twice: - replace(response, "{create_directory_button}", _("Create directory")); - replace(response, "{create_directory_button}", _("Create directory")); - replace(response, "{upload_files_button}", _("Upload files")); //tab - replace(response, "{upload_file_button}", _("Upload files")); //button in the tab - replace(response, "{create_directory_desc}", _("Type new directory name:")); - replace(response, "{upload_file_desc}", _("Select a file to upload:")); - replace(response, "{or_upload_directory_desc}", _("Or select a directory (works in Chrome only):")); - replace(response, "{index_of}", _("Index of ")); - replace(response, "{loading}", _("Loading...")); - replace(response, "{error}", _("Error occurred")); + replace(response, "{create_directory_button}", HandlerUtils::toUtf8(_("Create directory"))); + replace(response, "{create_directory_button}", HandlerUtils::toUtf8(_("Create directory"))); + replace(response, "{upload_files_button}", HandlerUtils::toUtf8(_("Upload files"))); //tab + replace(response, "{upload_file_button}", HandlerUtils::toUtf8(_("Upload files"))); //button in the tab + replace(response, "{create_directory_desc}", HandlerUtils::toUtf8(_("Type new directory name:"))); + replace(response, "{upload_file_desc}", HandlerUtils::toUtf8(_("Select a file to upload:"))); + replace(response, "{or_upload_directory_desc}", HandlerUtils::toUtf8(_("Or select a directory (works in Chrome only):"))); + replace(response, "{index_of}", HandlerUtils::toUtf8(_("Index of "))); + replace(response, "{loading}", HandlerUtils::toUtf8(("Loading..."))); + replace(response, "{error}", HandlerUtils::toUtf8(_("Error occurred"))); replace(response, "{start_path}", encodeDoubleQuotesAndSlashes(path)); LocalWebserver::setClientGetHandler(client, response); } diff --git a/backends/networking/sdl_net/handlers/filespagehandler.cpp b/backends/networking/sdl_net/handlers/filespagehandler.cpp index 8aee803c0fd..c8fd2f37a38 100644 --- a/backends/networking/sdl_net/handlers/filespagehandler.cpp +++ b/backends/networking/sdl_net/handlers/filespagehandler.cpp @@ -78,8 +78,8 @@ Common::String getDisplayPath(Common::String s) { bool FilesPageHandler::listDirectory(Common::String path, Common::String &content, const Common::String &itemTemplate) { if (path == "" || path == "/") { if (ConfMan.hasKey("rootpath", "cloud")) - addItem(content, itemTemplate, IT_DIRECTORY, "/root/", _("File system root")); - addItem(content, itemTemplate, IT_DIRECTORY, "/saves/", _("Saved games")); + addItem(content, itemTemplate, IT_DIRECTORY, "/root/", HandlerUtils::toUtf8(_("File system root"))); + addItem(content, itemTemplate, IT_DIRECTORY, "/saves/", HandlerUtils::toUtf8(_("Saved games"))); return true; } @@ -116,7 +116,7 @@ bool FilesPageHandler::listDirectory(Common::String path, Common::String &conten filePath = "/"; else filePath = parentPath(prefixToAdd + filePath); - addItem(content, itemTemplate, IT_PARENT_DIRECTORY, filePath, _("Parent directory")); + addItem(content, itemTemplate, IT_PARENT_DIRECTORY, filePath, HandlerUtils::toUtf8(_("Parent directory"))); } // fill the content @@ -182,7 +182,7 @@ void FilesPageHandler::addItem(Common::String &content, const Common::String &it void FilesPageHandler::handle(Client &client) { Common::String response = "" \ - "ScummVM" \ + "ResidualVM" \ "" \ "

{create_directory_desc}

" \ "
" \ @@ -215,21 +215,21 @@ void FilesPageHandler::handle(Client &client) { // show an error message if failed to list directory if (!listDirectory(path, content, itemTemplate)) { - HandlerUtils::setFilesManagerErrorMessageHandler(client, _("ResidualVM couldn't list the directory you specified.")); + HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("ResidualVM couldn't list the directory you specified."))); return; } //these occur twice: - replace(response, "{create_directory_button}", _("Create directory")); - replace(response, "{create_directory_button}", _("Create directory")); + replace(response, "{create_directory_button}", HandlerUtils::toUtf8(_("Create directory"))); + replace(response, "{create_directory_button}", HandlerUtils::toUtf8(_("Create directory"))); replace(response, "{path}", encodeDoubleQuotes(client.queryParameter("path"))); replace(response, "{path}", encodeDoubleQuotes(client.queryParameter("path"))); - replace(response, "{upload_files_button}", _("Upload files")); //tab - replace(response, "{upload_file_button}", _("Upload files")); //button in the tab - replace(response, "{create_directory_desc}", _("Type new directory name:")); - replace(response, "{upload_file_desc}", _("Select a file to upload:")); - replace(response, "{or_upload_directory_desc}", _("Or select a directory (works in Chrome only):")); - replace(response, "{index_of_directory}", Common::String::format(_("Index of %s"), encodeHtmlEntities(getDisplayPath(client.queryParameter("path"))).c_str())); + replace(response, "{upload_files_button}", HandlerUtils::toUtf8(_("Upload files"))); //tab + replace(response, "{upload_file_button}", HandlerUtils::toUtf8(_("Upload files"))); //button in the tab + replace(response, "{create_directory_desc}", HandlerUtils::toUtf8(_("Type new directory name:"))); + replace(response, "{upload_file_desc}", HandlerUtils::toUtf8(_("Select a file to upload:"))); + replace(response, "{or_upload_directory_desc}", HandlerUtils::toUtf8(_("Or select a directory (works in Chrome only):"))); + replace(response, "{index_of_directory}", Common::String::format("%s %s", HandlerUtils::toUtf8(_("Index of")).c_str(), encodeHtmlEntities(getDisplayPath(client.queryParameter("path"))).c_str())); replace(response, "{content}", content); LocalWebserver::setClientGetHandler(client, response); } diff --git a/backends/networking/sdl_net/handlers/indexpagehandler.cpp b/backends/networking/sdl_net/handlers/indexpagehandler.cpp index 51efd3cdd13..f872810bad4 100644 --- a/backends/networking/sdl_net/handlers/indexpagehandler.cpp +++ b/backends/networking/sdl_net/handlers/indexpagehandler.cpp @@ -24,7 +24,6 @@ #include "backends/networking/sdl_net/handlerutils.h" #include "backends/networking/sdl_net/localwebserver.h" #include "common/translation.h" -#include "gui/storagewizarddialog.h" namespace Networking { @@ -34,28 +33,17 @@ IndexPageHandler::~IndexPageHandler() {} /// public -Common::String IndexPageHandler::code() const { return _code; } - void IndexPageHandler::handle(Client &client) { - Common::String queryCode = client.queryParameter("code"); - - if (queryCode == "") { - // redirect to "/filesAJAX" - HandlerUtils::setMessageHandler( - client, - Common::String::format( - "%s
%s", - _("This is a local webserver index page."), - _("Open Files manager") - ), - "/filesAJAX" - ); - return; - } - - _code = queryCode; - sendCommand(GUI::kStorageCodePassedCmd, 0); - HandlerUtils::setMessageHandler(client, _("ResidualVM got the code and already connects to your cloud storage!")); + // redirect to "/filesAJAX" + HandlerUtils::setMessageHandler( + client, + Common::String::format( + "%s
%s", + HandlerUtils::toUtf8(_("This is a local webserver index page.")).c_str(), + HandlerUtils::toUtf8(_("Open Files manager")).c_str() + ), + "/filesAJAX" + ); } bool IndexPageHandler::minimalModeSupported() { diff --git a/backends/networking/sdl_net/handlers/indexpagehandler.h b/backends/networking/sdl_net/handlers/indexpagehandler.h index 0d8e6163959..b4841bcdcaa 100644 --- a/backends/networking/sdl_net/handlers/indexpagehandler.h +++ b/backends/networking/sdl_net/handlers/indexpagehandler.h @@ -30,12 +30,10 @@ namespace Networking { class LocalWebserver; class IndexPageHandler: public BaseHandler, public GUI::CommandSender { - Common::String _code; public: IndexPageHandler(); virtual ~IndexPageHandler(); - Common::String code() const; virtual void handle(Client &client); virtual bool minimalModeSupported(); }; diff --git a/backends/networking/sdl_net/handlers/listajaxhandler.cpp b/backends/networking/sdl_net/handlers/listajaxhandler.cpp index 7c2801539db..e364712283c 100644 --- a/backends/networking/sdl_net/handlers/listajaxhandler.cpp +++ b/backends/networking/sdl_net/handlers/listajaxhandler.cpp @@ -42,8 +42,8 @@ Common::JSONObject ListAjaxHandler::listDirectory(Common::String path) { if (path == "" || path == "/") { if (ConfMan.hasKey("rootpath", "cloud")) - addItem(itemsList, IT_DIRECTORY, "/root/", _("File system root")); - addItem(itemsList, IT_DIRECTORY, "/saves/", _("Saved games")); + addItem(itemsList, IT_DIRECTORY, "/root/", HandlerUtils::toUtf8(_("File system root"))); + addItem(itemsList, IT_DIRECTORY, "/saves/", HandlerUtils::toUtf8(_("Saved games"))); successResult.setVal("items", new Common::JSONValue(itemsList)); return successResult; } @@ -81,7 +81,7 @@ Common::JSONObject ListAjaxHandler::listDirectory(Common::String path) { filePath = "/"; else filePath = parentPath(prefixToAdd + filePath); - addItem(itemsList, IT_PARENT_DIRECTORY, filePath, _("Parent directory")); + addItem(itemsList, IT_PARENT_DIRECTORY, filePath, HandlerUtils::toUtf8(_("Parent directory"))); } // fill the content diff --git a/backends/networking/sdl_net/handlers/uploadfilehandler.cpp b/backends/networking/sdl_net/handlers/uploadfilehandler.cpp index 6b8be15f1fb..c3454a9c412 100644 --- a/backends/networking/sdl_net/handlers/uploadfilehandler.cpp +++ b/backends/networking/sdl_net/handlers/uploadfilehandler.cpp @@ -40,35 +40,35 @@ void UploadFileHandler::handle(Client &client) { // check that is not an absolute root if (path == "" || path == "/" || path == "\\") { - HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Invalid path!")); + HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("Invalid path!"))); return; } // check that contains no '../' if (HandlerUtils::hasForbiddenCombinations(path)) { - HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Invalid path!")); + HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("Invalid path!"))); return; } // transform virtual path to actual file system one Common::String prefixToRemove = "", prefixToAdd = ""; if (!transformPath(path, prefixToRemove, prefixToAdd, false) || path.empty()) { - HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Invalid path!")); + HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("Invalid path!"))); return; } // check that exists, is directory and isn't forbidden AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(path); if (!HandlerUtils::permittedPath(node->getPath())) { - HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Invalid path!")); + HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("Invalid path!"))); return; } if (!node->exists()) { - HandlerUtils::setFilesManagerErrorMessageHandler(client, _("The parent directory doesn't exist!")); + HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("The parent directory doesn't exist!"))); return; } if (!node->isDirectory()) { - HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Can't upload into a file!")); + HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("Can't upload into a file!"))); return; } diff --git a/backends/networking/sdl_net/handlerutils.cpp b/backends/networking/sdl_net/handlerutils.cpp index 73ddf9e83f4..d47e6cff5ce 100644 --- a/backends/networking/sdl_net/handlerutils.cpp +++ b/backends/networking/sdl_net/handlerutils.cpp @@ -171,8 +171,13 @@ bool HandlerUtils::permittedPath(const Common::String path) { return hasPermittedPrefix(path) && !isBlacklisted(path); } +Common::String HandlerUtils::toUtf8(const char *text) { + // FIXME: Convert the GUI to use UTF8 + return Common::String(text); +} + void HandlerUtils::setMessageHandler(Client &client, Common::String message, Common::String redirectTo) { - Common::String response = "ScummVM{message}"; + Common::String response = "ResidualVM{message}"; // load stylish response page from the archive Common::SeekableReadStream *const stream = getArchiveFile(INDEX_PAGE_NAME); @@ -194,7 +199,7 @@ void HandlerUtils::setFilesManagerErrorMessageHandler(Client &client, Common::St message.c_str(), client.queryParameter("ajax") == "true" ? "AJAX" : "", "%2F", //that's encoded "/" - _("Back to the files manager") + toUtf8(_("Back to the files manager")).c_str() ), redirectTo ); diff --git a/backends/networking/sdl_net/handlerutils.h b/backends/networking/sdl_net/handlerutils.h index 09582945956..10ef2dc66a4 100644 --- a/backends/networking/sdl_net/handlerutils.h +++ b/backends/networking/sdl_net/handlerutils.h @@ -41,6 +41,8 @@ public: static bool hasPermittedPrefix(const Common::String &path); static bool permittedPath(const Common::String path); + static Common::String toUtf8(const char*); + static void setMessageHandler(Client &client, Common::String message, Common::String redirectTo = ""); static void setFilesManagerErrorMessageHandler(Client &client, Common::String message, Common::String redirectTo = ""); }; diff --git a/backends/networking/sdl_net/reader.h b/backends/networking/sdl_net/reader.h index 4955edfc39a..60557fdf06f 100644 --- a/backends/networking/sdl_net/reader.h +++ b/backends/networking/sdl_net/reader.h @@ -111,7 +111,7 @@ class Reader { uint32 bytesLeft() const; public: - static const uint32 SUSPICIOUS_HEADERS_SIZE = 1024 * 1024; // 1 MB is really a lot + static const int32 SUSPICIOUS_HEADERS_SIZE = 1024 * 1024; // 1 MB is really a lot Reader(); ~Reader(); diff --git a/backends/networking/sdl_net/uploadfileclienthandler.cpp b/backends/networking/sdl_net/uploadfileclienthandler.cpp index 8486b6e92eb..fb00b6bf5e7 100644 --- a/backends/networking/sdl_net/uploadfileclienthandler.cpp +++ b/backends/networking/sdl_net/uploadfileclienthandler.cpp @@ -66,7 +66,7 @@ void UploadFileClientHandler::handle(Client *client) { // fail on suspicious headers if (_headersStream->size() > Reader::SUSPICIOUS_HEADERS_SIZE) { - setErrorMessageHandler(*client, _("Invalid request: headers are too long!")); + setErrorMessageHandler(*client, HandlerUtils::toUtf8(_("Invalid request: headers are too long!"))); } break; @@ -108,7 +108,7 @@ void UploadFileClientHandler::handleBlockHeaders(Client *client) { // fail on suspicious headers if (_headersStream->size() > Reader::SUSPICIOUS_HEADERS_SIZE) { - setErrorMessageHandler(*client, _("Invalid request: headers are too long!")); + setErrorMessageHandler(*client, HandlerUtils::toUtf8(_("Invalid request: headers are too long!"))); } // search for "upload_file" field @@ -134,11 +134,11 @@ void UploadFileClientHandler::handleBlockHeaders(Client *client) { path += '/'; AbstractFSNode *originalNode = g_system->getFilesystemFactory()->makeFileNodePath(path + filename); if (!HandlerUtils::permittedPath(originalNode->getPath())) { - setErrorMessageHandler(*client, _("Invalid path!")); + setErrorMessageHandler(*client, HandlerUtils::toUtf8(_("Invalid path!"))); return; } if (originalNode->exists()) { - setErrorMessageHandler(*client, _("There is a file with that name in the parent directory!")); + setErrorMessageHandler(*client, HandlerUtils::toUtf8(_("There is a file with that name in the parent directory!"))); return; } @@ -152,7 +152,7 @@ void UploadFileClientHandler::handleBlockHeaders(Client *client) { Common::DumpFile *f = new Common::DumpFile(); if (!f->open(originalNode->getPath(), true)) { delete f; - setErrorMessageHandler(*client, _("Failed to upload the file!")); + setErrorMessageHandler(*client, HandlerUtils::toUtf8(_("Failed to upload the file!"))); return; } @@ -181,7 +181,7 @@ void UploadFileClientHandler::handleBlockContent(Client *client) { if (client->noMoreContent()) { // if no file field was found - failure if (_uploadedFiles == 0) { - setErrorMessageHandler(*client, _("No file was passed!")); + setErrorMessageHandler(*client, HandlerUtils::toUtf8(_("No file was passed!"))); } else { setSuccessHandler(*client); } @@ -199,9 +199,9 @@ void UploadFileClientHandler::setSuccessHandler(Client &client) { client, Common::String::format( "%s
%s", - _("Uploaded successfully!"), + HandlerUtils::toUtf8(_("Uploaded successfully!")).c_str(), client.queryParameter("path").c_str(), - _("Back to parent directory") + HandlerUtils::toUtf8(_("Back to parent directory")).c_str() ), (client.queryParameter("ajax") == "true" ? "/filesAJAX?path=" : "/files?path=") + LocalWebserver::urlEncodeQueryParameterValue(client.queryParameter("path")) diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp index dc6a8baa4f2..73520328457 100644 --- a/backends/platform/android/android.cpp +++ b/backends/platform/android/android.cpp @@ -374,7 +374,7 @@ void OSystem_Android::initBackend() { gettimeofday(&_startTime, 0); - _mixer = new Audio::MixerImpl(this, _audio_sample_rate); + _mixer = new Audio::MixerImpl(_audio_sample_rate); _mixer->setReady(true); _timer_thread_exit = false; diff --git a/backends/platform/sdl/amigaos/amigaos.mk b/backends/platform/sdl/amigaos/amigaos.mk index 178fde9155b..f43a9427af3 100644 --- a/backends/platform/sdl/amigaos/amigaos.mk +++ b/backends/platform/sdl/amigaos/amigaos.mk @@ -10,15 +10,21 @@ amigaosdist: $(EXECUTABLE) ifdef DIST_FILES_ENGINEDATA cp $(DIST_FILES_ENGINEDATA) $(AMIGAOSPATH)/extras/ endif - cat ${srcdir}/README | sed -f ${srcdir}/dists/amiga/convertRM.sed > README.conv +ifdef DIST_FILES_NETWORKING + cp $(DIST_FILES_NETWORKING) $(AMIGAOSPATH)/extras/ +endif +ifdef DIST_FILES_VKEYBD + cp $(DIST_FILES_VKEYBD) $(AMIGAOSPATH)/extras/ +endif + cat ${srcdir}/README.md | sed -f ${srcdir}/dists/amiga/convertRM.sed > README.conv # AmigaOS's shell is not happy with indented comments, thus don't do it. # AREXX seems to have problems when ${srcdir} is '.'. It will break with a # "Program not found" error. Therefore we copy the script to the cwd and # remove it again, once it has finished. - cp ${srcdir}/dists/amiga/RM2AG.rx . - rx RM2AG.rx README.conv + cp ${srcdir}/dists/amiga/RM2AG.rexx . + rx RM2AG.rexx README.conv cp README.guide $(AMIGAOSPATH) - rm RM2AG.rx + rm RM2AG.rexx rm README.conv rm README.guide cp $(DIST_FILES_DOCS) $(AMIGAOSPATH) diff --git a/backends/platform/sdl/macosx/macosx.cpp b/backends/platform/sdl/macosx/macosx.cpp index 9d2d7a5dbc8..94b25971e15 100644 --- a/backends/platform/sdl/macosx/macosx.cpp +++ b/backends/platform/sdl/macosx/macosx.cpp @@ -34,6 +34,7 @@ #include "backends/taskbar/macosx/macosx-taskbar.h" #include "backends/dialogs/macosx/macosx-dialogs.h" #include "backends/platform/sdl/macosx/macosx_wrapper.h" +#include "backends/fs/posix/posix-fs.h" #include "common/archive.h" #include "common/config-manager.h" @@ -199,6 +200,19 @@ Common::String OSystem_MacOSX::getSystemLanguage() const { #endif // USE_DETECTLANG } +Common::String OSystem_MacOSX::getDefaultLogFileName() { + const char *prefix = getenv("HOME"); + if (prefix == nullptr) { + return Common::String(); + } + + if (!Posix::assureDirectoryExists("Library/Logs", prefix)) { + return Common::String(); + } + + return Common::String(prefix) + "/Library/Logs/scummvm.log"; +} + Common::String OSystem_MacOSX::getScreenshotsPath() { Common::String path = ConfMan.get("screenshotpath"); if (path.empty()) diff --git a/backends/platform/sdl/macosx/macosx.h b/backends/platform/sdl/macosx/macosx.h index 6f960dbdad1..b860b71ad86 100644 --- a/backends/platform/sdl/macosx/macosx.h +++ b/backends/platform/sdl/macosx/macosx.h @@ -50,6 +50,8 @@ public: virtual Common::String getScreenshotsPath(); protected: + virtual Common::String getDefaultLogFileName(); + // Override createAudioCDManager() to get our Mac-specific // version. virtual AudioCDManager *createAudioCDManager(); diff --git a/backends/platform/sdl/posix/posix.cpp b/backends/platform/sdl/posix/posix.cpp index cef7a8d7053..ea8c1c80df5 100644 --- a/backends/platform/sdl/posix/posix.cpp +++ b/backends/platform/sdl/posix/posix.cpp @@ -269,55 +269,29 @@ void OSystem_POSIX::addSysArchivesToSearchSet(Common::SearchSet &s, int priority OSystem_SDL::addSysArchivesToSearchSet(s, priority); } -Common::WriteStream *OSystem_POSIX::createLogFile() { - // Start out by resetting _logFilePath, so that in case - // of a failure, we know that no log file is open. - _logFilePath.clear(); - - const char *prefix = nullptr; +Common::String OSystem_POSIX::getDefaultLogFileName() { Common::String logFile; -#ifdef MACOSX - prefix = getenv("HOME"); - if (prefix == nullptr) { - return 0; - } - logFile = "Library/Logs"; -#elif SAMSUNGTV - prefix = nullptr; - logFile = "/mtd_ram"; -#else // On POSIX systems we follow the XDG Base Directory Specification for // where to store files. The version we based our code upon can be found // over here: http://standards.freedesktop.org/basedir-spec/basedir-spec-0.8.html - prefix = getenv("XDG_CACHE_HOME"); + const char *prefix = getenv("XDG_CACHE_HOME"); if (prefix == nullptr || !*prefix) { prefix = getenv("HOME"); if (prefix == nullptr) { - return 0; + return Common::String(); } logFile = ".cache/"; } logFile += "residualvm/logs"; -#endif if (!Posix::assureDirectoryExists(logFile, prefix)) { - return 0; + return Common::String(); } - if (prefix) { - logFile = Common::String::format("%s/%s", prefix, logFile.c_str()); - } - - logFile += "/residualvm.log"; - - Common::FSNode file(logFile); - Common::WriteStream *stream = file.createWriteStream(); - if (stream) - _logFilePath = logFile; - return stream; + return Common::String::format("%s/%s/residualvm.log", prefix, logFile.c_str()); } bool OSystem_POSIX::displayLogFile() { diff --git a/backends/platform/sdl/posix/posix.h b/backends/platform/sdl/posix/posix.h index 8377c4e288a..04702d0fe13 100644 --- a/backends/platform/sdl/posix/posix.h +++ b/backends/platform/sdl/posix/posix.h @@ -52,19 +52,8 @@ protected: */ Common::String _baseConfigName; - /** - * The path of the currently open log file, if any. - * - * @note This is currently a string and not an FSNode for simplicity; - * e.g. we don't need to include fs.h here, and currently the - * only use of this value is to use it to open the log file in an - * editor; for that, we need it only as a string anyway. - */ - Common::String _logFilePath; - virtual Common::String getDefaultConfigFileName(); - - virtual Common::WriteStream *createLogFile(); + virtual Common::String getDefaultLogFileName(); Common::String getXdgUserDir(const char *name); diff --git a/backends/platform/sdl/ps3/ps3.cpp b/backends/platform/sdl/ps3/ps3.cpp index e7869dbb2a1..a1f184ec4ac 100644 --- a/backends/platform/sdl/ps3/ps3.cpp +++ b/backends/platform/sdl/ps3/ps3.cpp @@ -78,7 +78,6 @@ Common::String OSystem_PS3::getDefaultConfigFileName() { return PREFIX "/" + _baseConfigName; } -Common::WriteStream *OSystem_PS3::createLogFile() { - Common::FSNode file(PREFIX "/residualvm.log"); - return file.createWriteStream(); +Common::String OSystem_PS3::getDefaultLogFileName() { + return PREFIX "/residualvm.log"; } diff --git a/backends/platform/sdl/ps3/ps3.h b/backends/platform/sdl/ps3/ps3.h index 4ae3a577d82..f4dd3f0dc16 100644 --- a/backends/platform/sdl/ps3/ps3.h +++ b/backends/platform/sdl/ps3/ps3.h @@ -40,8 +40,7 @@ protected: Common::String _baseConfigName; virtual Common::String getDefaultConfigFileName(); - - virtual Common::WriteStream *createLogFile(); + virtual Common::String getDefaultLogFileName(); }; #endif diff --git a/backends/platform/sdl/ps3/ps3.mk b/backends/platform/sdl/ps3/ps3.mk index cb454c8ba77..80ec7aae0b7 100644 --- a/backends/platform/sdl/ps3/ps3.mk +++ b/backends/platform/sdl/ps3/ps3.mk @@ -8,11 +8,15 @@ ps3pkg: $(EXECUTABLE) cp $(DIST_FILES_THEMES) ps3pkg/USRDIR/data/ ifdef DIST_FILES_ENGINEDATA cp $(DIST_FILES_ENGINEDATA) ps3pkg/USRDIR/data/ +endif +ifdef DIST_FILES_NETWORKING + cp $(DIST_FILES_NETWORKING) ps3pkg/USRDIR/data/ +endif +ifdef DIST_FILES_VKEYBD + cp $(DIST_FILES_VKEYBD) ps3pkg/USRDIR/data/ endif cp $(DIST_FILES_DOCS) ps3pkg/USRDIR/doc/ cp $(srcdir)/dists/ps3/readme-ps3.md ps3pkg/USRDIR/doc/ - cp $(srcdir)/backends/vkeybd/packs/vkeybd_default.zip ps3pkg/USRDIR/data/ - cp $(srcdir)/backends/vkeybd/packs/vkeybd_small.zip ps3pkg/USRDIR/data/ cp $(srcdir)/dists/ps3/ICON0.PNG ps3pkg/ sfo.py -f $(srcdir)/dists/ps3/sfo.xml ps3pkg/PARAM.SFO pkg.py --contentid UP0001-RESI12000_00-0000000000000000 ps3pkg/ residualvm-ps3.pkg diff --git a/backends/platform/sdl/riscos/riscos.cpp b/backends/platform/sdl/riscos/riscos.cpp index 1b4a6e291f1..a31436bc771 100644 --- a/backends/platform/sdl/riscos/riscos.cpp +++ b/backends/platform/sdl/riscos/riscos.cpp @@ -119,24 +119,14 @@ Common::String OSystem_RISCOS::getDefaultConfigFileName() { return "//ResidualVM/residualvm"; } -Common::WriteStream *OSystem_RISCOS::createLogFile() { - // Start out by resetting _logFilePath, so that in case - // of a failure, we know that no log file is open. - _logFilePath.clear(); - +Common::String OSystem_RISCOS::getDefaultLogFileName() { Common::String logFile = "//ResidualVM/Logs"; if (!Riscos::assureDirectoryExists(logFile)) { - return 0; + return Common::String(); } - logFile += "/residualvm"; - - Common::FSNode file(logFile); - Common::WriteStream *stream = file.createWriteStream(); - if (stream) - _logFilePath = logFile; - return stream; + return logFile + "/residualvm"; } #endif diff --git a/backends/platform/sdl/riscos/riscos.h b/backends/platform/sdl/riscos/riscos.h index 49ac5a2264f..7abeb4f8efe 100644 --- a/backends/platform/sdl/riscos/riscos.h +++ b/backends/platform/sdl/riscos/riscos.h @@ -37,18 +37,8 @@ public: virtual void logMessage(LogMessageType::Type type, const char *message); protected: - /** - * The path of the currently open log file, if any. - * - * @note This is currently a string and not an FSNode for simplicity; - * e.g. we don't need to include fs.h here, and currently the - * only use of this value is to use it to open the log file in an - * editor; for that, we need it only as a string anyway. - */ - Common::String _logFilePath; - virtual Common::String getDefaultConfigFileName(); - virtual Common::WriteStream *createLogFile(); + virtual Common::String getDefaultLogFileName(); }; #endif diff --git a/backends/platform/sdl/riscos/riscos.mk b/backends/platform/sdl/riscos/riscos.mk index 93daf9511bb..776ffc793d0 100644 --- a/backends/platform/sdl/riscos/riscos.mk +++ b/backends/platform/sdl/riscos/riscos.mk @@ -1,7 +1,7 @@ -ifeq ($(shell echo a | iconv --to-code=RISCOS-LATIN1//TRANSLIT >/dev/null 2>&1; echo $$?),0) -ENCODING=RISCOS-LATIN1//TRANSLIT +ifeq ($(shell echo a | iconv --to-code=RISCOS-LATIN1//IGNORE//TRANSLIT >/dev/null 2>&1; echo $$?),0) +ENCODING=RISCOS-LATIN1//IGNORE//TRANSLIT else -ENCODING=ISO-8859-1//TRANSLIT +ENCODING=ISO-8859-1//IGNORE//TRANSLIT endif APP_NAME=!ResidualVM @@ -27,6 +27,9 @@ ifdef USE_OPENGL_SHADERS mkdir -p $(APP_NAME)/data/shaders cp $(DIST_FILES_SHADERS) $(APP_NAME)/data/shaders/ endif +ifdef DIST_FILES_VKEYBD + cp $(DIST_FILES_VKEYBD) $(APP_NAME)/data/ +endif ifdef DYNAMIC_MODULES mkdir -p $(APP_NAME)/plugins cp $(PLUGINS) $(APP_NAME)/plugins/ diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index 852fc8a0056..88d295650aa 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -191,8 +191,6 @@ void OSystem_SDL::initBackend() { sdlDriverName[0] = '\0'; SDL_VideoDriverName(sdlDriverName, maxNameLen); #endif - // Using printf rather than debug() here as debug()/logging - // is not active by this point. debug(1, "Using SDL Video Driver \"%s\"", sdlDriverName); // ResidualVM specific code start @@ -384,7 +382,7 @@ void OSystem_SDL::initSDL() { if (ConfMan.hasKey("disable_sdl_parachute")) sdlFlags |= SDL_INIT_NOPARACHUTE; - // Initialize SDL (SDL Subsystems are initiliazed in the corresponding sdl managers) + // Initialize SDL (SDL Subsystems are initialized in the corresponding sdl managers) if (SDL_Init(sdlFlags) == -1) error("Could not initialize SDL: %s", SDL_GetError()); @@ -504,6 +502,22 @@ void OSystem_SDL::logMessage(LogMessageType::Type type, const char *message) { _logger->print(message); } +Common::WriteStream *OSystem_SDL::createLogFile() { + // Start out by resetting _logFilePath, so that in case + // of a failure, we know that no log file is open. + _logFilePath.clear(); + + Common::String logFile = getDefaultLogFileName(); + if (logFile.empty()) + return nullptr; + + Common::FSNode file(logFile); + Common::WriteStream *stream = file.createWriteStream(); + if (stream) + _logFilePath = logFile; + return stream; +} + Common::String OSystem_SDL::getSystemLanguage() const { #if defined(USE_DETECTLANG) && !defined(WIN32) // Activating current locale settings @@ -538,18 +552,14 @@ Common::String OSystem_SDL::getSystemLanguage() const { #endif // USE_DETECTLANG } -bool OSystem_SDL::hasTextInClipboard() { #if SDL_VERSION_ATLEAST(2, 0, 0) +bool OSystem_SDL::hasTextInClipboard() { return SDL_HasClipboardText() == SDL_TRUE; -#else - return false; -#endif } Common::String OSystem_SDL::getTextFromClipboard() { if (!hasTextInClipboard()) return ""; -#if SDL_VERSION_ATLEAST(2, 0, 0) char *text = SDL_GetClipboardText(); // The string returned by SDL is in UTF-8. Convert to the // current TranslationManager encoding or ISO-8859-1. @@ -566,13 +576,9 @@ Common::String OSystem_SDL::getTextFromClipboard() { SDL_free(text); return strText; -#else - return ""; -#endif } bool OSystem_SDL::setTextInClipboard(const Common::String &text) { -#if SDL_VERSION_ATLEAST(2, 0, 0) // The encoding we need to use is UTF-8. Assume we currently have the // current TranslationManager encoding or ISO-8859-1. #ifdef USE_TRANSLATION @@ -586,10 +592,8 @@ bool OSystem_SDL::setTextInClipboard(const Common::String &text) { return status == 0; } return SDL_SetClipboardText(text.c_str()) == 0; -#else - return false; -#endif } +#endif uint32 OSystem_SDL::getMillis(bool skipRecord) { uint32 millis = SDL_GetTicks(); diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h index 6ad2587f42c..c8c3edfb41e 100644 --- a/backends/platform/sdl/sdl.h +++ b/backends/platform/sdl/sdl.h @@ -70,10 +70,12 @@ public: virtual Common::String getSystemLanguage() const; +#if SDL_VERSION_ATLEAST(2, 0, 0) // Clipboard virtual bool hasTextInClipboard(); virtual Common::String getTextFromClipboard(); virtual bool setTextInClipboard(const Common::String &text); +#endif virtual void setWindowCaption(const char *caption); virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0); @@ -101,6 +103,16 @@ protected: bool _initedSDLnet; #endif + /** + * The path of the currently open log file, if any. + * + * @note This is currently a string and not an FSNode for simplicity; + * e.g. we don't need to include fs.h here, and currently the + * only use of this value is to use it to open the log file in an + * editor; for that, we need it only as a string anyway. + */ + Common::String _logFilePath; + /** * Mixer manager that configures and setups SDL for * the wrapped Audio::Mixer, the true mixer. @@ -138,7 +150,8 @@ protected: virtual AudioCDManager *createAudioCDManager(); // Logging - virtual Common::WriteStream *createLogFile() { return 0; } + virtual Common::String getDefaultLogFileName() { return Common::String(); } + virtual Common::WriteStream *createLogFile(); Backends::Log::Log *_logger; }; diff --git a/backends/platform/sdl/win32/win32.cpp b/backends/platform/sdl/win32/win32.cpp index b36648bca04..20ef21652d1 100644 --- a/backends/platform/sdl/win32/win32.cpp +++ b/backends/platform/sdl/win32/win32.cpp @@ -110,7 +110,7 @@ void OSystem_Win32::initBackend() { #if defined(USE_SPARKLE) // Initialize updates manager - _updateManager = new Win32UpdateManager(); + _updateManager = new Win32UpdateManager((SdlWindow_Win32*)_window); #endif // Invoke parent implementation of this method @@ -278,31 +278,22 @@ Common::String OSystem_Win32::getDefaultConfigFileName() { return configFile; } -Common::WriteStream *OSystem_Win32::createLogFile() { - // Start out by resetting _logFilePath, so that in case - // of a failure, we know that no log file is open. - _logFilePath.clear(); - +Common::String OSystem_Win32::getDefaultLogFileName() { char logFile[MAXPATHLEN]; // Use the Application Data directory of the user profile. - if (SHGetFolderPathFunc(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, logFile) == S_OK) { - strcat(logFile, "\\ResidualVM"); - CreateDirectory(logFile, NULL); - strcat(logFile, "\\Logs"); - CreateDirectory(logFile, NULL); - strcat(logFile, "\\residualvm.log"); - - Common::FSNode file(logFile); - Common::WriteStream *stream = file.createWriteStream(); - if (stream) - _logFilePath= logFile; - - return stream; - } else { + if (SHGetFolderPathFunc(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, logFile) != S_OK) { warning("Unable to access application data directory"); - return 0; + return Common::String(); } + + strcat(logFile, "\\ResidualVM"); + CreateDirectory(logFile, NULL); + strcat(logFile, "\\Logs"); + CreateDirectory(logFile, NULL); + strcat(logFile, "\\residualvm.log"); + + return logFile; } namespace { diff --git a/backends/platform/sdl/win32/win32.h b/backends/platform/sdl/win32/win32.h index 9919495e37b..f0c728792f8 100644 --- a/backends/platform/sdl/win32/win32.h +++ b/backends/platform/sdl/win32/win32.h @@ -46,20 +46,10 @@ public: virtual Common::String getScreenshotsPath(); protected: - /** - * The path of the currently open log file, if any. - * - * @note This is currently a string and not an FSNode for simplicity; - * e.g. we don't need to include fs.h here, and currently the - * only use of this value is to use it to open the log file in an - * editor; for that, we need it only as a string anyway. - */ - Common::String _logFilePath; - virtual Common::String getDefaultConfigFileName(); - virtual Common::WriteStream *createLogFile(); + virtual Common::String getDefaultLogFileName(); - // Override createAudioCDManager() to get our Mac-specific + // Override createAudioCDManager() to get our Windows-specific // version. virtual AudioCDManager *createAudioCDManager(); diff --git a/backends/platform/sdl/win32/win32.mk b/backends/platform/sdl/win32/win32.mk index fb3d6387c5d..55805b9a041 100644 --- a/backends/platform/sdl/win32/win32.mk +++ b/backends/platform/sdl/win32/win32.mk @@ -3,12 +3,12 @@ # # ResidualVM: Added DIST_FILES_SHADERS -residualvmwinres.o: $(srcdir)/icons/residualvm.ico $(DIST_FILES_THEMES) $(DIST_FILES_NETWORKING) $(DIST_FILES_ENGINEDATA) $(DIST_FILES_SHADERS) $(srcdir)/dists/residualvm.rc - $(QUIET_WINDRES)$(WINDRES) -DHAVE_CONFIG_H $(WINDRESFLAGS) $(DEFINES) -I. -I$(srcdir) $(srcdir)/dists/residualvm.rc residualvmwinres.o +dists/residualvm.o: $(srcdir)/icons/residualvm.ico $(DIST_FILES_THEMES) $(DIST_FILES_NETWORKING) $(DIST_FILES_ENGINEDATA) $(DIST_FILES_SHADERS) config.h $(srcdir)/base/internal_version.h # Special target to create a win32 snapshot binary (for Inno Setup) win32dist: all mkdir -p $(WIN32PATH) + mkdir -p $(WIN32PATH)/graphics mkdir -p $(WIN32PATH)/doc $(STRIP) $(EXECUTABLE) -o $(WIN32PATH)/$(EXECUTABLE) cp $(srcdir)/AUTHORS $(WIN32PATH)/AUTHORS.txt diff --git a/backends/platform/sdl/win32/win32_wrapper.h b/backends/platform/sdl/win32/win32_wrapper.h index 8bd60239df1..9fa1a162104 100644 --- a/backends/platform/sdl/win32/win32_wrapper.h +++ b/backends/platform/sdl/win32/win32_wrapper.h @@ -23,6 +23,8 @@ #ifndef PLATFORM_SDL_WIN32_WRAPPER_H #define PLATFORM_SDL_WIN32_WRAPPER_H +#include "common/scummsys.h" + HRESULT SHGetFolderPathFunc(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, LPSTR pszPath); // Helper functions diff --git a/backends/saves/default/default-saves.cpp b/backends/saves/default/default-saves.cpp index 8973101a5a6..17e888175cd 100644 --- a/backends/saves/default/default-saves.cpp +++ b/backends/saves/default/default-saves.cpp @@ -63,7 +63,9 @@ DefaultSaveFileManager::DefaultSaveFileManager(const Common::String &defaultSave void DefaultSaveFileManager::checkPath(const Common::FSNode &dir) { clearError(); if (!dir.exists()) { - setError(Common::kPathDoesNotExist, "The savepath '"+dir.getPath()+"' does not exist"); + if (!dir.createDirectory()) { + setError(Common::kPathDoesNotExist, "Failed to create directory '"+dir.getPath()+"'"); + } } else if (!dir.isDirectory()) { setError(Common::kPathNotDirectory, "The savepath '"+dir.getPath()+"' is not a directory"); } @@ -169,6 +171,8 @@ Common::OutSaveFile *DefaultSaveFileManager::openForSaving(const Common::String // Open the file for saving. Common::WriteStream *const sf = fileNode.createWriteStream(); + if (!sf) + return nullptr; Common::OutSaveFile *const result = new Common::OutSaveFile(compress ? Common::wrapCompressedWriteStream(sf) : sf); // Add file to cache now that it exists. @@ -358,7 +362,10 @@ void DefaultSaveFileManager::saveTimestamps(Common::HashMap::iterator i = timestamps.begin(); i != timestamps.end(); ++i) { - Common::String data = i->_key + Common::String::format(" %u\n", i->_value); + uint32 v = i->_value; + if (v < 1) v = 1; // 0 timestamp is treated as EOF up there, so we should never save zeros + + Common::String data = i->_key + Common::String::format(" %u\n", v); if (f.write(data.c_str(), data.size()) != data.size()) { warning("DefaultSaveFileManager: failed to write timestamps data into '%s'", filename.c_str()); return; diff --git a/backends/saves/posix/posix-saves.cpp b/backends/saves/posix/posix-saves.cpp index fa9f243f823..837f19f9b0b 100644 --- a/backends/saves/posix/posix-saves.cpp +++ b/backends/saves/posix/posix-saves.cpp @@ -38,9 +38,6 @@ #include "common/savefile.h" #include "common/textconsole.h" -#include -#include -#include #include POSIXSaveFileManager::POSIXSaveFileManager() { @@ -133,69 +130,4 @@ POSIXSaveFileManager::POSIXSaveFileManager() { #endif } -void POSIXSaveFileManager::checkPath(const Common::FSNode &dir) { - const Common::String path = dir.getPath(); - clearError(); - - struct stat sb; - - // Check whether the dir exists - if (stat(path.c_str(), &sb) == -1) { - // The dir does not exist, or stat failed for some other reason. - // If the problem was that the path pointed to nothing, try - // to create the dir (ENOENT case). - switch (errno) { - case EACCES: - setError(Common::kWritePermissionDenied, "Search or write permission denied: "+path); - break; - case ELOOP: - setError(Common::kUnknownError, "Too many symbolic links encountered while traversing the path: "+path); - break; - case ENAMETOOLONG: - setError(Common::kUnknownError, "The path name is too long: "+path); - break; - case ENOENT: - if (mkdir(path.c_str(), 0755) != 0) { - // mkdir could fail for various reasons: The parent dir doesn't exist, - // or is not writeable, the path could be completly bogus, etc. - warning("mkdir for '%s' failed", path.c_str()); - perror("mkdir"); - - switch (errno) { - case EACCES: - setError(Common::kWritePermissionDenied, "Search or write permission denied: "+path); - break; - case EMLINK: - setError(Common::kUnknownError, "The link count of the parent directory would exceed {LINK_MAX}: "+path); - break; - case ELOOP: - setError(Common::kUnknownError, "Too many symbolic links encountered while traversing the path: "+path); - break; - case ENAMETOOLONG: - setError(Common::kUnknownError, "The path name is too long: "+path); - break; - case ENOENT: - setError(Common::kPathDoesNotExist, "A component of the path does not exist, or the path is an empty string: "+path); - break; - case ENOTDIR: - setError(Common::kPathDoesNotExist, "A component of the path prefix is not a directory: "+path); - break; - case EROFS: - setError(Common::kWritePermissionDenied, "The parent directory resides on a read-only file system:"+path); - break; - } - } - break; - case ENOTDIR: - setError(Common::kPathDoesNotExist, "A component of the path prefix is not a directory: "+path); - break; - } - } else { - // So stat() succeeded. But is the path actually pointing to a directory? - if (!S_ISDIR(sb.st_mode)) { - setError(Common::kPathDoesNotExist, "The given savepath is not a directory: "+path); - } - } -} - #endif diff --git a/backends/saves/posix/posix-saves.h b/backends/saves/posix/posix-saves.h index 2477bd60e7d..2257b75b0d9 100644 --- a/backends/saves/posix/posix-saves.h +++ b/backends/saves/posix/posix-saves.h @@ -35,14 +35,6 @@ class POSIXSaveFileManager : public DefaultSaveFileManager { public: POSIXSaveFileManager(); - -protected: - /** - * Checks the given path for read access, existence, etc. - * In addition, tries to create a missing savedir, if possible. - * Sets the internal error and error message accordingly. - */ - virtual void checkPath(const Common::FSNode &dir); }; #endif diff --git a/backends/timer/default/default-timer.cpp b/backends/timer/default/default-timer.cpp index 19d1a0af115..067226be4df 100644 --- a/backends/timer/default/default-timer.cpp +++ b/backends/timer/default/default-timer.cpp @@ -36,7 +36,7 @@ struct TimerSlot { TimerSlot *next; - TimerSlot() : refCon(0), interval(0), nextFireTime(0), nextFireTimeMicro(0), next(0) {} + TimerSlot() : callback(nullptr), refCon(nullptr), interval(0), nextFireTime(0), nextFireTimeMicro(0), next(nullptr) {} }; void insertPrioQueue(TimerSlot *head, TimerSlot *newSlot) { diff --git a/backends/updates/macosx/macosx-updates.mm b/backends/updates/macosx/macosx-updates.mm index 64dcbf62cef..bf524e5704f 100644 --- a/backends/updates/macosx/macosx-updates.mm +++ b/backends/updates/macosx/macosx-updates.mm @@ -83,9 +83,6 @@ MacOSXUpdateManager::MacOSXUpdateManager() { // Set the target of the new menu item [updateMenuItem setTarget:sparkleUpdater]; - // Finally give up our references to the objects - [menuItem release]; - if (!ConfMan.hasKey("updates_check") || ConfMan.getInt("updates_check") == Common::UpdateManager::kUpdateIntervalNotSupported) { setAutomaticallyChecksForUpdates(kUpdateStateDisabled); diff --git a/backends/updates/win32/win32-updates.cpp b/backends/updates/win32/win32-updates.cpp index 95c5f4ca88e..868f5d886b2 100644 --- a/backends/updates/win32/win32-updates.cpp +++ b/backends/updates/win32/win32-updates.cpp @@ -27,10 +27,12 @@ #include "backends/updates/win32/win32-updates.h" #ifdef USE_SPARKLE +#include "backends/platform/sdl/win32/win32-window.h" #include "common/translation.h" #include "common/config-manager.h" #include +#include #include /** @@ -50,10 +52,15 @@ * https://winsparkle.org/ * */ -Win32UpdateManager::Win32UpdateManager() { - const char *appcastUrl = "https://www.residualvm.org/appcasts/macosx/release.xml"; - win_sparkle_set_appcast_url(appcastUrl); +static SdlWindow_Win32 *_window; + +Win32UpdateManager::Win32UpdateManager(SdlWindow_Win32 *window) { + _window = window; + const char *appcastUrl = "https://www.scummvm.org/appcasts/macosx/release.xml"; + win_sparkle_set_appcast_url(appcastUrl); + win_sparkle_set_can_shutdown_callback(canShutdownCallback); + win_sparkle_set_shutdown_request_callback(shutdownRequestCallback); win_sparkle_init(); if (!ConfMan.hasKey("updates_check") @@ -129,4 +136,20 @@ bool Win32UpdateManager::getLastUpdateCheckTimeAndDate(TimeDate &t) { return true; } +// WinSparkle calls this to ask if we can shut down. +// At this point the download has completed, the user has +// selected Install Update, and the installer has started. +// This callback runs on a non-main thread. +int Win32UpdateManager::canShutdownCallback() { + return true; +} + +// WinSparkle calls this to request that we shut down. +// This callback runs on a non-main thread so we post +// a WM_CLOSE message to our window so that we exit +// cleanly, as opposed to calling g_system->quit(). +void Win32UpdateManager::shutdownRequestCallback() { + PostMessage(_window->getHwnd(), WM_CLOSE, 0, 0); +} + #endif diff --git a/backends/updates/win32/win32-updates.h b/backends/updates/win32/win32-updates.h index 71ed9ef6850..afa2ef99ef5 100644 --- a/backends/updates/win32/win32-updates.h +++ b/backends/updates/win32/win32-updates.h @@ -29,9 +29,11 @@ #include "common/updates.h" +class SdlWindow_Win32; + class Win32UpdateManager : public Common::UpdateManager { public: - Win32UpdateManager(); + Win32UpdateManager(SdlWindow_Win32 *window); virtual ~Win32UpdateManager(); virtual void checkForUpdates(); @@ -43,6 +45,10 @@ public: virtual int getUpdateCheckInterval(); virtual bool getLastUpdateCheckTimeAndDate(TimeDate &t); + +private: + static int canShutdownCallback(); + static void shutdownRequestCallback(); }; #endif diff --git a/base/commandLine.cpp b/base/commandLine.cpp index ab741917d95..630b6e19cae 100644 --- a/base/commandLine.cpp +++ b/base/commandLine.cpp @@ -35,9 +35,9 @@ #include "common/config-manager.h" #include "common/fs.h" #include "common/rendermode.h" -#include "common/stack.h" #include "common/system.h" #include "common/textconsole.h" +#include "common/tokenizer.h" #include "gui/ThemeEngine.h" @@ -70,6 +70,7 @@ static const char HELP_STRING[] = " -h, --help Display a brief help text and exit\n" " -z, --list-games Display list of supported games and exit\n" " -t, --list-targets Display list of configured targets and exit\n" + " --list-engines Display list of suppported engines and exit\n" " --list-saves Display a list of saved games for the target specified\n" " with --game=TARGET, or all targets if none is specified\n" " -a, --add Add all games from current or specified directory.\n" @@ -178,6 +179,10 @@ static void ensureFirstCommand(const Common::String &existingCommand, const char usage("--%s: Cannot accept more than one command (already found --%s).", newCommand, existingCommand.c_str()); } +static Common::String buildQualifiedGameName(const Common::String &engineId, const Common::String &gameId) { + return Common::String::format("%s:%s", engineId.c_str(), gameId.c_str()); +} + #endif // DISABLE_COMMAND_LINE @@ -268,6 +273,70 @@ void registerDefaults() { #endif } +static bool parseGameName(const Common::String &gameName, Common::String &engineId, Common::String &gameId) { + Common::StringTokenizer tokenizer(gameName, ":"); + Common::String token1, token2; + + if (!tokenizer.empty()) { + token1 = tokenizer.nextToken(); + } + + if (!tokenizer.empty()) { + token2 = tokenizer.nextToken(); + } + + if (!tokenizer.empty()) { + return false; // Stray colon + } + + if (!token1.empty() && !token2.empty()) { + engineId = token1; + gameId = token2; + return true; + } else if (!token1.empty()) { + engineId.clear(); + gameId = token1; + return true; + } + + return false; +} + +static QualifiedGameDescriptor findGameMatchingName(const Common::String &name) { + if (name.empty()) { + return QualifiedGameDescriptor(); + } + + Common::String engineId; + Common::String gameId; + if (!parseGameName(name, engineId, gameId)) { + return QualifiedGameDescriptor(); // Invalid name format + } + + // Check if the name is a known game id + QualifiedGameList games = EngineMan.findGamesMatching(engineId, gameId); + if (games.size() != 1) { + // Game not found or ambiguous name + return QualifiedGameDescriptor(); + } + + return games[0]; +} + +static Common::String createTemporaryTarget(const Common::String &engineId, const Common::String &gameId) { + Common::String domainName = gameId; + + ConfMan.addGameDomain(domainName); + ConfMan.set("engineid", engineId, domainName); + ConfMan.set("gameid", gameId, domainName); + + // We designate targets which come strictly from command line + // so ConfMan will not save them to the configuration file. + ConfMan.set("id_came_from_command_line", "1", domainName); + + return domainName; +} + // // Various macros used by the command line parser. // @@ -401,6 +470,9 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha DO_COMMAND('z', "list-games") END_COMMAND + DO_LONG_COMMAND("list-engines") + END_COMMAND + DO_COMMAND('a', "add") END_COMMAND @@ -641,26 +713,39 @@ unknownOption: /** List all supported game IDs, i.e. all games which any loaded plugin supports. */ static void listGames() { - printf("Game ID Full Title \n" - "-------------------- ------------------------------------------------------\n"); + printf("Game ID Full Title \n" + "------------------------------ -----------------------------------------------------------\n"); const PluginList &plugins = EngineMan.getPlugins(); for (PluginList::const_iterator iter = plugins.begin(); iter != plugins.end(); ++iter) { - PlainGameList list = (*iter)->get().getSupportedGames(); - for (PlainGameList::iterator v = list.begin(); v != list.end(); ++v) { - printf("%-20s %s\n", v->gameId, v->description); + const MetaEngine &metaengine = (*iter)->get(); + + PlainGameList list = metaengine.getSupportedGames(); + for (PlainGameList::const_iterator v = list.begin(); v != list.end(); ++v) { + printf("%-30s %s\n", buildQualifiedGameName(metaengine.getEngineId(), v->gameId).c_str(), v->description); } } } +/** List all supported engines, i.e. all loaded plugins. */ +static void listEngines() { + printf("Engine ID Engine Name \n" + "--------------- ------------------------------------------------------\n"); + + const PluginList &plugins = EngineMan.getPlugins(); + for (PluginList::const_iterator iter = plugins.begin(); iter != plugins.end(); ++iter) { + const MetaEngine &metaEngine = (*iter)->get(); + printf("%-15s %s\n", metaEngine.getEngineId(), metaEngine.getName()); + } +} + /** List all targets which are configured in the config file. */ static void listTargets() { printf("Target Description \n" "-------------------- ------------------------------------------------------\n"); - using namespace Common; - const ConfigManager::DomainMap &domains = ConfMan.getGameDomains(); - ConfigManager::DomainMap::const_iterator iter; + const Common::ConfigManager::DomainMap &domains = ConfMan.getGameDomains(); + Common::ConfigManager::DomainMap::const_iterator iter; Common::Array targets; targets.reserve(domains.size()); @@ -669,15 +754,15 @@ static void listTargets() { Common::String name(iter->_key); Common::String description(iter->_value.getVal("description")); + // If there's no description, fallback on the default description. if (description.empty()) { - // FIXME: At this point, we should check for a "gameid" override - // to find the proper desc. In fact, the platform probably should - // be taken into account, too. - const Common::String &gameid = name; - PlainGameDescriptor g = EngineMan.findGame(gameid); + QualifiedGameDescriptor g = EngineMan.findTarget(name); if (g.description) description = g.description; } + // If there's still no description, we cannot come up with one. Insert some dummy text. + if (description.empty()) + description = ""; targets.push_back(Common::String::format("%-20s %s", name.c_str(), description.c_str())); } @@ -689,13 +774,13 @@ static void listTargets() { } /** List all saves states for the given target. */ -static Common::Error listSaves(const Common::String &target) { +static Common::Error listSaves(const Common::String &singleTarget) { Common::Error result = Common::kNoError; // If no target is specified, list save games for all known targets Common::Array targets; - if (!target.empty()) - targets.push_back(target); + if (!singleTarget.empty()) + targets.push_back(singleTarget); else { const Common::ConfigManager::DomainMap &domains = ConfMan.getGameDomains(); Common::ConfigManager::DomainMap::const_iterator iter; @@ -712,53 +797,56 @@ static Common::Error listSaves(const Common::String &target) { bool atLeastOneFound = false; for (Common::Array::const_iterator i = targets.begin(), end = targets.end(); i != end; ++i) { - // Grab the "target" domain, if any - const Common::ConfigManager::Domain *domain = ConfMan.getDomain(*i); - - // Set up the game domain as newly active domain, so - // target specific savepath will be checked - ConfMan.setActiveDomain(*i); - - // Grab the gameid from the domain resp. use the target as gameid - Common::String gameid; - if (domain) - gameid = domain->getVal("gameid"); - if (gameid.empty()) - gameid = *i; - gameid.toLowercase(); // Normalize it to lower case - - // Find the plugin that will handle the specified gameid + // Check whether there is either a game domain (i.e. a target) matching + // the specified game name, or alternatively whether there is a matching game id. + Common::String currentTarget; + QualifiedGameDescriptor game; const Plugin *plugin = nullptr; - EngineMan.findGame(gameid, &plugin); + if (ConfMan.hasGameDomain(*i)) { + // The name is a known target + currentTarget = *i; + EngineMan.upgradeTargetIfNecessary(*i); + game = EngineMan.findTarget(*i, &plugin); + } else if (game = findGameMatchingName(*i), game.gameId) { + // The name is a known game id + plugin = EngineMan.findPlugin(game.engineId); + currentTarget = createTemporaryTarget(game.engineId, game.gameId); + } else { + return Common::Error(Common::kEnginePluginNotFound, Common::String::format("target '%s'", singleTarget.c_str())); + } + + // If we actually found a domain, we're going to change the domain + ConfMan.setActiveDomain(currentTarget); if (!plugin) { // If the target was specified, treat this as an error, and otherwise skip it. - if (!target.empty()) + if (!singleTarget.empty()) return Common::Error(Common::kEnginePluginNotFound, - Common::String::format("target '%s', gameid '%s", i->c_str(), gameid.c_str())); - printf("Plugin could not be loaded for target '%s', gameid '%s", i->c_str(), gameid.c_str()); + Common::String::format("target '%s'", i->c_str())); + printf("Plugin could not be loaded for target '%s'\n", i->c_str()); continue; } const MetaEngine &metaEngine = plugin->get(); + Common::String qualifiedGameId = buildQualifiedGameName(game.engineId, game.gameId); if (!metaEngine.hasFeature(MetaEngine::kSupportsListSaves)) { // If the target was specified, treat this as an error, and otherwise skip it. - if (!target.empty()) + if (!singleTarget.empty()) // TODO: Include more info about the target (desc, engine name, ...) ??? return Common::Error(Common::kEnginePluginNotSupportSaves, - Common::String::format("target '%s', gameid '%s", i->c_str(), gameid.c_str())); + Common::String::format("target '%s', gameid '%s'", i->c_str(), qualifiedGameId.c_str())); continue; } // Query the plugin for a list of saved games SaveStateList saveList = metaEngine.listSaves(i->c_str()); - if (saveList.size() > 0) { + if (!saveList.empty()) { // TODO: Include more info about the target (desc, engine name, ...) ??? if (atLeastOneFound) printf("\n"); - printf("Save states for target '%s' (gameid '%s'):\n", i->c_str(), gameid.c_str()); + printf("Save states for target '%s' (gameid '%s'):\n", i->c_str(), qualifiedGameId.c_str()); printf(" Slot Description \n" " ---- ------------------------------------------------------\n"); @@ -769,15 +857,15 @@ static Common::Error listSaves(const Common::String &target) { atLeastOneFound = true; } else { // If the target was specified, indicate no save games were found for it. Otherwise just skip it. - if (!target.empty()) - printf("There are no save states for target '%s' (gameid '%s'):\n", i->c_str(), gameid.c_str()); + if (!singleTarget.empty()) + printf("There are no save states for target '%s' (gameid '%s'):\n", i->c_str(), qualifiedGameId.c_str()); } } // Revert to the old active domain ConfMan.setActiveDomain(oldDomain); - if (!atLeastOneFound && target.empty()) + if (!atLeastOneFound && singleTarget.empty()) printf("No save states could be found.\n"); return result; @@ -833,16 +921,17 @@ static DetectedGames getGameList(const Common::FSNode &dir) { return detectionResults.listRecognizedGames(); } -static DetectedGames recListGames(const Common::FSNode &dir, const Common::String &gameId, bool recursive) { +static DetectedGames recListGames(const Common::FSNode &dir, const Common::String &engineId, const Common::String &gameId, bool recursive) { DetectedGames list = getGameList(dir); if (recursive) { Common::FSList files; dir.getChildren(files, Common::FSNode::kListDirectoriesOnly); for (Common::FSList::const_iterator file = files.begin(); file != files.end(); ++file) { - DetectedGames rec = recListGames(*file, gameId, recursive); + DetectedGames rec = recListGames(*file, engineId, gameId, recursive); for (DetectedGames::const_iterator game = rec.begin(); game != rec.end(); ++game) { - if (gameId.empty() || game->gameId == gameId) + if ((game->engineId == engineId && game->gameId == gameId) + || gameId.empty()) list.push_back(*game); } } @@ -852,11 +941,11 @@ static DetectedGames recListGames(const Common::FSNode &dir, const Common::Strin } /** Display all games in the given directory, return ID of first detected game */ -static Common::String detectGames(const Common::String &path, const Common::String &gameId, bool recursive) { +static Common::String detectGames(const Common::String &path, const Common::String &engineId, const Common::String &gameId, bool recursive) { bool noPath = path.empty(); //Current directory Common::FSNode dir(path); - DetectedGames candidates = recListGames(dir, gameId, recursive); + DetectedGames candidates = recListGames(dir, engineId, gameId, recursive); if (candidates.empty()) { printf("WARNING: ResidualVM could not find any game in %s\n", dir.getPath().c_str()); @@ -869,24 +958,31 @@ static Common::String detectGames(const Common::String &path, const Common::Stri return Common::String(); } // TODO this is not especially pretty - printf("ID Description Full Path\n"); - printf("-------------- ---------------------------------------------------------- ---------------------------------------------------------\n"); + printf("GameID Description Full Path\n"); + printf("------------------------------ ---------------------------------------------------------- ---------------------------------------------------------\n"); for (DetectedGames::const_iterator v = candidates.begin(); v != candidates.end(); ++v) { - printf("%-14s %-58s %s\n", v->gameId.c_str(), v->description.c_str(), v->path.c_str()); + printf("%-30s %-58s %s\n", + buildQualifiedGameName(v->engineId, v->gameId).c_str(), + v->description.c_str(), + v->path.c_str()); } - return candidates[0].gameId; + return buildQualifiedGameName(candidates[0].engineId, candidates[0].gameId); } -static int recAddGames(const Common::FSNode &dir, const Common::String &game, bool recursive) { +static int recAddGames(const Common::FSNode &dir, const Common::String &engineId, const Common::String &gameId, bool recursive) { int count = 0; DetectedGames list = getGameList(dir); for (DetectedGames::const_iterator v = list.begin(); v != list.end(); ++v) { - if (v->gameId != game && !game.empty()) { - printf("Found %s, only adding %s per --game option, ignoring...\n", v->gameId.c_str(), game.c_str()); + if ((v->engineId != engineId || v->gameId != gameId) + && !gameId.empty()) { + printf("Found %s, only adding %s per --game option, ignoring...\n", + buildQualifiedGameName(v->engineId, v->gameId).c_str(), + buildQualifiedGameName(engineId, gameId).c_str()); } else if (ConfMan.hasGameDomain(v->preferredTarget)) { // TODO Better check for game already added? - printf("Found %s, but has already been added, skipping\n", v->gameId.c_str()); + printf("Found %s, but has already been added, skipping\n", + buildQualifiedGameName(v->engineId, v->gameId).c_str()); } else { Common::String target = EngineMan.createTargetForGame(*v); count++; @@ -894,7 +990,7 @@ static int recAddGames(const Common::FSNode &dir, const Common::String &game, bo // Display added game info printf("Game Added: \n Target: %s\n GameID: %s\n Name: %s\n Language: %s\n Platform: %s\n", target.c_str(), - v->gameId.c_str(), + buildQualifiedGameName(v->engineId, v->gameId).c_str(), v->description.c_str(), Common::getLanguageDescription(v->language), Common::getPlatformDescription(v->platform) @@ -906,7 +1002,7 @@ static int recAddGames(const Common::FSNode &dir, const Common::String &game, bo Common::FSList files; if (dir.getChildren(files, Common::FSNode::kListDirectoriesOnly)) { for (Common::FSList::const_iterator file = files.begin(); file != files.end(); ++file) { - count += recAddGames(*file, game, recursive); + count += recAddGames(*file, engineId, gameId, recursive); } } } @@ -914,10 +1010,10 @@ static int recAddGames(const Common::FSNode &dir, const Common::String &game, bo return count; } -static bool addGames(const Common::String &path, const Common::String &game, bool recursive) { +static bool addGames(const Common::String &path, const Common::String &engineId, const Common::String &gameId, bool recursive) { //Current directory Common::FSNode dir(path); - int added = recAddGames(dir, game, recursive); + int added = recAddGames(dir, engineId, gameId, recursive); printf("Added %d games\n", added); if (added == 0 && !recursive) { printf("Consider using --recursive to search inside subdirectories\n"); @@ -963,7 +1059,7 @@ static void runDetectorTest() { bool gameidDiffers = false; DetectedGames::const_iterator x; for (x = candidates.begin(); x != candidates.end(); ++x) { - gameidDiffers |= (scumm_stricmp(gameid.c_str(), x->gameId.c_str()) != 0); + gameidDiffers |= !gameid.equalsIgnoreCase(x->gameId); } if (candidates.empty()) { @@ -1073,7 +1169,8 @@ void upgradeTargets() { // At this point, g points to a GameDescriptor which we can use to update // the target referred to by dom. We update several things - // Always set the gameid explicitly (in case of legacy targets) + // Always set the engine ID and game ID explicitly (in case of legacy targets) + dom["engineid"] = g->engineId; dom["gameid"] = g->gameId; // Always set the GUI options. The user should not modify them, and engines might @@ -1102,7 +1199,7 @@ void upgradeTargets() { // ScummVM still generates an incorrect description string. So, the description // should only be updated if the user explicitly requests this. #if 0 - if (desc != g->description()) { + if (desc != g->description) { printf(" -> update desc from '%s' to\n '%s' ?\n", desc.c_str(), g->description.c_str()); dom["description"] = g->description; } @@ -1130,6 +1227,15 @@ bool processSettings(Common::String &command, Common::StringMap &settings, Commo #ifndef DISABLE_COMMAND_LINE + // Check the --game argument refers to a known game id. + QualifiedGameDescriptor gameOption; + if (settings.contains("game")) { + gameOption = findGameMatchingName(settings["game"]); + if (!gameOption.gameId) { + usage("Unrecognized game '%s'. Use the --list-games command for a list of accepted values.\n", settings["game"].c_str()); + } + } + // Handle commands passed via the command line (like --list-targets and // --list-games). This must be done after the config file and the plugins // have been loaded. @@ -1139,6 +1245,9 @@ bool processSettings(Common::String &command, Common::StringMap &settings, Commo } else if (command == "list-games") { listGames(); return true; + } else if (command == "list-engines") { + listEngines(); + return true; } else if (command == "list-saves") { err = listSaves(settings["game"]); return true; @@ -1168,17 +1277,17 @@ bool processSettings(Common::String &command, Common::StringMap &settings, Commo // From an UX point of view, however, it might get confusing. // Consider removing this if consensus says otherwise. } else { - command = detectGames(settings["path"], settings["game"], resursive); + command = detectGames(settings["path"], gameOption.engineId, gameOption.gameId, resursive); if (command.empty()) { err = Common::kNoGameDataFoundError; return true; } } } else if (command == "detect") { - detectGames(settings["path"], settings["game"], settings["recursive"] == "true"); + detectGames(settings["path"], gameOption.engineId, gameOption.gameId, settings["recursive"] == "true"); return true; } else if (command == "add") { - addGames(settings["path"], settings["game"], settings["recursive"] == "true"); + addGames(settings["path"], gameOption.engineId, gameOption.gameId, settings["recursive"] == "true"); return true; } #ifdef DETECTOR_TESTING_HACK @@ -1201,28 +1310,17 @@ bool processSettings(Common::String &command, Common::StringMap &settings, Commo // domain (i.e. a target) matching this argument, or alternatively // whether there is a gameid matching that name. if (!command.empty()) { - PlainGameDescriptor gd = EngineMan.findGame(command); - if (ConfMan.hasGameDomain(command) || gd.gameId) { - bool idCameFromCommandLine = false; - - // WORKAROUND: Fix for bug #1719463: "DETECTOR: Launching - // undefined target adds launcher entry" - // - // We designate gameids which come strictly from command line - // so AdvancedDetector will not save config file with invalid - // gameid in case target autoupgrade was performed - if (!ConfMan.hasGameDomain(command)) { - idCameFromCommandLine = true; - } - + QualifiedGameDescriptor gd; + if (ConfMan.hasGameDomain(command)) { + // Command is a known target ConfMan.setActiveDomain(command); - - if (idCameFromCommandLine) - ConfMan.set("id_came_from_command_line", "1"); - + } else if (gd = findGameMatchingName(command), gd.gameId) { + // Command is a known game ID + Common::String domainName = createTemporaryTarget(gd.engineId, gd.gameId); + ConfMan.setActiveDomain(domainName); } else { #ifndef DISABLE_COMMAND_LINE - usage("Unrecognized game target '%s'", command.c_str()); + usage("Unrecognized game '%s'. Use the --list-targets and --list-games commands for a list of accepted values.", command.c_str()); #endif // DISABLE_COMMAND_LINE } } diff --git a/base/main.cpp b/base/main.cpp index 6917df63124..c9943aebd70 100644 --- a/base/main.cpp +++ b/base/main.cpp @@ -107,39 +107,50 @@ static bool launcherDialog() { } static const Plugin *detectPlugin() { - const Plugin *plugin = nullptr; + // Figure out the engine ID and game ID + Common::String engineId = ConfMan.get("engineid"); + Common::String gameId = ConfMan.get("gameid"); - // Make sure the gameid is set in the config manager, and that it is lowercase. - Common::String gameid(ConfMan.getActiveDomainName()); - assert(!gameid.empty()); - if (ConfMan.hasKey("gameid")) { - gameid = ConfMan.get("gameid"); + // Print text saying what's going on + printf("User picked target '%s' (engine ID '%s', game ID '%s')...\n", ConfMan.getActiveDomainName().c_str(), engineId.c_str(), gameId.c_str()); - // Set last selected game, that the game will be highlighted - // on RTL - ConfMan.set("lastselectedgame", ConfMan.getActiveDomainName(), Common::ConfigManager::kApplicationDomain); - ConfMan.flushToDisk(); + // At this point the engine ID and game ID must be known + if (engineId.empty()) { + warning("The engine ID is not set for target '%s'", ConfMan.getActiveDomainName().c_str()); + return 0; } - gameid.toLowercase(); - ConfMan.set("gameid", gameid); + if (gameId.empty()) { + warning("The game ID is not set for target '%s'", ConfMan.getActiveDomainName().c_str()); + return 0; + } - // Query the plugins and find one that will handle the specified gameid - printf("User picked target '%s' (gameid '%s')...\n", ConfMan.getActiveDomainName().c_str(), gameid.c_str()); - printf(" Looking for a plugin supporting this gameid... "); + const Plugin *plugin = EngineMan.findPlugin(engineId); + if (!plugin) { + warning("'%s' is an invalid engine ID. Use the --list-engines command to list supported engine IDs", engineId.c_str()); + return 0; + } - PlainGameDescriptor game = EngineMan.findGame(gameid, &plugin); - - if (plugin == 0) { - printf("failed\n"); - warning("%s is an invalid gameid. Use the --list-games option to list supported gameid", gameid.c_str()); - } else { - printf("%s\n Starting '%s'\n", plugin->getName(), game.description); + // Query the plugin for the game descriptor + printf(" Looking for a plugin supporting this target... %s\n", plugin->getName()); + PlainGameDescriptor game = plugin->get().findGame(gameId.c_str()); + if (!game.gameId) { + warning("'%s' is an invalid game ID for the engine '%s'. Use the --list-games option to list supported game IDs", gameId.c_str(), engineId.c_str()); + return 0; } return plugin; } +void saveLastLaunchedTarget(const Common::String &target) { + if (ConfMan.hasGameDomain(target)) { + // Set the last selected game, so the game will be highlighted next time the user + // returns to the launcher. + ConfMan.set("lastselectedgame", target, Common::ConfigManager::kApplicationDomain); + ConfMan.flushToDisk(); + } +} + // TODO: specify the possible return values here static Common::Error runGame(const Plugin *plugin, OSystem &system, const Common::String &edebuglevels) { // Determine the game data path, for validation and error messages @@ -162,11 +173,11 @@ static Common::Error runGame(const Plugin *plugin, OSystem &system, const Common #endif // Verify that the game path refers to an actual directory - if (!dir.exists()) { + if (!dir.exists()) { err = Common::kPathDoesNotExist; - } else if (!dir.isDirectory()) { + } else if (!dir.isDirectory()) { err = Common::kPathNotDirectory; - } + } // Create the game engine if (err.getCode() == Common::kNoError) { @@ -208,7 +219,7 @@ static Common::Error runGame(const Plugin *plugin, OSystem &system, const Common Common::String caption(ConfMan.get("description")); if (caption.empty()) { - PlainGameDescriptor game = EngineMan.findGame(ConfMan.get("gameid")); + QualifiedGameDescriptor game = EngineMan.findTarget(ConfMan.getActiveDomainName()); if (game.description) { caption = game.description; } @@ -521,6 +532,10 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) { // work as well as it should. In theory everything should be destroyed // cleanly, so this is now enabled to encourage people to fix bits :) while (0 != ConfMan.getActiveDomain()) { + saveLastLaunchedTarget(ConfMan.getActiveDomainName()); + + EngineMan.upgradeTargetIfNecessary(ConfMan.getActiveDomainName()); + // Try to find a plugin which feels responsible for the specified game. const Plugin *plugin = detectPlugin(); if (plugin) { diff --git a/base/plugins.cpp b/base/plugins.cpp index 4fe5be1cf82..3d1c8b0fd19 100644 --- a/base/plugins.cpp +++ b/base/plugins.cpp @@ -288,14 +288,14 @@ void PluginManagerUncached::init() { /** * Try to load the plugin by searching in the ConfigManager for a matching - * gameId under the domain 'plugin_files'. + * engine ID under the domain 'engine_plugin_files'. **/ -bool PluginManagerUncached::loadPluginFromGameId(const Common::String &gameId) { - Common::ConfigManager::Domain *domain = ConfMan.getDomain("plugin_files"); +bool PluginManagerUncached::loadPluginFromEngineId(const Common::String &engineId) { + Common::ConfigManager::Domain *domain = ConfMan.getDomain("engine_plugin_files"); if (domain) { - if (domain->contains(gameId)) { - Common::String filename = (*domain)[gameId]; + if (domain->contains(engineId)) { + Common::String filename = (*domain)[engineId]; if (loadPluginByFileName(filename)) { return true; @@ -327,17 +327,17 @@ bool PluginManagerUncached::loadPluginByFileName(const Common::String &filename) /** * Update the config manager with a plugin file name that we found can handle - * the game. + * the engine. **/ -void PluginManagerUncached::updateConfigWithFileName(const Common::String &gameId) { +void PluginManagerUncached::updateConfigWithFileName(const Common::String &engineId) { // Check if we have a filename for the current plugin if ((*_currentPlugin)->getFileName()) { - if (!ConfMan.hasMiscDomain("plugin_files")) - ConfMan.addMiscDomain("plugin_files"); + if (!ConfMan.hasMiscDomain("engine_plugin_files")) + ConfMan.addMiscDomain("engine_plugin_files"); - Common::ConfigManager::Domain *domain = ConfMan.getDomain("plugin_files"); + Common::ConfigManager::Domain *domain = ConfMan.getDomain("engine_plugin_files"); assert(domain); - (*domain)[gameId] = (*_currentPlugin)->getFileName(); + (*domain)[engineId] = (*_currentPlugin)->getFileName(); ConfMan.flushToDisk(); } @@ -480,62 +480,54 @@ DECLARE_SINGLETON(EngineManager); * This function works for both cached and uncached PluginManagers. * For the cached version, most of the logic here will short circuit. * - * For the uncached version, we first try to find the plugin using the gameId + * For the uncached version, we first try to find the plugin using the engineId * and only if we can't find it there, we loop through the plugins. **/ -PlainGameDescriptor EngineManager::findGame(const Common::String &gameName, const Plugin **plugin) const { - // First look for the game using the plugins in memory. This is critical - // for calls coming from inside games - PlainGameDescriptor result = findGameInLoadedPlugins(gameName, plugin); - if (result.gameId) { - return result; +QualifiedGameList EngineManager::findGamesMatching(const Common::String &engineId, const Common::String &gameId) const { + QualifiedGameList results; + + if (!engineId.empty()) { + // If we got an engine name, look for THE game only in that engine + const Plugin *p = EngineMan.findPlugin(engineId); + if (p) { + const MetaEngine &engine = p->get(); + + PlainGameDescriptor pluginResult = engine.findGame(gameId.c_str()); + if (pluginResult.gameId) { + results.push_back(QualifiedGameDescriptor(engine.getEngineId(), pluginResult)); + } + } + } else { + // This is a slow path, we have to scan the list of plugins + PluginMan.loadFirstPlugin(); + do { + results.push_back(findGameInLoadedPlugins(gameId)); + } while (PluginMan.loadNextPlugin()); } - // Now look for the game using the gameId. This is much faster than scanning plugin - // by plugin - if (PluginMan.loadPluginFromGameId(gameName)) { - result = findGameInLoadedPlugins(gameName, plugin); - if (result.gameId) { - return result; - } - } - - // We failed to find it using the gameid. Scan the list of plugins - PluginMan.loadFirstPlugin(); - do { - result = findGameInLoadedPlugins(gameName, plugin); - if (result.gameId) { - // Update with new plugin file name - PluginMan.updateConfigWithFileName(gameName); - break; - } - } while (PluginMan.loadNextPlugin()); - - return result; + return results; } /** * Find the game within the plugins loaded in memory **/ -PlainGameDescriptor EngineManager::findGameInLoadedPlugins(const Common::String &gameName, const Plugin **plugin) const { +QualifiedGameList EngineManager::findGameInLoadedPlugins(const Common::String &gameId) const { // Find the GameDescriptor for this target const PluginList &plugins = getPlugins(); - if (plugin) - *plugin = 0; - + QualifiedGameList results; PluginList::const_iterator iter; for (iter = plugins.begin(); iter != plugins.end(); ++iter) { - PlainGameDescriptor pgd = (*iter)->get().findGame(gameName.c_str()); - if (pgd.gameId) { - if (plugin) - *plugin = *iter; - return pgd; + const MetaEngine &engine = (*iter)->get(); + PlainGameDescriptor pluginResult = engine.findGame(gameId.c_str()); + + if (pluginResult.gameId) { + results.push_back(QualifiedGameDescriptor(engine.getEngineId(), pluginResult)); } } - return PlainGameDescriptor::empty(); + return results; } DetectionResults EngineManager::detectGames(const Common::FSList &fslist) const { @@ -552,7 +544,6 @@ DetectionResults EngineManager::detectGames(const Common::FSList &fslist) const DetectedGames engineCandidates = metaEngine.detectGames(fslist); for (uint i = 0; i < engineCandidates.size(); i++) { - engineCandidates[i].engineName = metaEngine.getName(); engineCandidates[i].path = fslist.begin()->getParent().getPath(); engineCandidates[i].shortPath = fslist.begin()->getParent().getDisplayName(); candidates.push_back(engineCandidates[i]); @@ -598,6 +589,7 @@ Common::String EngineManager::createTargetForGame(const DetectedGame &game) { ConfMan.addGameDomain(domain); // Copy all non-empty relevant values into the new domain + addStringToConf("engineid", game.engineId, domain); addStringToConf("gameid", game.gameId, domain); addStringToConf("description", game.description, domain); addStringToConf("language", Common::getLanguageCode(game.language), domain); @@ -624,6 +616,164 @@ Common::String EngineManager::createTargetForGame(const DetectedGame &game) { return domain; } +const Plugin *EngineManager::findLoadedPlugin(const Common::String &engineId) const { + const PluginList &plugins = getPlugins(); + + for (PluginList::const_iterator iter = plugins.begin(); iter != plugins.end(); iter++) + if (engineId == (*iter)->get().getEngineId()) + return *iter; + + return 0; +} + +const Plugin *EngineManager::findPlugin(const Common::String &engineId) const { + // First look for the game using the plugins in memory. This is critical + // for calls coming from inside games + const Plugin *plugin = findLoadedPlugin(engineId); + if (plugin) + return plugin; + + // Now look for the plugin using the engine ID. This is much faster than scanning plugin + // by plugin + if (PluginMan.loadPluginFromEngineId(engineId)) { + plugin = findLoadedPlugin(engineId); + if (plugin) + return plugin; + } + + // We failed to find it using the engine ID. Scan the list of plugins + const PluginList &plugins = getPlugins(); + if (!plugins.empty()) { + PluginMan.loadFirstPlugin(); + do { + plugin = findLoadedPlugin(engineId); + if (plugin) { + // Update with new plugin file name + PluginMan.updateConfigWithFileName(engineId); + return plugin; + } + } while (PluginMan.loadNextPlugin()); + } + + return 0; +} + +QualifiedGameDescriptor EngineManager::findTarget(const Common::String &target, const Plugin **plugin) const { + // Ignore empty targets + if (target.empty()) + return QualifiedGameDescriptor(); + + // Lookup the domain. If we have no domain, fallback on the old function [ultra-deprecated]. + const Common::ConfigManager::Domain *domain = ConfMan.getDomain(target); + if (!domain || !domain->contains("gameid") || !domain->contains("engineid")) + return QualifiedGameDescriptor(); + + // Look for the engine ID + const Plugin *foundPlugin = findPlugin(domain->getVal("engineid")); + if (!foundPlugin) { + return QualifiedGameDescriptor(); + } + + // Make sure it does support the game ID + const MetaEngine &engine = foundPlugin->get(); + PlainGameDescriptor desc = engine.findGame(domain->getVal("gameid").c_str()); + if (!desc.gameId) { + return QualifiedGameDescriptor(); + } + + if (plugin) + *plugin = foundPlugin; + + return QualifiedGameDescriptor(engine.getEngineId(), desc); +} + +void EngineManager::upgradeTargetIfNecessary(const Common::String &target) const { + Common::ConfigManager::Domain *domain = ConfMan.getDomain(target); + assert(domain); + + if (!domain->contains("engineid")) { + upgradeTargetForEngineId(target); + } +} + +void EngineManager::upgradeTargetForEngineId(const Common::String &target) const { + Common::ConfigManager::Domain *domain = ConfMan.getDomain(target); + assert(domain); + + debug("Target '%s' lacks an engine ID, upgrading...", target.c_str()); + + Common::String oldGameId = domain->getVal("gameid"); + Common::String path = domain->getVal("path"); + + // At this point the game ID and game path must be known + if (oldGameId.empty()) { + warning("The game ID is required to upgrade target '%s'", target.c_str()); + return; + } + if (path.empty()) { + warning("The game path is required to upgrade target '%s'", target.c_str()); + return; + } + + // Game descriptor for the upgraded target + Common::String engineId; + Common::String newGameId; + + // First, try to update entries for engines that previously used the "single id" system + // Search for an engine whose ID is the game ID + const Plugin *plugin = findPlugin(oldGameId); + if (plugin) { + // Run detection on the game path + Common::FSNode dir(path); + Common::FSList files; + if (!dir.getChildren(files, Common::FSNode::kListAll)) { + warning("Failed to access path '%s' when upgrading target '%s'", path.c_str(), target.c_str()); + return; + } + + // Take the first detection entry + const MetaEngine &metaEngine = plugin->get(); + DetectedGames candidates = metaEngine.detectGames(files); + if (candidates.empty()) { + warning("No games supported by the engine '%s' were found in path '%s' when upgrading target '%s'", + metaEngine.getEngineId(), path.c_str(), target.c_str()); + return; + } + + engineId = candidates[0].engineId; + newGameId = candidates[0].gameId; + } + + // Next, try to find an engine with the game ID in its supported games list + if (engineId.empty()) { + QualifiedGameList candidates = findGamesMatching("", oldGameId); + if (candidates.size() > 1) { + warning("Multiple matching engines were found when upgrading target '%s'", target.c_str()); + return; + } else if (!candidates.empty()) { + engineId = candidates[0].engineId; + newGameId = candidates[0].gameId; + } + } + + if (engineId.empty() || newGameId.empty()) { + warning("No matching engine was found when upgrading target '%s'", target.c_str()); + return; + } + + domain->setVal("engineid", engineId); + domain->setVal("gameid", newGameId); + + // Save a backup of the pre-upgrade gameId to the config file + if (newGameId != oldGameId) { + domain->setVal("oldgameid", oldGameId); + } + + debug("Upgrade complete (engine ID '%s', game ID '%s')", engineId.c_str(), newGameId.c_str()); + + ConfMan.flushToDisk(); +} + // Music plugins #include "audio/musicplugin.h" diff --git a/base/plugins.h b/base/plugins.h index c1909049340..9919c1a3782 100644 --- a/base/plugins.h +++ b/base/plugins.h @@ -315,8 +315,8 @@ public: virtual void init() {} virtual void loadFirstPlugin() {} virtual bool loadNextPlugin() { return false; } - virtual bool loadPluginFromGameId(const Common::String &gameId) { return false; } - virtual void updateConfigWithFileName(const Common::String &gameId) {} + virtual bool loadPluginFromEngineId(const Common::String &engineId) { return false; } + virtual void updateConfigWithFileName(const Common::String &engineId) {} // Functions used only by the cached PluginManager virtual void loadAllPlugins(); @@ -345,8 +345,8 @@ public: virtual void init(); virtual void loadFirstPlugin(); virtual bool loadNextPlugin(); - virtual bool loadPluginFromGameId(const Common::String &gameId); - virtual void updateConfigWithFileName(const Common::String &gameId); + virtual bool loadPluginFromEngineId(const Common::String &engineId); + virtual void updateConfigWithFileName(const Common::String &engineId); virtual void loadAllPlugins() {} // we don't allow these virtual void loadAllPluginsOfType(PluginType type) {} diff --git a/common/archive.cpp b/common/archive.cpp index 7e189654a69..586f3c4fd10 100644 --- a/common/archive.cpp +++ b/common/archive.cpp @@ -115,7 +115,7 @@ void SearchSet::addDirectory(const String &name, const FSNode &dir, int priority if (!dir.exists() || !dir.isDirectory()) return; - add(name, new FSDirectory(dir, depth, flat), priority); + add(name, new FSDirectory(dir, depth, flat, _ignoreClashes), priority); } void SearchSet::addSubDirectoriesMatching(const FSNode &directory, String origPattern, bool ignoreCase, int priority, int depth, bool flat) { diff --git a/common/archive.h b/common/archive.h index d76d0c49669..2cf75553713 100644 --- a/common/archive.h +++ b/common/archive.h @@ -152,7 +152,10 @@ class SearchSet : public Archive { // Add an archive keeping the list sorted by descending priority. void insert(const Node& node); + bool _ignoreClashes; + public: + SearchSet() : _ignoreClashes(false) { } virtual ~SearchSet() { clear(); } /** @@ -247,6 +250,12 @@ public: * opening the first file encountered that matches the name. */ virtual SeekableReadStream *createReadStreamForMember(const String &name) const; + + /** + * Ignore clashes when adding directories. For more details see the corresponding parameter + * in FSDirectory documentation + */ + void setIgnoreClashes(bool ignoreClashes) { _ignoreClashes = ignoreClashes; } }; diff --git a/common/debug-channels.h b/common/debug-channels.h index 0fb80068038..a2df35102ff 100644 --- a/common/debug-channels.h +++ b/common/debug-channels.h @@ -80,7 +80,7 @@ public: void clearAllDebugChannels(); /** - * Enables an debug channel. + * Enables a debug channel. * * @param name the name of the debug channel to enable * @return true on success, false on failure @@ -88,13 +88,29 @@ public: bool enableDebugChannel(const String &name); /** - * Disables an debug channel. + * Enables a debug channel. + * + * @param channel The debug channel + * @return true on success, false on failure + */ + bool enableDebugChannel(uint32 channel); + + /** + * Disables a debug channel. * * @param name the name of the debug channel to disable * @return true on success, false on failure */ bool disableDebugChannel(const String &name); + /** + * Disables a debug channel. + * + * @param channel The debug channel + * @return true on success, false on failure + */ + bool disableDebugChannel(uint32 channel); + typedef List DebugChannelList; /** diff --git a/common/debug.cpp b/common/debug.cpp index 5db8990db80..568d2d52cb7 100644 --- a/common/debug.cpp +++ b/common/debug.cpp @@ -78,6 +78,11 @@ bool DebugManager::enableDebugChannel(const String &name) { } } +bool DebugManager::enableDebugChannel(uint32 channel) { + gDebugChannelsEnabled |= channel; + return true; +} + bool DebugManager::disableDebugChannel(const String &name) { DebugChannelMap::iterator i = gDebugChannels.find(name); @@ -91,6 +96,11 @@ bool DebugManager::disableDebugChannel(const String &name) { } } +bool DebugManager::disableDebugChannel(uint32 channel) { + gDebugChannelsEnabled &= ~channel; + return true; +} + DebugManager::DebugChannelList DebugManager::listDebugChannels() { DebugChannelList tmp; for (DebugChannelMap::iterator i = gDebugChannels.begin(); i != gDebugChannels.end(); ++i) diff --git a/common/events.h b/common/events.h index 723545469fb..d5245428506 100644 --- a/common/events.h +++ b/common/events.h @@ -86,7 +86,8 @@ enum EventType { EVENT_VIRTUAL_KEYBOARD = 20, #endif - EVENT_DROP_FILE = 23 + EVENT_DROP_FILE = 23, + EVENT_CLIPBOARD_UPDATE = 27 /* START of ResidualVM-specific code */ , diff --git a/common/file.cpp b/common/file.cpp index 0d760cb5094..6228c6640b0 100644 --- a/common/file.cpp +++ b/common/file.cpp @@ -166,7 +166,7 @@ bool DumpFile::open(const String &filename, bool createPath) { delete node; continue; } - if (!node->create(true)) warning("DumpFile: unable to create directories from path prefix"); + if (!node->createDirectory()) warning("DumpFile: unable to create directories from path prefix"); delete node; } } diff --git a/common/fs.cpp b/common/fs.cpp index 54fdf892f26..89c19aaaabf 100644 --- a/common/fs.cpp +++ b/common/fs.cpp @@ -152,22 +152,40 @@ WriteStream *FSNode::createWriteStream() const { return _realNode->createWriteStream(); } -FSDirectory::FSDirectory(const FSNode &node, int depth, bool flat) - : _node(node), _cached(false), _depth(depth), _flat(flat) { +bool FSNode::createDirectory() const { + if (_realNode == nullptr) + return false; + + if (_realNode->exists()) { + if (_realNode->isDirectory()) { + warning("FSNode::createDirectory: '%s' already exists", getName().c_str()); + } else { + warning("FSNode::createDirectory: '%s' is a file", getName().c_str()); + } + return false; + } + + return _realNode->createDirectory(); } -FSDirectory::FSDirectory(const String &prefix, const FSNode &node, int depth, bool flat) - : _node(node), _cached(false), _depth(depth), _flat(flat) { +FSDirectory::FSDirectory(const FSNode &node, int depth, bool flat, bool ignoreClashes) + : _node(node), _cached(false), _depth(depth), _flat(flat), _ignoreClashes(ignoreClashes) { +} + +FSDirectory::FSDirectory(const String &prefix, const FSNode &node, int depth, bool flat, + bool ignoreClashes) + : _node(node), _cached(false), _depth(depth), _flat(flat), _ignoreClashes(ignoreClashes) { setPrefix(prefix); } -FSDirectory::FSDirectory(const String &name, int depth, bool flat) - : _node(name), _cached(false), _depth(depth), _flat(flat) { +FSDirectory::FSDirectory(const String &name, int depth, bool flat, bool ignoreClashes) + : _node(name), _cached(false), _depth(depth), _flat(flat), _ignoreClashes(ignoreClashes) { } -FSDirectory::FSDirectory(const String &prefix, const String &name, int depth, bool flat) - : _node(name), _cached(false), _depth(depth), _flat(flat) { +FSDirectory::FSDirectory(const String &prefix, const String &name, int depth, bool flat, + bool ignoreClashes) + : _node(name), _cached(false), _depth(depth), _flat(flat), _ignoreClashes(ignoreClashes) { setPrefix(prefix); } @@ -237,11 +255,12 @@ SeekableReadStream *FSDirectory::createReadStreamForMember(const String &name) c return stream; } -FSDirectory *FSDirectory::getSubDirectory(const String &name, int depth, bool flat) { - return getSubDirectory(String(), name, depth, flat); +FSDirectory *FSDirectory::getSubDirectory(const String &name, int depth, bool flat, bool ignoreClashes) { + return getSubDirectory(String(), name, depth, flat, ignoreClashes); } -FSDirectory *FSDirectory::getSubDirectory(const String &prefix, const String &name, int depth, bool flat) { +FSDirectory *FSDirectory::getSubDirectory(const String &prefix, const String &name, int depth, + bool flat, bool ignoreClashes) { if (name.empty() || !_node.isDirectory()) return nullptr; @@ -249,7 +268,7 @@ FSDirectory *FSDirectory::getSubDirectory(const String &prefix, const String &na if (!node) return nullptr; - return new FSDirectory(prefix, *node, depth, flat); + return new FSDirectory(prefix, *node, depth, flat, ignoreClashes); } void FSDirectory::cacheDirectoryRecursive(FSNode node, int depth, const String& prefix) const { @@ -270,17 +289,26 @@ void FSDirectory::cacheDirectoryRecursive(FSNode node, int depth, const String& // since the hashmap is case insensitive, we need to check for clashes when caching if (it->isDirectory()) { if (!_flat && _subDirCache.contains(lowercaseName)) { - warning("FSDirectory::cacheDirectory: name clash when building cache, ignoring sub-directory '%s'", name.c_str()); + // Always warn in this case as it's when there are 2 directories at the same place with different case + // That means a problem in user installation as lookups are always done case insensitive + warning("FSDirectory::cacheDirectory: name clash when building cache, ignoring sub-directory '%s'", + name.c_str()); } else { if (_subDirCache.contains(lowercaseName)) { - warning("FSDirectory::cacheDirectory: name clash when building subDirCache with subdirectory '%s'", name.c_str()); + if (!_ignoreClashes) { + warning("FSDirectory::cacheDirectory: name clash when building subDirCache with subdirectory '%s'", + name.c_str()); + } } cacheDirectoryRecursive(*it, depth - 1, _flat ? prefix : lowercaseName + "/"); _subDirCache[lowercaseName] = *it; } } else { if (_fileCache.contains(lowercaseName)) { - warning("FSDirectory::cacheDirectory: name clash when building cache, ignoring file '%s'", name.c_str()); + if (!_ignoreClashes) { + warning("FSDirectory::cacheDirectory: name clash when building cache, ignoring file '%s'", + name.c_str()); + } } else { _fileCache[lowercaseName] = *it; } diff --git a/common/fs.h b/common/fs.h index 6ff5c6eb8da..718f47ff561 100644 --- a/common/fs.h +++ b/common/fs.h @@ -230,6 +230,15 @@ public: * @return pointer to the stream object, 0 in case of a failure */ WriteStream *createWriteStream() const; + + /** + * Creates a directory referred by this node. This assumes that this + * node refers to non-existing directory. If this is not the case, + * false is returned. + * + * @return true if the directory was created, false otherwise. + */ + bool createDirectory() const; }; /** @@ -258,6 +267,12 @@ public: * are cached without the relative path, so in the example above * c:\my\data\file.ext would be cached as file.ext. * + * When the 'ignoreClashes' argument to the constructor is true, name clashes are + * expected by the engine. It means that files which clash should be identical and + * getSubDirectory shouldn't be used on clashing directories. This flag is useful + * in flat mode when there are directories with same name at different places in the + * tree whose name isn't relevant for the engine code. + * * Client code can customize cache by using the constructors with the 'prefix' * parameter. In this case, the prefix is prepended to each entry in the cache, * and effectively treated as a 'virtual' parent subdirectory. FSDirectory adds @@ -267,7 +282,10 @@ public: * */ class FSDirectory : public Archive { - FSNode _node; + FSNode _node; + int _depth; + bool _flat; + bool _ignoreClashes; String _prefix; // string that is prepended to each cache item key void setPrefix(const String &prefix); @@ -277,8 +295,6 @@ class FSDirectory : public Archive { typedef HashMap NodeCache; mutable NodeCache _fileCache, _subDirCache; mutable bool _cached; - mutable int _depth; - mutable bool _flat; // look for a match FSNode *lookupCache(NodeCache &cache, const String &name) const; @@ -295,17 +311,19 @@ public: * unbound FSDirectory if name is not found on the filesystem or if the node is not a * valid directory. */ - FSDirectory(const String &name, int depth = 1, bool flat = false); - FSDirectory(const FSNode &node, int depth = 1, bool flat = false); + FSDirectory(const String &name, int depth = 1, bool flat = false, + bool ignoreClashes = false); + FSDirectory(const FSNode &node, int depth = 1, bool flat = false, + bool ignoreClashes = false); /** * Create a FSDirectory representing a tree with the specified depth. The parameter * prefix is prepended to the keys in the cache. See class comment. */ FSDirectory(const String &prefix, const String &name, int depth = 1, - bool flat = false); + bool flat = false, bool ignoreClashes = false); FSDirectory(const String &prefix, const FSNode &node, int depth = 1, - bool flat = false); + bool flat = false, bool ignoreClashes = false); virtual ~FSDirectory(); @@ -319,8 +337,10 @@ public: * for an explanation of the prefix parameter. * @return a new FSDirectory instance */ - FSDirectory *getSubDirectory(const String &name, int depth = 1, bool flat = false); - FSDirectory *getSubDirectory(const String &prefix, const String &name, int depth = 1, bool flat = false); + FSDirectory *getSubDirectory(const String &name, int depth = 1, bool flat = false, + bool ignoreClashes = false); + FSDirectory *getSubDirectory(const String &prefix, const String &name, int depth = 1, + bool flat = false, bool ignoreClashes = false); /** * Checks for existence in the cache. A full match of relative path and filename is needed diff --git a/common/ini-file.cpp b/common/ini-file.cpp index 1bf0a0eec6c..4c4acc9e60d 100644 --- a/common/ini-file.cpp +++ b/common/ini-file.cpp @@ -28,7 +28,9 @@ namespace Common { -bool INIFile::isValidName(const String &name) { +bool INIFile::isValidName(const String &name) const { + if (_allowNonEnglishCharacters) + return true; const char *p = name.c_str(); while (*p && (isAlnum(*p) || *p == '-' || *p == '_' || *p == '.' || *p == ' ')) p++; @@ -36,9 +38,7 @@ bool INIFile::isValidName(const String &name) { } INIFile::INIFile() { -} - -INIFile::~INIFile() { + _allowNonEnglishCharacters = false; } void INIFile::clear() { @@ -108,7 +108,7 @@ bool INIFile::loadFromStream(SeekableReadStream &stream) { // is, verify that it only consists of alphanumerics, // periods, dashes and underscores). Mohawk Living Books games // can have periods in their section names. - while (*p && (isAlnum(*p) || *p == '-' || *p == '_' || *p == '.' || *p == ' ')) + while (*p && ((_allowNonEnglishCharacters && *p != ']') || isAlnum(*p) || *p == '-' || *p == '_' || *p == '.' || *p == ' ')) p++; if (*p == '\0') @@ -125,7 +125,10 @@ bool INIFile::loadFromStream(SeekableReadStream &stream) { section.comment = comment; comment.clear(); - assert(isValidName(section.name)); + if (!isValidName(section.name)) { + warning("Invalid section name: %s", section.name.c_str()); + return false; + } } else { // This line should be a line with a 'key=value' pair, or an empty one. @@ -145,12 +148,15 @@ bool INIFile::loadFromStream(SeekableReadStream &stream) { // Split string at '=' into 'key' and 'value'. First, find the "=" delimeter. const char *p = strchr(t, '='); - if (!p) - error("Config file buggy: Junk found in line line %d: '%s'", lineno, t); - - // Extract the key/value pair - kv.key = String(t, p); - kv.value = String(p + 1); + if (!p) { + warning("Config file buggy: Junk found in line line %d: '%s'", lineno, t); + kv.key = String(t); + kv.value.clear(); + } else { + // Extract the key/value pair + kv.key = String(t, p); + kv.value = String(p + 1); + } // Trim of spaces kv.key.trim(); @@ -160,7 +166,10 @@ bool INIFile::loadFromStream(SeekableReadStream &stream) { kv.comment = comment; comment.clear(); - assert(isValidName(kv.key)); + if (!isValidName(kv.key)) { + warning("Invalid key name: %s", kv.key.c_str()); + return false; + } section.keys.push_back(kv); } @@ -237,7 +246,11 @@ void INIFile::addSection(const String §ion) { } void INIFile::removeSection(const String §ion) { - assert(isValidName(section)); + if (!isValidName(section)) { + warning("Invalid section name: %s", section.c_str()); + return; + } + for (List
::iterator i = _sections.begin(); i != _sections.end(); ++i) { if (section.equalsIgnoreCase(i->name)) { _sections.erase(i); @@ -247,14 +260,25 @@ void INIFile::removeSection(const String §ion) { } bool INIFile::hasSection(const String §ion) const { - assert(isValidName(section)); + if (!isValidName(section)) { + warning("Invalid section name: %s", section.c_str()); + return false; + } + const Section *s = getSection(section); return s != nullptr; } void INIFile::renameSection(const String &oldName, const String &newName) { - assert(isValidName(oldName)); - assert(isValidName(newName)); + if (!isValidName(oldName)) { + warning("Invalid section name: %s", oldName.c_str()); + return; + } + + if (!isValidName(newName)) { + warning("Invalid section name: %s", newName.c_str()); + return; + } Section *os = getSection(oldName); const Section *ns = getSection(newName); @@ -275,8 +299,15 @@ void INIFile::renameSection(const String &oldName, const String &newName) { bool INIFile::hasKey(const String &key, const String §ion) const { - assert(isValidName(key)); - assert(isValidName(section)); + if (!isValidName(key)) { + warning("Invalid key name: %s", key.c_str()); + return false; + } + + if (!isValidName(section)) { + warning("Invalid section name: %s", section.c_str()); + return false; + } const Section *s = getSection(section); if (!s) @@ -285,8 +316,15 @@ bool INIFile::hasKey(const String &key, const String §ion) const { } void INIFile::removeKey(const String &key, const String §ion) { - assert(isValidName(key)); - assert(isValidName(section)); + if (!isValidName(key)) { + warning("Invalid key name: %s", key.c_str()); + return; + } + + if (!isValidName(section)) { + warning("Invalid section name: %s", section.c_str()); + return; + } Section *s = getSection(section); if (s) @@ -294,9 +332,15 @@ void INIFile::removeKey(const String &key, const String §ion) { } bool INIFile::getKey(const String &key, const String §ion, String &value) const { - assert(isValidName(key)); - assert(isValidName(section)); + if (!isValidName(key)) { + warning("Invalid key name: %s", key.c_str()); + return false; + } + if (!isValidName(section)) { + warning("Invalid section name: %s", section.c_str()); + return false; + } const Section *s = getSection(section); if (!s) return false; @@ -308,8 +352,16 @@ bool INIFile::getKey(const String &key, const String §ion, String &value) co } void INIFile::setKey(const String &key, const String §ion, const String &value) { - assert(isValidName(key)); - assert(isValidName(section)); + if (!isValidName(key)) { + warning("Invalid key name: %s", key.c_str()); + return; + } + + if (!isValidName(section)) { + warning("Invalid section name: %s", section.c_str()); + return; + } + // TODO: Verify that value is valid, too. In particular, it shouldn't // contain CR or LF... @@ -389,4 +441,8 @@ void INIFile::Section::removeKey(const String &key) { } } +void INIFile::allowNonEnglishCharacters() { + _allowNonEnglishCharacters = true; +} + } // End of namespace Common diff --git a/common/ini-file.h b/common/ini-file.h index f27a8b94256..5d72f23bb9f 100644 --- a/common/ini-file.h +++ b/common/ini-file.h @@ -78,7 +78,7 @@ public: public: INIFile(); - ~INIFile(); + ~INIFile() {} // TODO: Maybe add a copy constructor etc.? @@ -88,7 +88,7 @@ public: * underscores. In particular, white space and "#", "=", "[", "]" * are not valid! */ - static bool isValidName(const String &name); + bool isValidName(const String &name) const; /** Reset everything stored in this ini file. */ void clear(); @@ -115,8 +115,11 @@ public: void listKeyValues(StringMap &kv); + void allowNonEnglishCharacters(); + private: SectionList _sections; + bool _allowNonEnglishCharacters; Section *getSection(const String §ion); const Section *getSection(const String §ion) const; diff --git a/common/json.cpp b/common/json.cpp index 89f780bfc84..93ab0601bd5 100644 --- a/common/json.cpp +++ b/common/json.cpp @@ -142,6 +142,7 @@ bool JSON::extractString(const char **data, String &str) { while (**data != 0) { // Save the char so we can change it if need be char next_char = **data; + uint32 next_uchar = 0; // Escaping something? if (next_char == '\\') { @@ -167,31 +168,24 @@ bool JSON::extractString(const char **data, String &str) { case 't': next_char = '\t'; break; case 'u': { - // We need 5 chars (4 hex + the 'u') or its not valid - if (!simplejson_wcsnlen(*data, 5)) - return false; - - // Deal with the chars next_char = 0; - for (int i = 0; i < 4; i++) { - // Do it first to move off the 'u' and leave us on the - // final hex digit as we move on by one later on + next_uchar = parseUnicode(data); + // If the codepoint is a high surrogate, we should have a low surrogate now + if (next_uchar >= 0xD800 && next_uchar <= 0xDBFF) { (*data)++; - - next_char <<= 4; - - // Parse the hex digit - if (**data >= '0' && **data <= '9') - next_char |= (**data - '0'); - else if (**data >= 'A' && **data <= 'F') - next_char |= (10 + (**data - 'A')); - else if (**data >= 'a' && **data <= 'f') - next_char |= (10 + (**data - 'a')); - else { - // Invalid hex digit = invalid JSON + if (**data != '\\') return false; - } - } + (*data)++; + uint32 low_surrogate = parseUnicode(data); + if (low_surrogate < 0xDC00 || low_surrogate > 0xDFFF) + return false; + //next_uchar = 0x10000 + (next_uchar - 0xD800) * 0x400 + (low_surrogate - 0xDC00); + next_uchar = (next_uchar << 10) + low_surrogate - 0x35FDC00u; + } else if (next_uchar >= 0xDC00 && next_uchar <= 0xDFFF) + return false; // low surrogate, which should only follow a high surrogate + // Check this is a valid code point + if (next_uchar > 0x10FFFF) + return false; break; } @@ -215,7 +209,29 @@ bool JSON::extractString(const char **data, String &str) { } // Add the next char - str += next_char; + if (next_char != 0) + str += next_char; + else { + if (next_uchar < 0x80) + // 1-byte character (ASCII) + str += (char)next_uchar; + else if (next_uchar <= 0x7FF) { + // 2-byte characters: 110xxxxx 10xxxxxx + str += (char)(0xC0 | (next_uchar >> 6)); + str += (char)(0x80 | (next_uchar & 0x3F)); + } else if (next_uchar <= 0xFFFF) { + // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx + str += (char)(0xE0 | (next_uchar >> 12)); + str += (char)(0x80 | ((next_uchar >> 6) & 0x3F)); + str += (char)(0x80 | (next_uchar & 0x3F)); + } else { + // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + str += (char)(0xF0 | (next_uchar >> 18)); + str += (char)(0x80 | ((next_uchar >> 12) & 0x3F)); + str += (char)(0x80 | ((next_uchar >> 6) & 0x3F)); + str += (char)(0x80 | (next_uchar & 0x3F)); + } + } // Move on (*data)++; @@ -225,6 +241,48 @@ bool JSON::extractString(const char **data, String &str) { return false; } +/** +* Parses some text as though it is a unicode hexadecimal sequence. +* It assumes that the data is currently pointing on the 'u' part of '\uXXXX`. +* +* @access protected +* +* @param char** data Pointer to a char* that contains the JSON text +* @param String& str Reference to a String to receive the extracted string +* +* @return uint32 Returns the unicode code point value or 0xFFFFFFFF in case of error. +*/ +uint32 JSON::parseUnicode(const char **data) { + if (**data != 'u') + return 0xFFFFFFFF; + // We need 5 chars (4 hex + the 'u') or its not valid + if (!simplejson_wcsnlen(*data, 5)) + return 0xFFFFFFFF; + + // Deal with the chars + uint32 codepoint = 0; + for (int i = 0; i < 4; i++) { + // Do it first to move off the 'u' and leave us on the + // final hex digit as we move on by one later on + (*data)++; + + codepoint <<= 4; + + // Parse the hex digit + if (**data >= '0' && **data <= '9') + codepoint |= (**data - '0'); + else if (**data >= 'A' && **data <= 'F') + codepoint |= (10 + (**data - 'A')); + else if (**data >= 'a' && **data <= 'f') + codepoint |= (10 + (**data - 'a')); + else { + // Invalid hex digit + return 0xFFFFFFFF; + } + } + return codepoint; +} + /** * Parses some text as though it is an integer * @@ -644,6 +702,8 @@ JSONValue::JSONValue(const JSONValue &source) { break; } + default: + // fallthrough intended case JSONType_Null: // Nothing to do. break; @@ -963,6 +1023,8 @@ String JSONValue::stringifyImpl(size_t const indentDepth) const { String const indentStr1 = indent(indentDepth1); switch (_type) { + default: + // fallthrough intended case JSONType_Null: ret_string = "null"; break; @@ -1039,33 +1101,30 @@ String JSONValue::stringifyString(const String &str) { String::const_iterator iter = str.begin(); while (iter != str.end()) { - char chr = *iter; + uint32 uchr = decodeUtf8Char(iter, str.end()); + if (uchr == 0xFFFFFFFF) + break; // error - truncate the result - if (chr == '"' || chr == '\\' || chr == '/') { + if (uchr == '"' || uchr == '\\' || uchr == '/') { str_out += '\\'; - str_out += chr; - } else if (chr == '\b') { + str_out += (char)uchr; + } else if (uchr == '\b') { str_out += "\\b"; - } else if (chr == '\f') { + } else if (uchr == '\f') { str_out += "\\f"; - } else if (chr == '\n') { + } else if (uchr == '\n') { str_out += "\\n"; - } else if (chr == '\r') { + } else if (uchr == '\r') { str_out += "\\r"; - } else if (chr == '\t') { + } else if (uchr == '\t') { str_out += "\\t"; - } else if (chr < ' ' || chr > 126) { - str_out += "\\u"; - for (int i = 0; i < 4; i++) { - int value = (chr >> 12) & 0xf; - if (value >= 0 && value <= 9) - str_out += (char)('0' + value); - else if (value >= 10 && value <= 15) - str_out += (char)('A' + (value - 10)); - chr <<= 4; - } + } else if (uchr >= ' ' && uchr <= 126 ) { + str_out += (char)uchr; } else { - str_out += chr; + if (uchr <= 0xFFFF) + str_out += String::format("\\u%04x", uchr); + else + str_out += String::format("\\u%04x\\u%04x", 0xD7C0 + (uchr >> 10), 0xDC00 + (uchr & 0x3FF)); } iter++; @@ -1075,6 +1134,86 @@ String JSONValue::stringifyString(const String &str) { return str_out; } +/** +* Decode the next utf-8 character in the String pointed to by begin. +* +* @param String::const_iterator &iter Iterator pointing to the start of the character to decode. +* +* @param const String::const_iterator &end Iterator pointing past the end of the string being decoded. +* +* @return The codepoint value for the next utf-8 character starting at the current iterator position, +* or 0xFFFFFFFF in case of error. +*/ +uint32 JSONValue::decodeUtf8Char(String::const_iterator &iter, const String::const_iterator &end) { + uint8 state = 0; + uint32 codepoint = 0; + int nbRead = 0; + do { + uint8 byte = uint8(*iter); + state = decodeUtf8Byte(state, codepoint, byte); + ++nbRead; + if (state == 0) + return codepoint; + } while (state != 1 && ++iter != end); + if (state == 1) { + // We failed to read this as a UTF-8 character. The string might be encoded differently, which + // would be invalid (since the json standard indicate the string has to be in utf-8) but rather + // that return 0FFFFFFFF and truncate, try to recover from it by rewinding and returning the + // raw byte. + while (--nbRead > 0) { --iter; } + uint8 byte = uint8(*iter); + warning("Invalid UTF-8 character 0x%x in JSON string.", byte); + return byte; + } + return 0xFFFFFFFF; +} + +/** +* Decode one byte from a UTF-8 string. +* +* The function must initially (for the first byte) be called with a state of 0, and then +* with the state from the previous byte until it returns 0 (success) or 1 (failure). +* +* Copyright (c) 2008-2009 Bjoern Hoehrmann +* See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. +* +* @access private +* +* @param uint8 state The state from the previous byte, or 0 when decoding the first byte. +* +* @param uint32 &codepoint The codepoint value. Unless the returned state is 0, the codepoint is +* a partial reasult and the function needs to be called again with the next byte. +* +* @param uint8 byte The byte to decode. +* +* @return The state of the utf8 decoder: 0 if a character has been decoded, 1 in case of +* error, and any other value for decoding in progress. +*/ +uint8 JSONValue::decodeUtf8Byte(uint8 state, uint32 &codepoint, uint8 byte) { + static const uint8 utf8d[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF + 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF + 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF + 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF + 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2 + 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4 + 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6 + 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8 + }; + + const uint8 type = utf8d[byte]; + codepoint = state != 0 ? + (codepoint << 6) | (byte & 0x3f) : + (0xFF >> type) & byte; + return utf8d[256 + state * 16 + type]; +} + /** * Creates the indentation string for the depth given * diff --git a/common/json.h b/common/json.h index a911196d180..c1e630ca32f 100644 --- a/common/json.h +++ b/common/json.h @@ -130,6 +130,8 @@ protected: private: static String stringifyString(const String &str); + static uint32 decodeUtf8Char(String::const_iterator &begin, const String::const_iterator &end); + static uint8 decodeUtf8Byte(uint8 state, uint32 &codepoint, uint8 byte); String stringifyImpl(size_t const indentDepth) const; static String indent(size_t depth); @@ -155,6 +157,7 @@ public: protected: static bool skipWhitespace(const char **data); static bool extractString(const char **data, String &str); + static uint32 parseUnicode(const char **data); static double parseInt(const char **data); static double parseDecimal(const char **data); private: diff --git a/common/rational.cpp b/common/rational.cpp index 90e44576a75..84c1e4bee0d 100644 --- a/common/rational.cpp +++ b/common/rational.cpp @@ -51,6 +51,11 @@ Rational::Rational(int num, int denom) { cancel(); } +Rational::Rational(const Rational &rational) { + _num = rational._num; + _denom = rational._denom; +} + void Rational::cancel() { // Cancel the fraction by dividing both the num and the denom // by their greatest common divisor. diff --git a/common/rational.h b/common/rational.h index 89caaf25b4b..bd240c99f3a 100644 --- a/common/rational.h +++ b/common/rational.h @@ -34,6 +34,7 @@ public: Rational(); Rational(int num); Rational(int num, int denom); + Rational(const Rational &rational); Rational &operator=(const Rational &right); Rational &operator=(int right); diff --git a/common/str.cpp b/common/str.cpp index 24341ddc44b..383a61a6871 100644 --- a/common/str.cpp +++ b/common/str.cpp @@ -518,7 +518,7 @@ void String::wordWrap(const uint32 maxLength) { makeUnique(); - enum { kNoSpace = 0xFFFFFFFF }; + const uint32 kNoSpace = 0xFFFFFFFF; uint32 i = 0; while (i < _size) { @@ -605,6 +605,31 @@ void String::replace(uint32 posOri, uint32 countOri, const char *str, } +uint32 String::find(const String &str, uint32 pos) const { + if (pos >= _size) { + return npos; + } + + const char *strP = str.c_str(); + + for (const_iterator cur = begin() + pos; *cur; ++cur) { + uint i = 0; + while (true) { + if (!strP[i]) { + return cur - begin(); + } + + if (cur[i] != strP[i]) { + break; + } + + ++i; + } + } + + return npos; +} + // static String String::format(const char *fmt, ...) { String output; diff --git a/common/str.h b/common/str.h index 54044cfac06..92cbc8952be 100644 --- a/common/str.h +++ b/common/str.h @@ -168,6 +168,8 @@ public: bool contains(const char *x) const; bool contains(char x) const; + uint32 find(const String &str, uint32 pos = 0) const; + /** Return uint64 corrensponding to String's contents. */ uint64 asUint64() const; diff --git a/common/system.h b/common/system.h index 2091525b24b..9a73cb7c328 100644 --- a/common/system.h +++ b/common/system.h @@ -204,6 +204,12 @@ protected: */ FilesystemFactory *_fsFactory; + /** + * Used by the default clipboard implementation, for backends that don't + * implement clipboard support. + */ + Common::String _clipboard; + private: /** * Indicate if initBackend() has been called. @@ -389,8 +395,11 @@ public: kFeatureDisplayLogFile, /** - * The presence of this feature indicates whether the hasTextInClipboard(), - * getTextFromClipboard() and setTextInClipboard() calls are supported. + * The presence of this feature indicates whether the system clipboard is + * available. If this feature is not present, the hasTextInClipboard(), + * getTextFromClipboard() and setTextInClipboard() calls can still be used, + * however it should not be used in scenarios where the user is expected to + * copy data outside of the application. * * This feature has no associated state. */ @@ -995,9 +1004,6 @@ public: * Fills the screen with a given color value. * !!! Not used in ResidualVM !!! * - * @note We are using uint32 here even though currently - * we only support 8bpp indexed mode. Thus the value should - * be always inside [0, 255] for now. */ virtual void fillScreen(uint32 col) = 0; @@ -1571,7 +1577,7 @@ public: * * @return true if there is text in the clipboard, false otherwise */ - virtual bool hasTextInClipboard() { return false; } + virtual bool hasTextInClipboard() { return !_clipboard.empty(); } /** * Returns clipboard contents as a String. @@ -1582,7 +1588,7 @@ public: * * @return clipboard contents ("" if hasTextInClipboard() == false) */ - virtual Common::String getTextFromClipboard() { return ""; } + virtual Common::String getTextFromClipboard() { return _clipboard; } /** * Set the content of the clipboard to the given string. @@ -1593,7 +1599,7 @@ public: * * @return true if the text was properly set in the clipboard, false otherwise */ - virtual bool setTextInClipboard(const Common::String &text) { return false; } + virtual bool setTextInClipboard(const Common::String &text) { _clipboard = text; return true; } /** * Open the given Url in the default browser (if available on the target diff --git a/common/ustr.cpp b/common/ustr.cpp index 8e41299e525..2dec93f3d78 100644 --- a/common/ustr.cpp +++ b/common/ustr.cpp @@ -90,7 +90,7 @@ U32String::U32String(const char *beginP, const char *endP) : _size(0), _str(_sto initWithCStr(beginP, endP - beginP); } -U32String::U32String(const String &str) : _size(0) { +U32String::U32String(const String &str) : _size(0), _str(_storage) { initWithCStr(str.c_str(), str.size()); } @@ -232,6 +232,30 @@ void U32String::deleteChar(uint32 p) { _size--; } +void U32String::deleteLastChar() { + if (_size > 0) + deleteChar(_size - 1); +} + +void U32String::erase(uint32 p, uint32 len) { + assert(p < _size); + + makeUnique(); + // If len == npos or p + len is over the end, remove all the way to the end + if (len == npos || p + len >= _size) { + // Delete char at p as well. So _size = (p - 1) + 1 + _size = p; + // Null terminate + _str[_size] = 0; + return; + } + + for ( ; p + len <= _size; p++) { + _str[p] = _str[p + len]; + } + _size -= len; +} + void U32String::clear() { decRefCount(_extern._refCount); @@ -423,7 +447,7 @@ void U32String::initWithCStr(const char *str, uint32 len) { // Copy the string into the storage area for (size_t idx = 0; idx < len; ++idx, ++str) - _str[idx] = *str; + _str[idx] = (byte)(*str); _str[len] = 0; } diff --git a/common/ustr.h b/common/ustr.h index 7f20207969c..85ee6d52db2 100644 --- a/common/ustr.h +++ b/common/ustr.h @@ -162,6 +162,12 @@ public: */ void deleteChar(uint32 p); + /** Remove the last character from the string. */ + void deleteLastChar(); + + /** Remove all characters from position p to the p + len. If len = String::npos, removes all characters to the end */ + void erase(uint32 p, uint32 len = npos); + /** Clears the string, making it empty. */ void clear(); diff --git a/common/util.cpp b/common/util.cpp index a6c7958a0da..4b7537f8ec6 100644 --- a/common/util.cpp +++ b/common/util.cpp @@ -20,17 +20,7 @@ * */ -#define FORBIDDEN_SYMBOL_EXCEPTION_isalnum -#define FORBIDDEN_SYMBOL_EXCEPTION_isalpha -#define FORBIDDEN_SYMBOL_EXCEPTION_isdigit -#define FORBIDDEN_SYMBOL_EXCEPTION_isxdigit -#define FORBIDDEN_SYMBOL_EXCEPTION_isnumber -#define FORBIDDEN_SYMBOL_EXCEPTION_islower -#define FORBIDDEN_SYMBOL_EXCEPTION_isspace -#define FORBIDDEN_SYMBOL_EXCEPTION_isupper -#define FORBIDDEN_SYMBOL_EXCEPTION_isprint -#define FORBIDDEN_SYMBOL_EXCEPTION_ispunct - +#define FORBIDDEN_SYMBOL_EXCEPTION_ctype_h #include "common/util.h" #include "common/debug.h" @@ -163,4 +153,46 @@ bool isPunct(int c) { return ispunct((byte)c); } +bool isCntrl(int c) { + ENSURE_ASCII_CHAR(c); + return iscntrl((byte)c); +} + +bool isGraph(int c) { + ENSURE_ASCII_CHAR(c); + return isgraph((byte)c); +} + + +#pragma mark - + + +Common::String getHumanReadableBytes(uint64 bytes, Common::String &unitsOut) { + if (bytes < 1024) { + unitsOut = "B"; + return Common::String::format("%lu", (unsigned long int)bytes); + } + + double floating = bytes / 1024.0; + unitsOut = "KB"; + + if (floating >= 1024) { + floating /= 1024.0; + unitsOut = "MB"; + } + + if (floating >= 1024) { + floating /= 1024.0; + unitsOut = "GB"; + } + + if (floating >= 1024) { // woah + floating /= 1024.0; + unitsOut = "TB"; + } + + // print one digit after floating point + return Common::String::format("%.1f", floating); +} + } // End of namespace Common diff --git a/common/util.h b/common/util.h index 5f853da43a3..8254e972d06 100644 --- a/common/util.h +++ b/common/util.h @@ -195,16 +195,43 @@ bool isUpper(int c); */ bool isPrint(int c); - /** * Test whether the given character is a punctuation character, - * (i.e not alphanumeric. + * (i.e. not alphanumeric). * * @param c the character to test * @return true if the character is punctuation, false otherwise. */ bool isPunct(int c); +/** + * Test whether the given character is a control character. + * + * @param c the character to test + * @return true if the character is a control character, false otherwise. + */ +bool isCntrl(int c); + +/** + * Test whether the given character has a graphical representation. + * + * @param c the character to test + * @return true if the character is a graphic, false otherwise. + */ +bool isGraph(int c); + + +/** + * Represent bytes size of a file as a number with floating point and + * largest suitable units. For example, 1474560 bytes as 1.4 MB. + * + * @param bytes size in bytes to be represented + * @param unitsOut (out-parameter) string with units + * @note use _() to translate units correctly + * @return string with a floating point number representing given size + */ +Common::String getHumanReadableBytes(uint64 bytes, Common::String &unitsOut); + } // End of namespace Common #endif diff --git a/config.guess b/config.guess index 0967f2afa92..7f9ebbe3109 100755 --- a/config.guess +++ b/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2016 Free Software Foundation, Inc. +# Copyright 1992-2019 Free Software Foundation, Inc. -timestamp='2016-04-02' +timestamp='2019-09-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -15,7 +15,7 @@ timestamp='2016-04-02' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -27,7 +27,7 @@ timestamp='2016-04-02' # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to . @@ -39,7 +39,7 @@ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2016 Free Software Foundation, Inc. +Copyright 1992-2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -84,8 +84,6 @@ if test $# != 0; then exit 1 fi -trap 'exit 1' 1 2 15 - # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a @@ -96,34 +94,38 @@ trap 'exit 1' 1 2 15 # Portable tmp directory creation inspired by the Autoconf team. -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' +tmp= +# shellcheck disable=SC2172 +trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 + +set_cc_for_build() { + : "${TMPDIR=/tmp}" + # shellcheck disable=SC2039 + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD="$driver" + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then +if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi @@ -132,14 +134,14 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown -case "${UNAME_SYSTEM}" in +case "$UNAME_SYSTEM" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu - eval $set_cc_for_build - cat <<-EOF > $dummy.c + set_cc_for_build + cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc @@ -149,13 +151,20 @@ Linux|GNU|GNU/*) LIBC=gnu #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" + + # If ldd exists, use it to detect musl libc. + if command -v ldd >/dev/null && \ + ldd --version 2>&1 | grep -q ^musl + then + LIBC=musl + fi ;; esac # Note: order is significant - the case branches are not exclusive. -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in +case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, @@ -169,27 +178,30 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ - /sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || \ + "/sbin/$sysctl" 2>/dev/null || \ + "/usr/sbin/$sysctl" 2>/dev/null || \ echo unknown)` - case "${UNAME_MACHINE_ARCH}" in + case "$UNAME_MACHINE_ARCH" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) - arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` - endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` - machine=${arch}${endian}-unknown + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine="${arch}${endian}"-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + *) machine="$UNAME_MACHINE_ARCH"-unknown ;; esac # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build + # to ELF recently (or will in the future) and ABI. + case "$UNAME_MACHINE_ARCH" in + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then @@ -205,10 +217,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ;; esac # Determine ABI tags. - case "${UNAME_MACHINE_ARCH}" in + case "$UNAME_MACHINE_ARCH" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' - abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release @@ -216,45 +228,60 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in + case "$UNAME_VERSION" in Debian*) release='-gnu' ;; *) - release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}${abi}" + echo "$machine-${os}${release}${abi-}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" exit ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" + exit ;; + *:MidnightBSD:*:*) + echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" exit ;; *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" exit ;; *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" + exit ;; + *:OS108:*:*) + echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE" exit ;; macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} + echo powerpc-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:Sortix:*:*) - echo ${UNAME_MACHINE}-unknown-sortix + echo "$UNAME_MACHINE"-unknown-sortix + exit ;; + *:Twizzler:*:*) + echo "$UNAME_MACHINE"-unknown-twizzler + exit ;; + *:Redox:*:*) + echo "$UNAME_MACHINE"-unknown-redox + exit ;; + mips:OSF1:*.*) + echo mips-dec-osf1 exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in @@ -307,28 +334,19 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos + echo "$UNAME_MACHINE"-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos + echo "$UNAME_MACHINE"-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition @@ -340,7 +358,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} + echo arm-acorn-riscix"$UNAME_RELEASE" exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos @@ -367,19 +385,19 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} + echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build + set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. @@ -392,13 +410,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in SUN_ARCH=x86_64 fi fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in @@ -407,25 +425,25 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" exit ;; sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} + echo m68k-sun-sunos"$UNAME_RELEASE" exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) - echo m68k-sun-sunos${UNAME_RELEASE} + echo m68k-sun-sunos"$UNAME_RELEASE" ;; sun4) - echo sparc-sun-sunos${UNAME_RELEASE} + echo sparc-sun-sunos"$UNAME_RELEASE" ;; esac exit ;; aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} + echo sparc-auspex-sunos"$UNAME_RELEASE" exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not @@ -436,44 +454,44 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} + echo m68k-milan-mint"$UNAME_RELEASE" exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} + echo m68k-hades-mint"$UNAME_RELEASE" exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} + echo m68k-unknown-mint"$UNAME_RELEASE" exit ;; m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} + echo m68k-apple-machten"$UNAME_RELEASE" exit ;; powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} + echo powerpc-apple-machten"$UNAME_RELEASE" exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} + echo mips-dec-ultrix"$UNAME_RELEASE" exit ;; VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} + echo vax-dec-ultrix"$UNAME_RELEASE" exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} + echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { @@ -482,23 +500,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} + echo mips-mips-riscos"$UNAME_RELEASE" exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax @@ -524,17 +542,17 @@ EOF AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] + if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ + [ "$TARGET_BINARY_INTERFACE"x = x ] then - echo m88k-dg-dgux${UNAME_RELEASE} + echo m88k-dg-dgux"$UNAME_RELEASE" else - echo m88k-dg-dguxbcs${UNAME_RELEASE} + echo m88k-dg-dguxbcs"$UNAME_RELEASE" fi else - echo i586-dg-dgux${UNAME_RELEASE} + echo i586-dg-dgux"$UNAME_RELEASE" fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) @@ -551,7 +569,7 @@ EOF echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id @@ -563,14 +581,14 @@ EOF if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #include main() @@ -581,7 +599,7 @@ EOF exit(0); } EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then echo "$SYSTEM_NAME" else @@ -595,7 +613,7 @@ EOF exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc @@ -604,18 +622,18 @@ EOF IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} + echo "$IBM_ARCH"-ibm-aix"$IBM_REV" exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx @@ -630,28 +648,28 @@ EOF echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + case "$UNAME_MACHINE" in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in + case "$sc_cpu_version" in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in + case "$sc_kernel_bits" in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + if [ "$HP_ARCH" = "" ]; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include @@ -684,13 +702,13 @@ EOF exit (0); } EOF - (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ ${HP_ARCH} = hppa2.0w ] + if [ "$HP_ARCH" = hppa2.0w ] then - eval $set_cc_for_build + set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler @@ -709,15 +727,15 @@ EOF HP_ARCH=hppa64 fi fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} + echo "$HP_ARCH"-hp-hpux"$HPUX_REV" exit ;; ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #include int main () @@ -742,11 +760,11 @@ EOF exit (0); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) @@ -755,7 +773,7 @@ EOF *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) @@ -763,9 +781,9 @@ EOF exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk + echo "$UNAME_MACHINE"-unknown-osf1mk else - echo ${UNAME_MACHINE}-unknown-osf1 + echo "$UNAME_MACHINE"-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) @@ -790,127 +808,120 @@ EOF echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" exit ;; sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} + echo sparc-unknown-bsdi"$UNAME_RELEASE" exit ;; *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" + exit ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi + else + echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf + fi exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_PROCESSOR} in + case "$UNAME_PROCESSOR" in amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; esac + echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin + echo "$UNAME_MACHINE"-pc-cygwin exit ;; *:MINGW64*:*) - echo ${UNAME_MACHINE}-pc-mingw64 + echo "$UNAME_MACHINE"-pc-mingw64 exit ;; *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 + echo "$UNAME_MACHINE"-pc-mingw32 exit ;; *:MSYS*:*) - echo ${UNAME_MACHINE}-pc-msys - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 + echo "$UNAME_MACHINE"-pc-msys exit ;; i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 + echo "$UNAME_MACHINE"-pc-pw32 exit ;; *:Interix*:*) - case ${UNAME_MACHINE} in + case "$UNAME_MACHINE" in x86) - echo i586-pc-interix${UNAME_RELEASE} + echo i586-pc-interix"$UNAME_RELEASE" exit ;; authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} + echo x86_64-unknown-interix"$UNAME_RELEASE" exit ;; IA64) - echo ia64-unknown-interix${UNAME_RELEASE} + echo ia64-unknown-interix"$UNAME_RELEASE" exit ;; esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin + echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin + echo x86_64-pc-cygwin exit ;; prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; *:GNU:*:*) # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix + *:Minix:*:*) + echo "$UNAME_MACHINE"-unknown-minix exit ;; aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in @@ -924,134 +935,168 @@ EOF esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arc:Linux:*:* | arceb:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) - eval $set_cc_for_build + set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi else - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf fi fi exit ;; avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; e2k:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-${LIBC} + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; k1om:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 + sed 's/^ //' << EOF > "$dummy.c" #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el + #undef mips + #undef mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 + #else + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 + #else + LIBCABI=${LIBC} + #endif + #endif + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el + MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} + MIPS_ENDIAN= #else - CPU= + MIPS_ENDIAN= #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`" + test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; + mips64el:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; openrisc*:Linux:*:*) - echo or1k-unknown-linux-${LIBC} + echo or1k-unknown-linux-"$LIBC" exit ;; or32:Linux:*:* | or1k*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; padre:Linux:*:*) - echo sparc-unknown-linux-${LIBC} + echo sparc-unknown-linux-"$LIBC" exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-${LIBC} + echo hppa64-unknown-linux-"$LIBC" exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; - PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; - *) echo hppa-unknown-linux-${LIBC} ;; + PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; + PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; + *) echo hppa-unknown-linux-"$LIBC" ;; esac exit ;; ppc64:Linux:*:*) - echo powerpc64-unknown-linux-${LIBC} + echo powerpc64-unknown-linux-"$LIBC" exit ;; ppc:Linux:*:*) - echo powerpc-unknown-linux-${LIBC} + echo powerpc-unknown-linux-"$LIBC" exit ;; ppc64le:Linux:*:*) - echo powerpc64le-unknown-linux-${LIBC} + echo powerpc64le-unknown-linux-"$LIBC" exit ;; ppcle:Linux:*:*) - echo powerpcle-unknown-linux-${LIBC} + echo powerpcle-unknown-linux-"$LIBC" + exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" exit ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; tile*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-${LIBC} + echo "$UNAME_MACHINE"-dec-linux-"$LIBC" exit ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-${LIBC} + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. @@ -1065,34 +1110,34 @@ EOF # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx + echo "$UNAME_MACHINE"-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop + echo "$UNAME_MACHINE"-unknown-stop exit ;; i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos + echo "$UNAME_MACHINE"-unknown-atheos exit ;; i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable + echo "$UNAME_MACHINE"-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} + echo i386-unknown-lynxos"$UNAME_RELEASE" exit ;; i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp + echo "$UNAME_MACHINE"-pc-msdosdjgpp exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" fi exit ;; i*86:*:5:[678]*) @@ -1102,12 +1147,12 @@ EOF *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}" exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 @@ -1117,9 +1162,9 @@ EOF && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" else - echo ${UNAME_MACHINE}-pc-sysv32 + echo "$UNAME_MACHINE"-pc-sysv32 fi exit ;; pc:*:*:*) @@ -1139,9 +1184,9 @@ EOF exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) @@ -1161,9 +1206,9 @@ EOF test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; @@ -1172,28 +1217,28 @@ EOF test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} + echo m68k-unknown-lynxos"$UNAME_RELEASE" exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} + echo sparc-unknown-lynxos"$UNAME_RELEASE" exit ;; rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} + echo rs6000-unknown-lynxos"$UNAME_RELEASE" exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} + echo powerpc-unknown-lynxos"$UNAME_RELEASE" exit ;; SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} + echo mips-dde-sysv"$UNAME_RELEASE" exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 @@ -1204,7 +1249,7 @@ EOF *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 + echo "$UNAME_MACHINE"-sni-sysv4 else echo ns32k-sni-sysv fi @@ -1224,23 +1269,23 @@ EOF exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos + echo "$UNAME_MACHINE"-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} + echo m68k-apple-aux"$UNAME_RELEASE" exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + echo mips-nec-sysv"$UNAME_RELEASE" else - echo mips-unknown-sysv${UNAME_RELEASE} + echo mips-unknown-sysv"$UNAME_RELEASE" fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. @@ -1259,60 +1304,68 @@ EOF echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} + echo sx4-nec-superux"$UNAME_RELEASE" exit ;; SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} + echo sx5-nec-superux"$UNAME_RELEASE" exit ;; SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} + echo sx6-nec-superux"$UNAME_RELEASE" exit ;; SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} + echo sx7-nec-superux"$UNAME_RELEASE" exit ;; SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} + echo sx8-nec-superux"$UNAME_RELEASE" exit ;; SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} + echo sx8r-nec-superux"$UNAME_RELEASE" exit ;; SX-ACE:SUPER-UX:*:*) - echo sxace-nec-superux${UNAME_RELEASE} + echo sxace-nec-superux"$UNAME_RELEASE" exit ;; Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} + echo powerpc-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval $set_cc_for_build - if test "$UNAME_PROCESSOR" = unknown ; then - UNAME_PROCESSOR=powerpc + UNAME_PROCESSOR=`uname -p` + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + if command -v xcode-select > /dev/null 2> /dev/null && \ + ! xcode-select --print-path > /dev/null 2> /dev/null ; then + # Avoid executing cc if there is no toolchain installed as + # cc will be a stub that puts up a graphical alert + # prompting the user to install developer tools. + CC_FOR_BUILD=no_compiler_found + else + set_cc_for_build fi - if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then - if [ "$CC_FOR_BUILD" != no_compiler_found ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - case $UNAME_PROCESSOR in - i386) UNAME_PROCESSOR=x86_64 ;; - powerpc) UNAME_PROCESSOR=powerpc64 ;; - esac - fi + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then - # Avoid executing cc on OS X 10.9, as it ships with a stub - # that puts up a graphical alert prompting to install - # developer tools. Any system running Mac OS X 10.7 or - # later (Darwin 11 and later) is required to have a 64-bit - # processor. This is not true of the ARM version of Darwin - # that Apple uses in portable devices. - UNAME_PROCESSOR=x86_64 + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE fi - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` @@ -1320,19 +1373,25 @@ EOF UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; - NEO-?:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk${UNAME_RELEASE} + NEO-*:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk"$UNAME_RELEASE" exit ;; NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} + echo nse-tandem-nsk"$UNAME_RELEASE" exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} + NSR-*:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSV-*:NONSTOP_KERNEL:*:*) + echo nsv-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSX-*:NONSTOP_KERNEL:*:*) + echo nsx-tandem-nsk"$UNAME_RELEASE" exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux @@ -1341,18 +1400,19 @@ EOF echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. + # shellcheck disable=SC2154 if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi - echo ${UNAME_MACHINE}-unknown-plan9 + echo "$UNAME_MACHINE"-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 @@ -1373,14 +1433,14 @@ EOF echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} + echo mips-sei-seiux"$UNAME_RELEASE" exit ;; *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in + case "$UNAME_MACHINE" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; @@ -1389,37 +1449,188 @@ EOF echo i386-pc-xenix exit ;; i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` + echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" exit ;; i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos + echo "$UNAME_MACHINE"-pc-rdos exit ;; i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros + echo "$UNAME_MACHINE"-pc-aros exit ;; x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-unknown-esx + echo "$UNAME_MACHINE"-unknown-esx exit ;; amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; + *:Unleashed:*:*) + echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE" + exit ;; +esac + +# No uname command or uname output not recognized. +set_cc_for_build +cat > "$dummy.c" < +#include +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include +#if defined(_SIZE_T_) || defined(SIGLOST) +#include +#endif +#endif +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); +#endif + +#if defined (vax) +#if !defined (ultrix) +#include +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#else +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname un; + uname (&un); + printf ("vax-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("mips-dec-ultrix\n"); exit (0); +#endif +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } + +echo "$0: unable to guess system type" >&2 + +case "$UNAME_MACHINE:$UNAME_SYSTEM" in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 < in order to provide the needed -information to handle your system. +If $0 has already been updated, send the following data and any +information you think might be pertinent to config-patches@gnu.org to +provide the necessary information to handle your system. config.guess timestamp = $timestamp @@ -1438,16 +1649,16 @@ hostinfo = `(hostinfo) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" EOF exit 1 # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/config.sub b/config.sub index 8d39c4ba39f..0f2234c174d 100755 --- a/config.sub +++ b/config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2016 Free Software Foundation, Inc. +# Copyright 1992-2019 Free Software Foundation, Inc. -timestamp='2016-03-30' +timestamp='2019-06-30' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -15,7 +15,7 @@ timestamp='2016-03-30' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -33,7 +33,7 @@ timestamp='2016-03-30' # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases @@ -57,7 +57,7 @@ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -67,7 +67,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2016 Free Software Foundation, Inc. +Copyright 1992-2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -89,12 +89,12 @@ while test $# -gt 0 ; do - ) # Use stdin as input. break ;; -* ) - echo "$me: invalid option $1$help" + echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) # First pass through any local machine types. - echo $1 + echo "$1" exit ;; * ) @@ -110,1234 +110,1164 @@ case $# in exit 1;; esac -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ - linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ - kopensolaris*-gnu* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - android-linux) - os=-linux-android - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac +# Split fields of configuration type +# shellcheck disable=SC2162 +IFS="-" read field1 field2 field3 field4 <&2 + exit 1 ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray | -microblaze*) - os= - basic_machine=$1 + *-*-*-*) + basic_machine=$field1-$field2 + os=$field3-$field4 ;; - -bluegene*) - os=-cnk + *-*-*) + # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two + # parts + maybe_os=$field2-$field3 + case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc \ + | linux-newlib* | linux-musl* | linux-uclibc* | uclinux-uclibc* \ + | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ + | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ + | storm-chaos* | os2-emx* | rtmk-nova*) + basic_machine=$field1 + os=$maybe_os + ;; + android-linux) + basic_machine=$field1-unknown + os=linux-android + ;; + *) + basic_machine=$field1-$field2 + os=$field3 + ;; + esac ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 + *-*) + # A lone config we happen to match not fitting any pattern + case $field1-$field2 in + decstation-3100) + basic_machine=mips-dec + os= + ;; + *-*) + # Second component is usually, but not always the OS + case $field2 in + # Prevent following clause from handling this valid os + sun*os*) + basic_machine=$field1 + os=$field2 + ;; + # Manufacturers + dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ + | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ + | unicom* | ibm* | next | hp | isi* | apollo | altos* \ + | convergent* | ncr* | news | 32* | 3600* | 3100* \ + | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ + | ultra | tti* | harris | dolphin | highlevel | gould \ + | cbm | ns | masscomp | apple | axis | knuth | cray \ + | microblaze* | sim | cisco \ + | oki | wec | wrs | winbond) + basic_machine=$field1-$field2 + os= + ;; + *) + basic_machine=$field1 + os=$field2 + ;; + esac + ;; + esac ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco6) - os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*178) - os=-lynxos178 - ;; - -lynx*5) - os=-lynxos5 - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint + *) + # Convert single-component short-hands not valid as part of + # multi-component configurations. + case $field1 in + 386bsd) + basic_machine=i386-pc + os=bsd + ;; + a29khif) + basic_machine=a29k-amd + os=udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=scout + ;; + alliant) + basic_machine=fx80-alliant + os= + ;; + altos | altos3068) + basic_machine=m68k-altos + os= + ;; + am29k) + basic_machine=a29k-none + os=bsd + ;; + amdahl) + basic_machine=580-amdahl + os=sysv + ;; + amiga) + basic_machine=m68k-unknown + os= + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=bsd + ;; + aros) + basic_machine=i386-pc + os=aros + ;; + aux) + basic_machine=m68k-apple + os=aux + ;; + balance) + basic_machine=ns32k-sequent + os=dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=linux + ;; + cegcc) + basic_machine=arm-unknown + os=cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=bsd + ;; + convex-c2) + basic_machine=c2-convex + os=bsd + ;; + convex-c32) + basic_machine=c32-convex + os=bsd + ;; + convex-c34) + basic_machine=c34-convex + os=bsd + ;; + convex-c38) + basic_machine=c38-convex + os=bsd + ;; + cray) + basic_machine=j90-cray + os=unicos + ;; + crds | unos) + basic_machine=m68k-crds + os= + ;; + da30) + basic_machine=m68k-da30 + os= + ;; + decstation | pmax | pmin | dec3100 | decstatn) + basic_machine=mips-dec + os= + ;; + delta88) + basic_machine=m88k-motorola + os=sysv3 + ;; + dicos) + basic_machine=i686-pc + os=dicos + ;; + djgpp) + basic_machine=i586-pc + os=msdosdjgpp + ;; + ebmon29k) + basic_machine=a29k-amd + os=ebmon + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=ose + ;; + gmicro) + basic_machine=tron-gmicro + os=sysv + ;; + go32) + basic_machine=i386-pc + os=go32 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=hms + ;; + harris) + basic_machine=m88k-harris + os=sysv3 + ;; + hp300 | hp300hpux) + basic_machine=m68k-hp + os=hpux + ;; + hp300bsd) + basic_machine=m68k-hp + os=bsd + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=proelf + ;; + i386mach) + basic_machine=i386-mach + os=mach + ;; + isi68 | isi) + basic_machine=m68k-isi + os=sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=linux + ;; + magnum | m3230) + basic_machine=mips-mips + os=sysv + ;; + merlin) + basic_machine=ns32k-utek + os=sysv + ;; + mingw64) + basic_machine=x86_64-pc + os=mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=mingw32ce + ;; + monitor) + basic_machine=m68k-rom68k + os=coff + ;; + morphos) + basic_machine=powerpc-unknown + os=morphos + ;; + moxiebox) + basic_machine=moxie-unknown + os=moxiebox + ;; + msdos) + basic_machine=i386-pc + os=msdos + ;; + msys) + basic_machine=i686-pc + os=msys + ;; + mvs) + basic_machine=i370-ibm + os=mvs + ;; + nacl) + basic_machine=le32-unknown + os=nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=sysv4 + ;; + netbsd386) + basic_machine=i386-pc + os=netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=newsos + ;; + news1000) + basic_machine=m68030-sony + os=newsos + ;; + necv70) + basic_machine=v70-nec + os=sysv + ;; + nh3000) + basic_machine=m68k-harris + os=cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=cxux + ;; + nindy960) + basic_machine=i960-intel + os=nindy + ;; + mon960) + basic_machine=i960-intel + os=mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=nonstopux + ;; + os400) + basic_machine=powerpc-ibm + os=os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=ose + ;; + os68k) + basic_machine=m68k-none + os=os68k + ;; + paragon) + basic_machine=i860-intel + os=osf + ;; + parisc) + basic_machine=hppa-unknown + os=linux + ;; + pw32) + basic_machine=i586-unknown + os=pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=rdos + ;; + rdos32) + basic_machine=i386-pc + os=rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=coff + ;; + sa29200) + basic_machine=a29k-amd + os=udi + ;; + sei) + basic_machine=mips-sei + os=seiux + ;; + sequent) + basic_machine=i386-sequent + os= + ;; + sps7) + basic_machine=m68k-bull + os=sysv2 + ;; + st2000) + basic_machine=m68k-tandem + os= + ;; + stratus) + basic_machine=i860-stratus + os=sysv4 + ;; + sun2) + basic_machine=m68000-sun + os= + ;; + sun2os3) + basic_machine=m68000-sun + os=sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=sunos4 + ;; + sun3) + basic_machine=m68k-sun + os= + ;; + sun3os3) + basic_machine=m68k-sun + os=sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=sunos4 + ;; + sun4) + basic_machine=sparc-sun + os= + ;; + sun4os3) + basic_machine=sparc-sun + os=sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=solaris2 + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + os= + ;; + sv1) + basic_machine=sv1-cray + os=unicos + ;; + symmetry) + basic_machine=i386-sequent + os=dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=unicos + ;; + t90) + basic_machine=t90-cray + os=unicos + ;; + toad1) + basic_machine=pdp10-xkl + os=tops20 + ;; + tpf) + basic_machine=s390x-ibm + os=tpf + ;; + udi29k) + basic_machine=a29k-amd + os=udi + ;; + ultra3) + basic_machine=a29k-nyu + os=sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=none + ;; + vaxv) + basic_machine=vax-dec + os=sysv + ;; + vms) + basic_machine=vax-dec + os=vms + ;; + vsta) + basic_machine=i386-pc + os=vsta + ;; + vxworks960) + basic_machine=i960-wrs + os=vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=vxworks + ;; + xbox) + basic_machine=i686-pc + os=mingw32 + ;; + ymp) + basic_machine=ymp-cray + os=unicos + ;; + *) + basic_machine=$1 + os= + ;; + esac ;; esac -# Decode aliases for certain CPU-COMPANY combinations. +# Decode 1-component or ad-hoc basic machines case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | aarch64 | aarch64_be \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arceb \ - | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ - | avr | avr32 \ - | ba \ - | be32 | be64 \ - | bfin \ - | c4x | c8051 | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | e2k | epiphany \ - | fido | fr30 | frv | ft32 \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | hexagon \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | k1om \ - | le32 | le64 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa32r6 | mipsisa32r6el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64r6 | mipsisa64r6el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nds32 | nds32le | nds32be \ - | nios | nios2 | nios2eb | nios2el \ - | ns16k | ns32k \ - | open8 | or1k | or1knd | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle \ - | pyramid \ - | riscv32 | riscv64 \ - | rl78 | rx \ - | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu \ - | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ - | ubicom32 \ - | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ - | visium \ - | we32k \ - | x86 | xc16x | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown + # Here we handle the default manufacturer of certain CPU types. It is in + # some cases the only manufacturer, in others, it is the most popular. + w89k) + cpu=hppa1.1 + vendor=winbond ;; - c54x) - basic_machine=tic54x-unknown + op50n) + cpu=hppa1.1 + vendor=oki ;; - c55x) - basic_machine=tic55x-unknown + op60c) + cpu=hppa1.1 + vendor=oki ;; - c6x) - basic_machine=tic6x-unknown + ibm*) + cpu=i370 + vendor=ibm + ;; + orion105) + cpu=clipper + vendor=highlevel + ;; + mac | mpw | mac-mpw) + cpu=m68k + vendor=apple + ;; + pmac | pmac-mpw) + cpu=powerpc + vendor=apple + ;; + + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + cpu=m68000 + vendor=att + ;; + 3b*) + cpu=we32k + vendor=att + ;; + bluegene*) + cpu=powerpc + vendor=ibm + os=cnk + ;; + decsystem10* | dec10*) + cpu=pdp10 + vendor=dec + os=tops10 + ;; + decsystem20* | dec20*) + cpu=pdp10 + vendor=dec + os=tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + cpu=m68k + vendor=motorola + ;; + dpx2*) + cpu=m68k + vendor=bull + os=sysv3 + ;; + encore | umax | mmax) + cpu=ns32k + vendor=encore + ;; + elxsi) + cpu=elxsi + vendor=elxsi + os=${os:-bsd} + ;; + fx2800) + cpu=i860 + vendor=alliant + ;; + genix) + cpu=ns32k + vendor=ns + ;; + h3050r* | hiux*) + cpu=hppa1.1 + vendor=hitachi + os=hiuxwe2 + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + cpu=m68000 + vendor=hp + ;; + hp9k3[2-9][0-9]) + cpu=m68k + vendor=hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + i*86v32) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + os=sysv32 + ;; + i*86v4*) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + os=sysv4 + ;; + i*86v) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + os=sysv + ;; + i*86sol2) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + os=solaris2 + ;; + j90 | j90-cray) + cpu=j90 + vendor=cray + os=${os:-unicos} + ;; + iris | iris4d) + cpu=mips + vendor=sgi + case $os in + irix*) + ;; + *) + os=irix4 + ;; + esac + ;; + miniframe) + cpu=m68000 + vendor=convergent + ;; + *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) + cpu=m68k + vendor=atari + os=mint + ;; + news-3600 | risc-news) + cpu=mips + vendor=sony + os=newsos + ;; + next | m*-next) + cpu=m68k + vendor=next + case $os in + openstep*) + ;; + nextstep*) + ;; + ns2*) + os=nextstep2 + ;; + *) + os=nextstep3 + ;; + esac + ;; + np1) + cpu=np1 + vendor=gould + ;; + op50n-* | op60c-*) + cpu=hppa1.1 + vendor=oki + os=proelf + ;; + pa-hitachi) + cpu=hppa1.1 + vendor=hitachi + os=hiuxwe2 + ;; + pbd) + cpu=sparc + vendor=tti + ;; + pbb) + cpu=m68k + vendor=tti + ;; + pc532) + cpu=ns32k + vendor=pc532 + ;; + pn) + cpu=pn + vendor=gould + ;; + power) + cpu=power + vendor=ibm + ;; + ps2) + cpu=i386 + vendor=ibm + ;; + rm[46]00) + cpu=mips + vendor=siemens + ;; + rtpc | rtpc-*) + cpu=romp + vendor=ibm + ;; + sde) + cpu=mipsisa32 + vendor=sde + os=${os:-elf} + ;; + simso-wrs) + cpu=sparclite + vendor=wrs + os=vxworks + ;; + tower | tower-32) + cpu=m68k + vendor=ncr + ;; + vpp*|vx|vx-*) + cpu=f301 + vendor=fujitsu + ;; + w65) + cpu=w65 + vendor=wdc + ;; + w89k-*) + cpu=hppa1.1 + vendor=winbond + os=proelf + ;; + none) + cpu=none + vendor=none ;; leon|leon[3-9]) - basic_machine=sparc-$basic_machine + cpu=sparc + vendor=$basic_machine ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - ms1) - basic_machine=mt-unknown + leon-*|leon[3-9]-*) + cpu=sparc + vendor=`echo "$basic_machine" | sed 's/-.*//'` ;; - strongarm | thumb | xscale) - basic_machine=arm-unknown + *-*) + # shellcheck disable=SC2162 + IFS="-" read cpu vendor <&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | aarch64-* | aarch64_be-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ - | ba-* \ - | be32-* | be64-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | c8051-* | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | e2k-* | elxsi-* \ - | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | hexagon-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | k1om-* \ - | le32-* | le64-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ - | microblaze-* | microblazeel-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa32r6-* | mipsisa32r6el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64r6-* | mipsisa64r6el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipsr5900-* | mipsr5900el-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* | nios2eb-* | nios2el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | open8-* \ - | or1k*-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ - | pyramid-* \ - | riscv32-* | riscv64-* \ - | rl78-* | romp-* | rs6000-* | rx-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ - | tahoe-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile*-* \ - | tron-* \ - | ubicom32-* \ - | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ - | vax-* \ - | visium-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - asmjs) - basic_machine=asmjs-unknown - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - bluegene*) - basic_machine=powerpc-ibm - os=-cnk - ;; - c54x-*) - basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c55x-*) - basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c6x-*) - basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16 | cr16-*) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dicos) - basic_machine=i686-pc - os=-dicos - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - leon-*|leon[3-9]-*) - basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - microblaze*) - basic_machine=microblaze-xilinx - ;; - mingw64) - basic_machine=x86_64-pc - os=-mingw64 - ;; - mingw32) - basic_machine=i686-pc - os=-mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - os=-mingw32ce - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - moxiebox) - basic_machine=moxie-unknown - os=-moxiebox - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` - ;; - msys) - basic_machine=i686-pc - os=-msys - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - nacl) - basic_machine=le32-unknown - os=-nacl - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - neo-tandem) - basic_machine=neo-tandem - ;; - nse-tandem) - basic_machine=nse-tandem - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 + cpu=$basic_machine + vendor=pc ;; + # These rules are duplicated from below for sake of the special case above; + # i.e. things that normalized to x86 arches should also default to "pc" pc98) - basic_machine=i386-pc + cpu=i386 + vendor=pc ;; - pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + x64 | amd64) + cpu=x86_64 + vendor=pc ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc + # Recognize the basic CPU types without company name. + *) + cpu=$basic_machine + vendor=unknown ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc +esac + +unset -v basic_machine + +# Decode basic machines in the full and proper CPU-Company form. +case $cpu-$vendor in + # Here we handle the default manufacturer of certain CPU types in canonical form. It is in + # some cases the only manufacturer, in others, it is the most popular. + craynv-unknown) + vendor=cray + os=${os:-unicosmp} ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc + c90-unknown | c90-cray) + vendor=cray + os=${os:-unicos} ;; - pentium4) - basic_machine=i786-pc + fx80-unknown) + vendor=alliant ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + romp-unknown) + vendor=ibm ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + mmix-unknown) + vendor=knuth ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + microblaze-unknown | microblazeel-unknown) + vendor=xilinx ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + rs6000-unknown) + vendor=ibm ;; - pn) - basic_machine=pn-gould + vax-unknown) + vendor=dec ;; - power) basic_machine=power-ibm + pdp11-unknown) + vendor=dec ;; - ppc | ppcbe) basic_machine=powerpc-unknown + we32k-unknown) + vendor=att ;; - ppc-* | ppcbe-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + cydra-unknown) + vendor=cydrome ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown + i370-ibm*) + vendor=ibm ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + orion-unknown) + vendor=highlevel ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rdos | rdos64) - basic_machine=x86_64-pc - os=-rdos - ;; - rdos32) - basic_machine=i386-pc - os=-rdos - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; - sde) - basic_machine=mipsisa32-sde - os=-elf - ;; - sei) - basic_machine=mips-sei - os=-seiux - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sh5el) - basic_machine=sh5le-unknown - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - strongarm-* | thumb-*) - basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tile*) - basic_machine=$basic_machine-unknown - os=-linux-gnu - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - xscale-* | xscalee[bl]-*) - basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - z80-*-coff) - basic_machine=z80-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none + xps-unknown | xps100-unknown) + cpu=xps100 + vendor=honeywell ;; -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond + # Here we normalize CPU types with a missing or matching vendor + dpx20-unknown | dpx20-bull) + cpu=rs6000 + vendor=bull + os=${os:-bosx} ;; - op50n) - basic_machine=hppa1.1-oki + + # Here we normalize CPU types irrespective of the vendor + amd64-*) + cpu=x86_64 ;; - op60c) - basic_machine=hppa1.1-oki + blackfin-*) + cpu=bfin + os=linux ;; - romp) - basic_machine=romp-ibm + c54x-*) + cpu=tic54x ;; - mmix) - basic_machine=mmix-knuth + c55x-*) + cpu=tic55x ;; - rs6000) - basic_machine=rs6000-ibm + c6x-*) + cpu=tic6x ;; - vax) - basic_machine=vax-dec + e500v[12]-*) + cpu=powerpc + os=$os"spe" ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown + mips3*-*) + cpu=mips64 ;; - pdp11) - basic_machine=pdp11-dec + ms1-*) + cpu=mt ;; - we32k) - basic_machine=we32k-att + m68knommu-*) + cpu=m68k + os=linux ;; - sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown + m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*) + cpu=s12z ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun + openrisc-*) + cpu=or32 ;; - cydra) - basic_machine=cydra-cydrome + parisc-*) + cpu=hppa + os=linux ;; - orion) - basic_machine=orion-highlevel + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + cpu=i586 ;; - orion105) - basic_machine=clipper-highlevel + pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*) + cpu=i686 ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + cpu=i686 ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple + pentium4-*) + cpu=i786 ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. + pc98-*) + cpu=i386 ;; + ppc-* | ppcbe-*) + cpu=powerpc + ;; + ppcle-* | powerpclittle-*) + cpu=powerpcle + ;; + ppc64-*) + cpu=powerpc64 + ;; + ppc64le-* | powerpc64little-*) + cpu=powerpc64le + ;; + sb1-*) + cpu=mipsisa64sb1 + ;; + sb1el-*) + cpu=mipsisa64sb1el + ;; + sh5e[lb]-*) + cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'` + ;; + spur-*) + cpu=spur + ;; + strongarm-* | thumb-*) + cpu=arm + ;; + tx39-*) + cpu=mipstx39 + ;; + tx39el-*) + cpu=mipstx39el + ;; + x64-*) + cpu=x86_64 + ;; + xscale-* | xscalee[bl]-*) + cpu=`echo "$cpu" | sed 's/^xscale/arm/'` + ;; + + # Recognize the canonical CPU Types that limit and/or modify the + # company names they are paired with. + cr16-*) + os=${os:-elf} + ;; + crisv32-* | etraxfs*-*) + cpu=crisv32 + vendor=axis + ;; + cris-* | etrax*-*) + cpu=cris + vendor=axis + ;; + crx-*) + os=${os:-elf} + ;; + neo-tandem) + cpu=neo + vendor=tandem + ;; + nse-tandem) + cpu=nse + vendor=tandem + ;; + nsr-tandem) + cpu=nsr + vendor=tandem + ;; + nsv-tandem) + cpu=nsv + vendor=tandem + ;; + nsx-tandem) + cpu=nsx + vendor=tandem + ;; + s390-*) + cpu=s390 + vendor=ibm + ;; + s390x-*) + cpu=s390x + vendor=ibm + ;; + tile*-*) + os=${os:-linux-gnu} + ;; + *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 + # Recognize the canonical CPU types that are allowed with any + # company name. + case $cpu in + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | abacus \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ + | alphapca5[67] | alpha64pca5[67] \ + | am33_2.0 \ + | amdgcn \ + | arc | arceb \ + | arm | arm[lb]e | arme[lb] | armv* \ + | avr | avr32 \ + | asmjs \ + | ba \ + | be32 | be64 \ + | bfin | bpf | bs2000 \ + | c[123]* | c30 | [cjt]90 | c4x \ + | c8051 | clipper | craynv | csky | cydra \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | elxsi | epiphany \ + | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \ + | h8300 | h8500 \ + | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i*86 | i860 | i960 | ia16 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle \ + | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ + | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ + | m88110 | m88k | maxq | mb | mcore | mep | metag \ + | microblaze | microblazeel \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64eb | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mmix \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nfp \ + | nios | nios2 | nios2eb | nios2el \ + | none | np1 | ns16k | ns32k | nvptx \ + | open8 \ + | or1k* \ + | or32 \ + | orion \ + | picochip \ + | pdp10 | pdp11 | pj | pjl | pn | power \ + | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \ + | pru \ + | pyramid \ + | riscv | riscv32 | riscv64 \ + | rl78 | romp | rs6000 | rx \ + | score \ + | sh | shl \ + | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \ + | sh[1234]e[lb] | sh[12345][lb]e | sh[23]ele | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \ + | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \ + | spu \ + | tahoe \ + | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \ + | tron \ + | ubicom32 \ + | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \ + | vax \ + | visium \ + | w65 \ + | wasm32 | wasm64 \ + | we32k \ + | x86 | x86_64 | xc16x | xgate | xps100 \ + | xstormy16 | xtensa* \ + | ymp \ + | z8k | z80) + ;; + + *) + echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2 + exit 1 + ;; + esac ;; esac # Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` +case $vendor in + digital*) + vendor=dec ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + commodore*) + vendor=cbm ;; *) ;; @@ -1345,200 +1275,244 @@ esac # Decode manufacturer-specific aliases for certain operating systems. -if [ x"$os" != x"" ] +if [ x$os != x ] then case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -auroraux) - os=-auroraux + # First match some system type aliases that might get confused + # with valid system types. + # solaris* is a basic system type, with this one exception. + auroraux) + os=auroraux ;; - -solaris1 | -solaris1.*) + bluegene*) + os=cnk + ;; + solaris1 | solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; - -solaris) - os=-solaris2 + solaris) + os=solaris2 ;; - -svr4*) - os=-sysv4 + unixware*) + os=sysv4.2uw ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) + gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; - # First accept the basic system types. + # es1800 is here to avoid being matched by es* (a different OS) + es1800*) + os=ose + ;; + # Some version numbers need modification + chorusos*) + os=chorusos + ;; + isc) + os=isc2.2 + ;; + sco6) + os=sco5v6 + ;; + sco5) + os=sco3.2v5 + ;; + sco4) + os=sco3.2v4 + ;; + sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + ;; + sco3.2v[4-9]* | sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + ;; + scout) + # Don't match below + ;; + sco*) + os=sco3.2v2 + ;; + psos*) + os=psos + ;; + # Now accept the basic system types. # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* | -plan9* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* | -cloudabi* | -sortix* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* \ - | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ - | -linux-newlib* | -linux-musl* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ - | -onefs* | -tirtos*) + # Each alternative MUST end in a * to match a version number. + # sysv* is not here because it comes later, after sysvr4. + gnu* | bsd* | mach* | minix* | genix* | ultrix* | irix* \ + | *vms* | esix* | aix* | cnk* | sunos | sunos[34]*\ + | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ + | sym* | kopensolaris* | plan9* \ + | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ + | aos* | aros* | cloudabi* | sortix* | twizzler* \ + | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ + | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \ + | knetbsd* | mirbsd* | netbsd* \ + | bitrig* | openbsd* | solidbsd* | libertybsd* | os108* \ + | ekkobsd* | kfreebsd* | freebsd* | riscix* | lynxos* \ + | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ + | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ + | udi* | eabi* | lites* | ieee* | go32* | aux* | hcos* \ + | chorusrdb* | cegcc* | glidix* \ + | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ + | midipix* | mingw32* | mingw64* | linux-gnu* | linux-android* \ + | linux-newlib* | linux-musl* | linux-uclibc* \ + | uxpv* | beos* | mpeix* | udk* | moxiebox* \ + | interix* | uwin* | mks* | rhapsody* | darwin* \ + | openstep* | oskit* | conix* | pw32* | nonstopux* \ + | storm-chaos* | tops10* | tenex* | tops20* | its* \ + | os2* | vos* | palmos* | uclinux* | nucleus* \ + | morphos* | superux* | rtmk* | windiss* \ + | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ + | skyos* | haiku* | rdos* | toppers* | drops* | es* \ + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix) # Remember, each alternative MUST END IN *, to match a version number. ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) + qnx*) + case $cpu in + x86 | i*86) ;; *) - os=-nto$os + os=nto-$os ;; esac ;; - -nto-qnx*) + hiux*) + os=hiuxwe2 ;; - -nto*) + nto-qnx*) + ;; + nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + sim | xray | os68k* | v88r* \ + | windows* | osx | abug | netware* | os9* \ + | macos* | mpw* | magic* | mmixware* | mon960* | lnews*) ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` + linux-dietlibc) + os=linux-dietlibc ;; - -linux-dietlibc) - os=-linux-dietlibc - ;; - -linux*) + linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` + lynx*178) + os=lynxos178 ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` + lynx*5) + os=lynxos5 ;; - -opened*) - os=-openedition + lynx*) + os=lynxos ;; - -os400*) - os=-os400 + mac*) + os=`echo "$os" | sed -e 's|mac|macos|'` ;; - -wince*) - os=-wince + opened*) + os=openedition ;; - -osfrose*) - os=-osfrose + os400*) + os=os400 ;; - -osf*) - os=-osf + sunos5*) + os=`echo "$os" | sed -e 's|sunos5|solaris2|'` ;; - -utek*) - os=-bsd + sunos6*) + os=`echo "$os" | sed -e 's|sunos6|solaris3|'` ;; - -dynix*) - os=-bsd + wince*) + os=wince ;; - -acis*) - os=-aos + utek*) + os=bsd ;; - -atheos*) - os=-atheos + dynix*) + os=bsd ;; - -syllable*) - os=-syllable + acis*) + os=aos ;; - -386bsd) - os=-bsd + atheos*) + os=atheos ;; - -ctix* | -uts*) - os=-sysv + syllable*) + os=syllable ;; - -nova*) - os=-rtmk-nova + 386bsd) + os=bsd ;; - -ns2 ) - os=-nextstep2 + ctix* | uts*) + os=sysv ;; - -nsk*) - os=-nsk + nova*) + os=rtmk-nova + ;; + ns2) + os=nextstep2 ;; # Preserve the version number of sinix5. - -sinix5.*) + sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; - -sinix*) - os=-sysv4 + sinix*) + os=sysv4 ;; - -tpf*) - os=-tpf + tpf*) + os=tpf ;; - -triton*) - os=-sysv3 + triton*) + os=sysv3 ;; - -oss*) - os=-sysv3 + oss*) + os=sysv3 ;; - -svr4) - os=-sysv4 + svr4*) + os=sysv4 ;; - -svr3) - os=-sysv3 + svr3) + os=sysv3 ;; - -sysvr4) - os=-sysv4 + sysvr4) + os=sysv4 ;; - # This must come after -sysvr4. - -sysv*) + # This must come after sysvr4. + sysv*) ;; - -ose*) - os=-ose + ose*) + os=ose ;; - -es1800*) - os=-ose + *mint | mint[0-9]* | *MiNT | MiNT[0-9]*) + os=mint ;; - -xenix) - os=-xenix + zvmoe) + os=zvmoe ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint + dicos*) + os=dicos ;; - -aros*) - os=-aros + pikeos*) + # Until real need of OS specific support for + # particular features comes up, bare metal + # configurations are quite functional. + case $cpu in + arm*) + os=eabi + ;; + *) + os=elf + ;; + esac ;; - -zvmoe) - os=-zvmoe + nacl*) ;; - -dicos*) - os=-dicos + ios) ;; - -nacl*) + none) ;; - -ios) - ;; - -none) + *-eabi) ;; *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 exit 1 ;; esac @@ -1554,261 +1528,265 @@ else # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. -case $basic_machine in +case $cpu-$vendor in score-*) - os=-elf + os=elf ;; spu-*) - os=-elf + os=elf ;; *-acorn) - os=-riscix1.2 + os=riscix1.2 ;; arm*-rebel) - os=-linux + os=linux ;; arm*-semi) - os=-aout + os=aout ;; c4x-* | tic4x-*) - os=-coff + os=coff ;; c8051-*) - os=-elf + os=elf + ;; + clipper-intergraph) + os=clix ;; hexagon-*) - os=-elf + os=elf ;; tic54x-*) - os=-coff + os=coff ;; tic55x-*) - os=-coff + os=coff ;; tic6x-*) - os=-coff + os=coff ;; # This must come before the *-dec entry. pdp10-*) - os=-tops20 + os=tops20 ;; pdp11-*) - os=-none + os=none ;; *-dec | vax-*) - os=-ultrix4.2 + os=ultrix4.2 ;; m68*-apollo) - os=-domain + os=domain ;; i386-sun) - os=-sunos4.0.2 + os=sunos4.0.2 ;; m68000-sun) - os=-sunos3 + os=sunos3 ;; m68*-cisco) - os=-aout + os=aout ;; mep-*) - os=-elf + os=elf ;; mips*-cisco) - os=-elf + os=elf ;; mips*-*) - os=-elf + os=elf ;; or32-*) - os=-coff + os=coff ;; *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 + os=sysv3 ;; sparc-* | *-sun) - os=-sunos4.1.1 + os=sunos4.1.1 + ;; + pru-*) + os=elf ;; *-be) - os=-beos - ;; - *-haiku) - os=-haiku + os=beos ;; *-ibm) - os=-aix + os=aix ;; *-knuth) - os=-mmixware + os=mmixware ;; *-wec) - os=-proelf + os=proelf ;; *-winbond) - os=-proelf + os=proelf ;; *-oki) - os=-proelf + os=proelf ;; *-hp) - os=-hpux + os=hpux ;; *-hitachi) - os=-hiux + os=hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv + os=sysv ;; *-cbm) - os=-amigaos + os=amigaos ;; *-dg) - os=-dgux + os=dgux ;; *-dolphin) - os=-sysv3 + os=sysv3 ;; m68k-ccur) - os=-rtu + os=rtu ;; m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs + os=luna ;; *-next) - os=-nextstep3 + os=nextstep + ;; + *-sequent) + os=ptx + ;; + *-crds) + os=unos + ;; + *-ns) + os=genix + ;; + i370-*) + os=mvs ;; *-gould) - os=-sysv + os=sysv ;; *-highlevel) - os=-bsd + os=bsd ;; *-encore) - os=-bsd + os=bsd ;; *-sgi) - os=-irix + os=irix ;; *-siemens) - os=-sysv4 + os=sysv4 ;; *-masscomp) - os=-rtu + os=rtu ;; f30[01]-fujitsu | f700-fujitsu) - os=-uxpv + os=uxpv ;; *-rom68k) - os=-coff + os=coff ;; *-*bug) - os=-coff + os=coff ;; *-apple) - os=-macos + os=macos ;; *-atari*) - os=-mint + os=mint + ;; + *-wrs) + os=vxworks ;; *) - os=-none + os=none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) +case $vendor in + unknown) case $os in - -riscix*) + riscix*) vendor=acorn ;; - -sunos*) + sunos*) vendor=sun ;; - -cnk*|-aix*) + cnk*|-aix*) vendor=ibm ;; - -beos*) + beos*) vendor=be ;; - -hpux*) + hpux*) vendor=hp ;; - -mpeix*) + mpeix*) vendor=hp ;; - -hiux*) + hiux*) vendor=hitachi ;; - -unos*) + unos*) vendor=crds ;; - -dgux*) + dgux*) vendor=dg ;; - -luna*) + luna*) vendor=omron ;; - -genix*) + genix*) vendor=ns ;; - -mvs* | -opened*) + clix*) + vendor=intergraph + ;; + mvs* | opened*) vendor=ibm ;; - -os400*) + os400*) vendor=ibm ;; - -ptx*) + ptx*) vendor=sequent ;; - -tpf*) + tpf*) vendor=ibm ;; - -vxsim* | -vxworks* | -windiss*) + vxsim* | vxworks* | windiss*) vendor=wrs ;; - -aux*) + aux*) vendor=apple ;; - -hms*) + hms*) vendor=hitachi ;; - -mpw* | -macos*) + mpw* | macos*) vendor=apple ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + *mint | mint[0-9]* | *MiNT | MiNT[0-9]*) vendor=atari ;; - -vos*) + vos*) vendor=stratus ;; esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac -echo $basic_machine$os +echo "$cpu-$vendor-$os" exit # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/configure b/configure index ae8703496e3..1fca05f234b 100755 --- a/configure +++ b/configure @@ -222,6 +222,7 @@ _amigaospath="Games:ResidualVM" _staticlibpath= _xcodetoolspath= _sparklepath= +_pkgconfig=pkg-config _sdlconfig=sdl2-config _libcurlconfig=curl-config _freetypeconfig=freetype-config @@ -235,8 +236,8 @@ NASM="" _tainted_build=no PANDOC="" _pandocpath="$PATH" -_pandocoutput="README" -_pandocformat="plain" +_pandocformat="default" +_pandocext="default" # The following variables are automatically detected, and should not # be modified otherwise. Consider them read-only. _posix=no @@ -533,7 +534,7 @@ get_system_exe_extension() { riscos) _exeext=",e1f" ;; - 3ds | dreamcast | ds | gamecube | n64 | ps2 | psp | wii) + 3ds | dreamcast | ds | gamecube | n64 | ps2 | psp | switch | wii) _exeext=".elf" ;; gph-linux) @@ -669,6 +670,26 @@ engine_disable_all() { done } +# Enable all unstable engines +engine_enable_all_unstable() { + for engine in $_engines; do + engine_build_default=`get_engine_build_default $engine` + if test $engine_build_default = no ; then + set_var _engine_${engine}_build "yes" + fi + done +} + +# Disable all unstable engines +engine_disable_all_unstable() { + for engine in $_engines; do + engine_build_default=`get_engine_build_default $engine` + if test $engine_build_default = no ; then + set_var _engine_${engine}_build "no" + fi + done +} + # Enable the given engine engine_enable() { # Get the parameter @@ -959,6 +980,10 @@ Game engines: --enable-all-engines enable all engines, including those which are broken or unsupported --disable-all-engines disable all engines + --enable-all-unstable-engines enable the engines which are + broken or unsupported + --disable-all-unstable-engines disable only the engines which are + broken or unsupported --enable-engine=[,...] enable engine(s) listed --disable-engine=[,...] disable engine(s) listed --enable-engine-static=[,...] @@ -1016,6 +1041,7 @@ Optional Libraries: --with-mpeg2-prefix=DIR prefix where libmpeg2 is installed (optional) --enable-mpeg2 enable mpeg2 codec for cutscenes [autodetect] + --with-a52-prefix=DIR Prefix where liba52 is installed (optional) --enable-a52 enable a52 codec for MPEG decoder [autodetect] @@ -1430,6 +1456,12 @@ for ac_option in $@; do --disable-all-engines) engine_disable_all ;; + --enable-all-unstable-engines) + engine_enable_all_unstable + ;; + --disable-all-unstable-engines) + engine_disable_all_unstable + ;; --enable-engine=* | --enable-engines=*) for engine_name in `echo $ac_option | cut -d '=' -f 2- | tr ',' '\n'`; do engine_enable "${engine_name}" @@ -1672,6 +1704,15 @@ samsungtv) _host_cpu=arm _host_alias=arm-linux-gnueabi ;; +switch) + _host_os=switch + _host_cpu=aarch64 + _host_alias=aarch64-none-elf + test "x$prefix" = xNONE && prefix=. + datarootdir='${prefix}/data' + datadir='${datarootdir}' + docdir='${prefix}/doc' + ;; tizen) _host_os=tizen _host_cpu=arm @@ -1725,7 +1766,7 @@ else fi case $_host in -caanoo | gp2x | gp2xwiz | openpandora | ps2 | psp2) +arm-*riscos | caanoo | gp2x | gp2xwiz | openpandora | ps2 | psp | psp2 | switch) if test "$_debug_build" = auto; then # If you want to debug one of these platforms, use '--disable-optimizations --enable-debug' _debug_build=no @@ -1776,7 +1817,7 @@ android) exit 1 fi ;; -3ds | ds | gamecube | wii) +3ds | ds | gamecube | switch | wii) if test -z "$DEVKITPRO"; then echo "Please set DEVKITPRO in your environment. export DEVKITPRO=" exit 1 @@ -1828,6 +1869,15 @@ psp) echo "Please set PSPSDK in your environment. export PSPSDK=" exit 1 fi + + # These have to be set early because the compiler will not link successfully + # during testing otherwise + if test -d "$PSPDEV/psp/lib"; then + append_var LDFLAGS "-L$PSPDEV/psp/lib" + fi + append_var LDFLAGS "-L$PSPSDK/lib" + append_var LDFLAGS "-specs=$_srcdir/backends/platform/psp/psp.spec" + ;; riscos) if test -z "$GCCSDK_INSTALL_ENV"; then @@ -1840,6 +1890,11 @@ riscos) elif `which tokenize >/dev/null 2>&1`; then add_line_to_config_mk "TOKENIZE := tokenize" fi + if test -e "$GCCSDK_INSTALL_ENV/bin/bindhelp"; then + add_line_to_config_mk "BINDHELP := $GCCSDK_INSTALL_ENV/bin/bindhelp" + elif `which bindhelp >/dev/null 2>&1`; then + add_line_to_config_mk "BINDHELP := bindhelp" + fi ;; tizen) if test -z "$TIZEN_ROOTSTRAP"; then @@ -2079,7 +2134,7 @@ if test "$have_gcc" = yes ; then case $_host_os in # newlib-based system include files suppress non-C89 function # declarations under __STRICT_ANSI__ - 3ds | amigaos* | android | androidsdl | dreamcast | ds | gamecube | mingw* | mint* | n64 | psp | ps2 | ps3 | psp2 | tizen | wii | wince ) + 3ds | amigaos* | android | androidsdl | dreamcast | ds | gamecube | mingw* | mint* | n64 | psp | ps2 | ps3 | psp2 | switch | tizen | wii | wince ) ;; *) append_var CXXFLAGS "-ansi" @@ -2153,7 +2208,7 @@ fi # However, some platforms use GNU extensions in system header files, so # for these we must not use -pedantic. case $_host_os in -3ds | android | androidsdl | gamecube | ps2 | psp | tizen | wii | webos) +3ds | android | androidsdl | gamecube | ps2 | psp | switch | tizen | wii | webos) ;; *) # ICC does not support pedantic, while GCC and clang do. @@ -2228,20 +2283,20 @@ echo_n "Checking endianness... " cat > tmp_endianness_check.cpp << EOF unsigned short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; unsigned short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; -void _ascii() { char* s = (char*) ascii_mm; s = (char*) ascii_ii; } +const char * _ascii() { char* s = (char*) ascii_mm; s = (char*) ascii_ii; return s; } unsigned short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; unsigned short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; -void _ebcdic() { char* s = (char*) ebcdic_mm; s = (char*) ebcdic_ii; } +const char * _ebcdic() { char* s = (char*) ebcdic_mm; s = (char*) ebcdic_ii; return s; } int main() { _ascii (); _ebcdic (); return 0; } EOF -$CXX $CXXFLAGS -c -o $TMPO.o tmp_endianness_check.cpp -if $_strings $TMPO.o | grep BIGenDianSyS >/dev/null; then +$CXX $LDFLAGS $CXXFLAGS -o $TMPO$HOSTEXEEXT tmp_endianness_check.cpp +if $_strings $TMPO$HOSTEXEEXT | grep BIGenDianSyS >/dev/null; then _endian=big -elif $_strings $TMPO.o | grep LiTTleEnDian >/dev/null; then +elif $_strings $TMPO$HOSTEXEEXT | grep LiTTleEnDian >/dev/null; then _endian=little fi echo $_endian; -cc_check_clean tmp_endianness_check.cpp +cc_check_clean tmp_endianness_check.cpp tmp_endianness_check.dwo case $_endian in big) @@ -2728,10 +2783,10 @@ case $_host_os in ;; mingw*) append_var DEFINES "-DWIN32" - append_var DEFINES "-D__USE_MINGW_ANSI_STDIO=0" + # append_var DEFINES "-D__USE_MINGW_ANSI_STDIO=0" # Modern MinGW does not need it append_var LDFLAGS "-static-libgcc -static-libstdc++" append_var LIBS "-lmingw32 -lwinmm -lgdi32" - append_var OBJS "residualvmwinres.o" + append_var OBJS "dists/residualvm.o" add_line_to_config_mk 'WIN32 = 1' _port_mk="backends/platform/sdl/win32/win32.mk" ;; @@ -2810,22 +2865,17 @@ case $_host_os in add_line_to_config_h "#define PREFIX \"${prefix}\"" ;; psp) - if test -d "$PSPDEV/psp/lib"; then - append_var LDFLAGS "-L$PSPDEV/psp/lib" - fi - append_var LDFLAGS "-L$PSPSDK/lib" - append_var LDFLAGS "-specs=$_srcdir/backends/platform/psp/psp.spec" - _optimization_level=-O3 + _optimization_level=-O2 append_var CXXFLAGS "-I$PSPSDK/include" # FIXME: Why is the following in CXXFLAGS and not in DEFINES? Change or document this. append_var CXXFLAGS "-D_PSP_FW_VERSION=150" add_line_to_config_mk 'PSP = 1' ;; riscos) - append_var DEFINES "-DRISCOS" - add_line_to_config_mk 'RISCOS = 1' + define_in_config_if_yes yes 'RISCOS' append_var LDFLAGS "-L$GCCSDK_INSTALL_ENV/lib" - append_var CXXFLAGS "-I$GCCSDK_INSTALL_ENV/include" + append_var CXXFLAGS "-isystem $GCCSDK_INSTALL_ENV/include" + _pkgconfig=$GCCSDK_INSTALL_ENV/ro-pkg-config _sdlpath=$GCCSDK_INSTALL_ENV/bin _freetypepath=$GCCSDK_INSTALL_ENV/bin _libcurlpath=$GCCSDK_INSTALL_ENV/bin @@ -2844,6 +2894,23 @@ case $_host_os in # Needs -lbind -lsocket for the timidity MIDI driver append_var LIBS "-lnsl -lsocket" ;; + switch) + _pkgconfig="$DEVKITPRO/portlibs/switch/bin/aarch64-none-elf-pkg-config" + _libcurlpath="$DEVKITPRO/portlibs/switch/bin" + _sdlpath="$DEVKITPRO/portlibs/switch/bin" + append_var DEFINES "-DSWITCH -D__SWITCH__ -DNINTENDO_SWITCH" + append_var CXXFLAGS "-march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE -ftls-model=local-exec" + append_var CXXFLAGS "-ffunction-sections -fdata-sections" + append_var CXXFLAGS "-I$DEVKITPRO/libnx/include -I$DEVKITPRO/portlibs/switch/include" + append_var LDFLAGS "-L$DEVKITPRO/libnx/lib -L$DEVKITPRO/portlibs/switch/lib" + append_var LDFLAGS "-specs=$DEVKITPRO/libnx/switch.specs" + add_line_to_config_mk 'SWITCH = 1' + if test "$_debug_build" = yes; then + append_var DEFINES "-D__SWITCH_DEBUG__" + else + _optimization_level=-O3 + fi + ;; tizen) add_line_to_config_mk "TIZEN_ROOTSTRAP = $TIZEN_ROOTSTRAP" append_var LDFLAGS "--sysroot=${TIZEN_ROOTSTRAP}" @@ -2922,7 +2989,7 @@ if test -n "$_host"; then _vorbis=no _port_mk="backends/platform/3ds/3ds.mk" ;; - android | android-arm | android-v7a | android-arm-v7a | android-mips | android-x86 | ouya | android-arm64-v8a) + android | android-arm | android-v7a | android-arm-v7a | android-arm64-v8a | android-mips | android-x86 | ouya) # we link a .so as default append_var LDFLAGS "-shared" append_var LDFLAGS "-Wl,-Bsymbolic,--no-undefined" @@ -2946,7 +3013,7 @@ if test -n "$_host"; then ;; arm-*riscos) _opengl_mode=none - _build_hq_scalers=no + _vorbis=no ;; bfin*) ;; @@ -3079,7 +3146,7 @@ if test -n "$_host"; then gcw0) _sysroot=`$CXX --print-sysroot` _sdlpath=$_sysroot/usr/bin - append_var DEFINES "-DDINGUX -DGCW0 -DGUI_ONLY_FULLSCREEN" + append_var DEFINES "-DDINGUX -DGCW0" append_var DEFINES "-DREDUCE_MEMORY_USAGE" append_var CXXFLAGS "-mips32" _backend="dingux" @@ -3163,7 +3230,7 @@ if test -n "$_host"; then *mingw32*) _sdlconfig=$_host-sdl-config _windres=$_host-windres - _ar="$_host-ar cru" + _ar="$_host-ar cr" _ranlib=$_host-ranlib ;; mips-sgi*) @@ -3320,7 +3387,6 @@ if test -n "$_host"; then _port_mk="backends/platform/sdl/psp2/psp2.mk" ;; psp) - append_var DEFINES "-DGUI_ONLY_FULLSCREEN" _backend="psp" _build_scalers=no _mt32emu=no @@ -3335,6 +3401,16 @@ if test -n "$_host"; then _mt32emu=no _vkeybd=yes ;; + switch) + _backend="switch" + # Switch port crashes when switching between SDL2 and OpenGL + # graphics. But OpenGL works when it is enabled from the start. + # This might be related to a known crash on OpenGL de-init due + # to the OpenGL implementation on this platform. + _opengl_mode=gles2 + _vkeybd=yes + _port_mk="backends/platform/sdl/switch/switch.mk" + ;; tizen) _unix=yes _backend="tizen" @@ -3375,7 +3451,9 @@ if test -n "$_host"; then ;; wince) append_var LDFLAGS "-Wl,--stack,65536" - _tremolo=yes + if test "$_tremor" = auto; then + _tremolo=yes + fi _backend="wince" _detectlang=yes _mt32emu=no @@ -3419,6 +3497,7 @@ case $_backend in ;; dingux) append_var DEFINES "-DDINGUX" + _sdl=auto ;; ds) append_var INCLUDES '-I$(srcdir)/backends/platform/ds/arm9/source' @@ -3433,6 +3512,7 @@ case $_backend in if test "$_debug_build" = yes; then append_var DEFINES "-DGPH_DEBUG" fi + _sdl=auto ;; iphone) append_var LIBS "-lobjc -framework UIKit -framework CoreGraphics -framework OpenGLES" @@ -3454,9 +3534,11 @@ case $_backend in ;; linuxmoto) append_var DEFINES "-DLINUXMOTO" + _sdl=auto ;; maemo) append_var DEFINES "-DMAEMO" + _sdl=auto ;; n64) append_var INCLUDES '-I$(N64SDK)/include' @@ -3470,6 +3552,7 @@ case $_backend in append_var DEFINES "-DUSE_NULL_DRIVER" ;; openpandora) + _sdl=auto ;; ps2) append_var DEFINES "-D_EE" @@ -3505,9 +3588,8 @@ case $_backend in append_var LIBS "-lSceAudio_stub -lSceCtrl_stub -lScePower_stub" append_var LIBS "-lSceNet_stub -lSceNetCtl_stub -lSceAppMgr_stub -lScePgf_stub" append_var LIBS "-lSceTouch_stub -lSceHid_stub" - append_var DEFINES "-DSDL_BACKEND" - add_line_to_config_mk "SDL_BACKEND = 1" - add_line_to_config_mk "USE_SDL2 = 1" + _sdl=yes + _sdlversion=2.0.0 append_var MODULES "backends/platform/sdl" append_var INCLUDES "-I$VITASDK/arm-vita-eabi/include/SDL2" ;; @@ -3515,8 +3597,14 @@ case $_backend in append_var DEFINES "-DSAMSUNGTV" append_var LDFLAGS "-shared" append_var LDFLAGS "-fpic" + _sdl=auto ;; sdl) + _sdl=auto + ;; + switch) + _sdl=auto + append_var MODULES "backends/platform/sdl" ;; tizen) # dirent.h not available. NONSTANDARD_PORT==ensure portdefs.h is included @@ -3542,9 +3630,9 @@ case $_backend in # The PDL library acts as the WebOS device toolchain, and is required to control the virtual keyboard among other OS-level events. append_var LIBS "-lSDL -lpdl" append_var DEFINES "-DWEBOS" - append_var DEFINES "-DSDL_BACKEND" - add_line_to_config_mk "SDL_BACKEND = 1" append_var MODULES "backends/platform/sdl" + _sdl=yes + _sdlversion=1.2.0 ;; wii) append_var DEFINES "-D__WII__" @@ -3562,9 +3650,10 @@ case $_backend in append_var INCLUDES '-I$(srcdir)/backends/platform/wince' append_var INCLUDES '-I$(srcdir)/backends/platform/wince/CEgui' append_var INCLUDES '-I$(srcdir)/backends/platform/wince/CEkeys' + append_var INCLUDES '-I$(srcdir)/backends/platform/wince/missing' append_var LIBS "-static -lSDL" - append_var DEFINES "-DSDL_BACKEND" - add_line_to_config_mk "SDL_BACKEND = 1" + _sdl=yes + _sdlversion=1.2.0 ;; *) echo "support for $_backend backend not implemented in configure script yet" @@ -3573,59 +3662,129 @@ case $_backend in esac append_var MODULES "backends/platform/$_backend" +# +# Check for pkg-config +# +echocheck "pkg-config" +_pkg_config=no +command -v $_pkgconfig >/dev/null 2>&1 && _pkg_config=yes +echo "$_pkg_config" + +if test "$_pkg_config" = yes && test -n "$_host" && test -z "$PKG_CONFIG_LIBDIR"; then + echo "WARNING: When cross-compiling PKG_CONFIG_LIBDIR must be set to the location of the .pc files for the target" +fi + # # Setup SDL specifics for SDL based backends # -case $_backend in - androidsdl | dingux | gph | linuxmoto | maemo | openpandora | samsungtv | sdl) - find_sdlconfig - append_var INCLUDES "`$_sdlconfig --prefix="$_sdlpath" --cflags`" - if test "$_static_build" = yes ; then - append_var LIBS "`$_sdlconfig --prefix="$_sdlpath" --static-libs`" +if test "$_sdl" = auto ; then + find_sdlconfig + append_var SDL_CFLAGS "`$_sdlconfig --prefix="$_sdlpath" --cflags`" + if test "$_static_build" = yes ; then + append_var SDL_LIBS "`$_sdlconfig --prefix="$_sdlpath" --static-libs`" + else + append_var SDL_LIBS "`$_sdlconfig --prefix="$_sdlpath" --libs`" + fi + _sdlversion=`$_sdlconfig --version` + + echocheck "SDL" + _sdl=no + cat > $TMPC << EOF +#include "SDL.h" +int main(int argc, char *argv[]) { SDL_Init(0); return 0; } +EOF + cc_check $LIBS $SDL_LIBS $INCLUDES $SDL_CFLAGS && _sdl=yes + echo "$_sdl" + if test "$_sdl" = no ; then + exit 1 + fi +fi + +_sdlMajorVersionNumber=0 +if test "$_sdl" = yes ; then + append_var DEFINES "-DSDL_BACKEND" + add_line_to_config_mk "SDL_BACKEND = 1" + append_var INCLUDES "$SDL_CFLAGS" + append_var LIBS "$SDL_LIBS" + case $_sdlversion in + 2.0.*) + add_line_to_config_mk "USE_SDL2 = 1" + _sdlMajorVersionNumber=2 + ;; + *) + _sdlMajorVersionNumber=1 + ;; + esac +fi + +# +# Some platforms (eg. Android, iOS) may use an edited version +# of SDL-net or SDL2-net that does not require SDL or SDL2 respectively +# +if test "$_sdlnet" = auto ; then + # If SDL2 was detected, then test for SDL2_net exclusively + # If SDL was detected, then test for SDL_net exclusively + # If neither SDL nor SDL2 detected, then test for both (SDL2_net success takes priority) + set_var SDL2_NET_LIBS "$SDL_NET_LIBS" + set_var SDL2_NET_CFLAGS "$SDL_NET_CFLAGS" + set_var SDL1_NET_LIBS "$SDL_NET_LIBS" + set_var SDL1_NET_CFLAGS "$SDL_NET_CFLAGS" + + if test "$_sdl" = no || test "$_sdlMajorVersionNumber" = 2; then + if test "$_pkg_config" = "yes" && $_pkgconfig --exists SDL2_net; then + append_var SDL2_NET_LIBS "`$_pkgconfig --libs SDL2_net`" + append_var SDL2_NET_CFLAGS "`$_pkgconfig --cflags SDL2_net`" else - append_var LIBS "`$_sdlconfig --prefix="$_sdlpath" --libs`" + append_var SDL2_NET_LIBS "-lSDL2_net" fi - append_var DEFINES "-DSDL_BACKEND" - add_line_to_config_mk "SDL_BACKEND = 1" + fi - _sdlversion=`$_sdlconfig --version` - case $_sdlversion in - 2.0.*) - add_line_to_config_mk "USE_SDL2 = 1" - append_var SDL_NET_LIBS "-lSDL2_net" - ;; - *) - append_var SDL_NET_LIBS "-lSDL_net" - ;; - esac + if test "$_sdl" = no || test "$_sdlMajorVersionNumber" = 1; then + if test "$_pkg_config" = "yes" && $_pkgconfig --exists SDL_net; then + append_var SDL1_NET_LIBS "`$_pkgconfig --libs SDL_net`" + append_var SDL1_NET_CFLAGS "`$_pkgconfig --cflags SDL_net`" + else + append_var SDL1_NET_LIBS "-lSDL_net" + fi + fi - # Check for SDL_Net - echocheck "SDL_Net" - if test "$_sdlnet" = auto ; then - _sdlnet=no - cat > $TMPC << EOF + # Check for SDL_Net + echocheck "SDL_Net" + _sdlnet=no + cat > $TMPC << EOF #include "SDL_net.h" int main(int argc, char *argv[]) { SDLNet_Init(); return 0; } EOF - cc_check $SDL_NET_LIBS $LIBS $INCLUDES $SDL_NET_CFLAGS && _sdlnet=yes - fi - if test "$_sdlnet" = yes ; then - # Some platforms require SDL to be after SDL_Net, thus we prepend var - prepend_var LIBS "$SDL_NET_LIBS" - append_var INCLUDES "$SDL_NET_CFLAGS" - fi - define_in_config_if_yes "$_sdlnet" 'USE_SDL_NET' - echo "$_sdlnet" - ;; -esac + cc_check $SDL2_NET_LIBS $LIBS $INCLUDES $SDL2_NET_CFLAGS && _sdlnet=yes + if test "$_sdlnet" = yes ; then + set_var SDL_NET_LIBS "$SDL2_NET_LIBS" + set_var SDL_NET_CFLAGS "$SDL2_NET_CFLAGS" + else + cat > $TMPC << EOF +#include "SDL_net.h" +int main(int argc, char *argv[]) { SDLNet_Init(); return 0; } +EOF + cc_check $SDL1_NET_LIBS $LIBS $INCLUDES $SDL1_NET_CFLAGS && _sdlnet=yes + set_var SDL_NET_LIBS "$SDL1_NET_LIBS" + set_var SDL_NET_CFLAGS "$SDL1_NET_CFLAGS" + fi + + if test "$_sdlnet" = yes ; then + # Some platforms require SDL to be after SDL_Net, thus we prepend var + prepend_var LIBS "$SDL_NET_LIBS" + append_var INCLUDES "$SDL_NET_CFLAGS" + fi + define_in_config_if_yes "$_sdlnet" 'USE_SDL_NET' + echo "$_sdlnet" +fi # # Enable 16bit support only for backends which support it # case $_backend in - 3ds | android | androidsdl | dingux | dc | gph | iphone | ios7 | maemo | openpandora | psp | psp2 | samsungtv | sdl | tizen | webos | wii) + 3ds | android | androidsdl | dingux | dc | gph | iphone | ios7 | maemo | openpandora | psp | psp2 | samsungtv | sdl | switch | tizen | webos | wii) if test "$_16bit" = auto ; then _16bit=yes else @@ -3704,7 +3863,7 @@ case $_host_os in amigaos* | cygwin* | dreamcast | ds | gamecube | mingw* | n64 | ps2 | ps3 | psp2 | psp | riscos | wii | wince) _posix=no ;; - 3ds | android | androidsdl | beos* | bsd* | darwin* | freebsd* | gnu* | gph-linux | haiku* | hpux* | iphone | ios7 | irix*| k*bsd*-gnu* | linux* | maemo | mint* | netbsd* | openbsd* | solaris* | sunos* | uclinux* | webos) + 3ds | android | androidsdl | beos* | bsd* | darwin* | freebsd* | gnu* | gph-linux | haiku* | hpux* | iphone | ios7 | irix*| k*bsd*-gnu* | linux* | maemo | mint* | netbsd* | openbsd* | solaris* | sunos* | switch | uclinux* | webos) _posix=yes ;; os2-emx*) @@ -4008,18 +4167,6 @@ int main(void) { return 0; } EOF cc_check -lm && append_var LIBS "-lm" -# -# Check for pkg-config -# -echocheck "pkg-config" -_pkg_config=no -command -v pkg-config >/dev/null 2>&1 && _pkg_config=yes -echo "$_pkg_config" - -if test "$_pkg_config" = yes && test -n "$_host" && test -z "$PKG_CONFIG_LIBDIR"; then - echo "WARNING: When cross-compiling PKG_CONFIG_LIBDIR must be set to the location of the .pc files for the target" -fi - # # Check for Ogg # @@ -4207,6 +4354,12 @@ echo "$_jpeg" # Check for PNG # echocheck "PNG >= 1.2.8" +if test "$_pkg_config" = "yes" && $_pkgconfig --exists libpng; then + append_var PNG_LIBS "`$_pkgconfig --libs libpng`" + append_var PNG_CFLAGS "`$_pkgconfig --cflags libpng`" +else + append_var PNG_LIBS "-lpng -lz" +fi if test "$_png" = auto ; then _png=no cat > $TMPC << EOF @@ -4219,10 +4372,10 @@ int main(void) { return 0; } EOF - cc_check $PNG_CFLAGS $PNG_LIBS -lpng -lz && _png=yes + cc_check $PNG_CFLAGS $PNG_LIBS && _png=yes fi if test "$_png" = yes ; then - append_var LIBS "$PNG_LIBS -lpng -lz" + append_var LIBS "$PNG_LIBS" append_var INCLUDES "$PNG_CFLAGS" fi define_in_config_if_yes "$_png" 'USE_PNG' @@ -4434,10 +4587,11 @@ case $_host_os in if test "$_updates" = no; then _sparkle=no else - if test ! -z $_sparklepath ; then - SPARKLE_CFLAGS="-F$_sparklepath" - SPARKLE_LIBS="-F$_sparklepath" + if test -z $_sparklepath; then + _sparklepath=/Library/Frameworks fi + SPARKLE_CFLAGS="-F$_sparklepath" + SPARKLE_LIBS="-F$_sparklepath" if test "$_sparkle" = auto ; then _sparkle=no cat > $TMPC << EOF @@ -4496,13 +4650,21 @@ if test "$_libcurl" != "no"; then if test -z "$_libcurlconfig"; then _libcurl=no else - LIBCURL_LIBS=`$_libcurlconfig --libs` + if test -n "$_staticlibpath"; then + LIBCURL_LIBS=`$_libcurlconfig --static-libs` + else + LIBCURL_LIBS=`$_libcurlconfig --libs` + fi LIBCURL_CFLAGS=`$_libcurlconfig --cflags` case $_host_os in amigaos*) append_var LIBCURL_LIBS "-lpthread" ;; + # macOS does not allow static libs, overriding + darwin*) + LIBCURL_LIBS=`$_libcurlconfig --libs` + ;; psp2*) append_var LIBCURL_LIBS "-lssl -lcrypto" ;; @@ -4725,8 +4887,8 @@ if test "$_libunity" = auto ; then ;; *) # Unity has a lots of dependencies, update the libs and cflags var with them - LIBUNITY_LIBS="$LIBUNITY_LIBS `pkg-config --libs 'unity > 3.8.1' 2>> "$TMPLOG"`" - LIBUNITY_CFLAGS="$LIBUNITY_CFLAGS `pkg-config --cflags 'unity > 3.8.1' 2>> "$TMPLOG"`" + LIBUNITY_LIBS="$LIBUNITY_LIBS `$_pkgconfig --libs 'unity > 3.8.1' 2>> "$TMPLOG"`" + LIBUNITY_CFLAGS="$LIBUNITY_CFLAGS `$_pkgconfig --cflags 'unity > 3.8.1' 2>> "$TMPLOG"`" _libunity=no cat > $TMPC << EOF #include @@ -4741,11 +4903,11 @@ EOF fi if test "$_libunity" = yes ; then if test "$LIBUNITY_CFLAGS" = "" || test "$LIBUNITY_LIBS" = ""; then - LIBUNITY_LIBS="$LIBUNITY_LIBS `pkg-config --libs 'unity > 3.8.1' 2>> "$TMPLOG"`" - LIBUNITY_CFLAGS="$LIBUNITY_CFLAGS `pkg-config --cflags 'unity > 3.8.1' 2>> "$TMPLOG"`" + LIBUNITY_LIBS="$LIBUNITY_LIBS `$_pkgconfig --libs 'unity > 3.8.1' 2>> "$TMPLOG"`" + LIBUNITY_CFLAGS="$LIBUNITY_CFLAGS `$_pkgconfig --cflags 'unity > 3.8.1' 2>> "$TMPLOG"`" fi append_var LIBS "$LIBUNITY_LIBS" - append_var INCLUDES "$LIBUNITY_CFLAGS" + append_var CXXFLAGS "$LIBUNITY_CFLAGS" fi define_in_config_h_if_yes "$_libunity" 'USE_UNITY' fi @@ -4756,14 +4918,14 @@ echo "$_libunity" # find_freetype() { # Wrapper function which tries to find freetype - # either by callimg freetype-config or by using + # either by calling freetype-config or by using # pkg-config. # As of freetype-2.9.1 the freetype-config file # no longer gets installed by default. - if test "$_pkg_config" = "yes" && pkg-config --exists freetype2; then - FREETYPE2_LIBS=`pkg-config --libs freetype2` - FREETYPE2_CFLAGS=`pkg-config --cflags freetype2` - FREETYPE2_STATIC_LIBS=`pkg-config --static --libs freetype2` + if test "$_pkg_config" = "yes" && $_pkgconfig --exists freetype2; then + FREETYPE2_LIBS=`$_pkgconfig --libs freetype2` + FREETYPE2_CFLAGS=`$_pkgconfig --cflags freetype2` + FREETYPE2_STATIC_LIBS=`$_pkgconfig --static --libs freetype2` _freetype_found="true" else # Look for the freetype-config script @@ -4819,7 +4981,7 @@ EOF if test "$_freetype2" = "yes"; then append_var LIBS "$FREETYPE2_LIBS" - append_var INCLUDES "$FREETYPE2_CFLAGS" + append_var CXXFLAGS "$FREETYPE2_CFLAGS" fi fi @@ -5324,16 +5486,17 @@ echo "$_bink" # Check whether to build updates support # echo_n "Building updates support... " -define_in_config_if_yes $_updates 'USE_UPDATES' if test "$_updates" = yes; then if test "$_sparkle" = yes; then echo "Sparkle" else + _updates=no; echo "$_updates" fi else echo "$_updates" fi +define_in_config_if_yes $_updates 'USE_UPDATES' # # Check whether to activate engines (ResidualVM specific) @@ -5756,6 +5919,8 @@ vpath %.mm \$(srcdir) vpath %.asm \$(srcdir) vpath %.s \$(srcdir) vpath %.S \$(srcdir) +vpath %.rc \$(srcdir) +vpath %.md \$(srcdir) include \$(srcdir)/Makefile EOF diff --git a/devtools/create_project/cmake/CMakeLists.txt b/devtools/create_project/cmake/CMakeLists.txt index 2646b89d2df..5c546656cd9 100644 --- a/devtools/create_project/cmake/CMakeLists.txt +++ b/devtools/create_project/cmake/CMakeLists.txt @@ -20,4 +20,6 @@ set(SOURCE_FILES ) add_executable(create_project ${SOURCE_FILES}) - +if (WIN32) + target_link_libraries(create_project rpcrt4 advapi32) +endif () diff --git a/devtools/create_project/msbuild.cpp b/devtools/create_project/msbuild.cpp index bcc195b8434..7cf5d7e788a 100644 --- a/devtools/create_project/msbuild.cpp +++ b/devtools/create_project/msbuild.cpp @@ -364,6 +364,7 @@ void MSBuildProvider::outputGlobalPropFile(const BuildSetup &setup, std::ofstrea "\t\t\tfalse\n" "\t\t\tDefault\n" "\t\t\ttrue\n" + "\t\t\ttrue\n" "\t\t\n" "\t\t\n" "\t\t\t%(IgnoreSpecificDefaultLibraries)\n" @@ -398,6 +399,7 @@ void MSBuildProvider::createBuildProp(const BuildSetup &setup, bool isRelease, b "\t\n" "\t\t<_PropertySheetDisplayName>" << setup.projectDescription << "_" << configuration << outputBitness << "\n" "\t\t" << (isRelease ? "false" : "true") << "\n" + "\t\tfalse\n" "\t\n" "\t\n" "\t\t\n"; diff --git a/devtools/create_project/scripts/revision.vbs b/devtools/create_project/scripts/revision.vbs index e6fef57030e..7f0655dae18 100644 --- a/devtools/create_project/scripts/revision.vbs +++ b/devtools/create_project/scripts/revision.vbs @@ -128,8 +128,9 @@ End Sub ' Output revision header file Sub OutputRevisionHeader(str) - FSO.CopyFile rootFolder & "\\base\\internal_revision.h.in", targetFolder & "\\internal_revision.h" - FindReplaceInFile targetFolder & "\\internal_revision.h", "@REVISION@", str + FSO.CopyFile rootFolder & "\\base\\internal_revision.h.in", targetFolder & "\\internal_revision.h.tmp" + FindReplaceInFile targetFolder & "\\internal_revision.h.tmp", "@REVISION@", str + CompareFileAndReplace targetFolder & "\\internal_revision.h.tmp", targetFolder & "\\internal_revision.h" End Sub Function DetermineTortoiseSVNVersion() @@ -482,3 +483,23 @@ Sub FindReplaceInFile(filename, to_find, replacement) file.Write data file.Close End Sub + +Sub CompareFileAndReplace(src_filename, dst_filename) + Dim file, src_data, dst_data + Set file = FSO.OpenTextFile(src_filename, 1, 0, 0) + src_data = file.ReadAll + file.Close + If Not FSO.FileExists(dst_filename) Then + FSO.CopyFile src_filename, dst_filename, True + Else + Set file = FSO.OpenTextFile(dst_filename, 1, 0, 0) + dst_data = file.ReadAll + file.Close + If StrComp(src_data, dst_data, vbBinaryCompare) <> 0 Then + ' Files are different, overwrite the destination + FSO.CopyFile src_filename, dst_filename, True + End If + End If + ' Remove temporary source + FSO.DeleteFile src_filename +End Sub diff --git a/devtools/create_project/visualstudio.cpp b/devtools/create_project/visualstudio.cpp index 8ceca552658..2515ef31d9b 100644 --- a/devtools/create_project/visualstudio.cpp +++ b/devtools/create_project/visualstudio.cpp @@ -289,6 +289,7 @@ void VisualStudioProvider::createBuildProp(const BuildSetup &setup, bool isRelea "\t $(srcdir)/../../docs/trunk/docbook/credits.xml -# Rule to explicitly rebuild the wwwroot archive -wwwroot: - $(srcdir)/devtools/make-www-archive.py $(srcdir)/dists/networking/ - - # # Rules which automatically and implicitly rebuild the credits and # MD5 tables when needed. diff --git a/dists/networking/wwwroot/style.css b/dists/networking/wwwroot/style.css index 2d9c91942a8..dca9d872c95 100644 --- a/dists/networking/wwwroot/style.css +++ b/dists/networking/wwwroot/style.css @@ -1,6 +1,5 @@ html { - background: rgb(212, 117, 11); - background: linear-gradient(to bottom, rgb(212, 117, 11) 0%, rgb(212, 117, 11) 36%, rgb(239, 196, 24) 100%); + background: rgb(204, 102, 0); min-height: 100vh; } @@ -16,7 +15,7 @@ html { .content { padding: 8pt; - background: rgb(215, 236, 220); + background: rgb(251, 241, 206); font-family: Tahoma; font-size: 16pt; } diff --git a/dists/residualvm.rc b/dists/residualvm.rc index 00135c7a3e4..4dff81f1ecd 100644 --- a/dists/residualvm.rc +++ b/dists/residualvm.rc @@ -11,8 +11,9 @@ #define IDI_ICON 1001 #define IDI_COUNT 1002 -IDI_ICON ICON DISCARDABLE "icons/residualvm.ico" -IDI_COUNT ICON DISCARDABLE "icons/count.ico" +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "dists/win32/residualvm.exe.manifest" +IDI_ICON ICON "icons/residualvm.ico" +IDI_COUNT ICON "icons/count.ico" residualvm-grim-patch.lab FILE "dists/engine-data/residualvm-grim-patch.lab" residualvm-emi-patch.m4b FILE "dists/engine-data/residualvm-emi-patch.m4b" diff --git a/dists/win32/residualvm.exe.manifest b/dists/win32/residualvm.exe.manifest new file mode 100644 index 00000000000..76d99c7c93b --- /dev/null +++ b/dists/win32/residualvm.exe.manifest @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/engines/advancedDetector.cpp b/engines/advancedDetector.cpp index 10ddb0d0738..4cc05aef32d 100644 --- a/engines/advancedDetector.cpp +++ b/engines/advancedDetector.cpp @@ -82,8 +82,6 @@ static Common::String generatePreferredTarget(const ADGameDescription *desc) { DetectedGame AdvancedMetaEngine::toDetectedGame(const ADDetectedGame &adGame) const { const ADGameDescription *desc = adGame.desc; - const char *gameId = _singleId ? _singleId : desc->gameId; - const char *title; const char *extra; if (desc->flags & ADGF_USEEXTRAASTITLE) { @@ -99,7 +97,7 @@ DetectedGame AdvancedMetaEngine::toDetectedGame(const ADDetectedGame &adGame) co extra = desc->extra; } - DetectedGame game(gameId, title, desc->language, desc->platform, extra); + DetectedGame game(getEngineId(), desc->gameId, title, desc->language, desc->platform, extra); game.hasUnknownFiles = adGame.hasUnknownFiles; game.matchedFiles = adGame.matchedFiles; game.preferredTarget = generatePreferredTarget(desc); @@ -264,7 +262,7 @@ Common::Error AdvancedMetaEngine::createInstance(OSystem *syst, Engine **engine) ADDetectedGame agdDesc; for (uint i = 0; i < matches.size(); i++) { - if ((_singleId || matches[i].desc->gameId == gameid) && !matches[i].hasUnknownFiles) { + if (matches[i].desc->gameId == gameid && !matches[i].hasUnknownFiles) { agdDesc = matches[i]; break; } @@ -277,7 +275,7 @@ Common::Error AdvancedMetaEngine::createInstance(OSystem *syst, Engine **engine) if (agdDesc.desc) { // Seems we found a fallback match. But first perform a basic // sanity check: the gameid must match. - if (!_singleId && agdDesc.desc->gameId != gameid) + if (agdDesc.desc->gameId != gameid) agdDesc = ADDetectedGame(); } } @@ -556,21 +554,6 @@ ADDetectedGame AdvancedMetaEngine::detectGameFilebased(const FileMap &allFiles, } PlainGameList AdvancedMetaEngine::getSupportedGames() const { - if (_singleId != NULL) { - PlainGameList gl; - - const PlainGameDescriptor *g = _gameIds; - while (g->gameId) { - if (0 == scumm_stricmp(_singleId, g->gameId)) { - gl.push_back(*g); - - return gl; - } - g++; - } - error("Engine %s doesn't have its singleid specified in ids list", _singleId); - } - return PlainGameList(_gameIds); } @@ -589,7 +572,6 @@ AdvancedMetaEngine::AdvancedMetaEngine(const void *descs, uint descItemSize, con _extraGuiOptions(extraGuiOptions) { _md5Bytes = 5000; - _singleId = NULL; _flags = 0; _guiOptions = GUIO_NONE; _maxScanDepth = 1; diff --git a/engines/advancedDetector.h b/engines/advancedDetector.h index 326cb79c492..088dfeae415 100644 --- a/engines/advancedDetector.h +++ b/engines/advancedDetector.h @@ -205,19 +205,6 @@ protected: */ uint _md5Bytes; - /** - * Name of single gameid (optional). - * - * Used to override gameid. - * This is a recommended setting to prevent global gameid pollution. - * With this option set, the gameid effectively turns into engineid. - * - * FIXME: This field actually removes a feature (gameid) in order to - * address a more generic problem. We should find a better way to - * disambiguate gameids. - */ - const char *_singleId; - /** * A bitmask of flags which can be used to configure the behavior * of the AdvancedDetector. Refer to ADFlags for a list of flags diff --git a/engines/engine.cpp b/engines/engine.cpp index a17aa7ff0fd..b62d67373bd 100644 --- a/engines/engine.cpp +++ b/engines/engine.cpp @@ -266,7 +266,6 @@ void splashScreen() { uint time0 = g_system->getMillis(); Common::Event event; while (time0 + 600 > g_system->getMillis()) { - (void)g_system->getEventManager()->pollEvent(event); g_system->delayMillis(10); } g_system->hideOverlay(); @@ -305,7 +304,7 @@ void initGraphics(int width, int height, const Graphics::PixelFormat *format) { // Error out on size switch failure if (gfxError & OSystem::kTransactionSizeChangeFailed) { Common::String message; - message = Common::String::format("Could not switch to resolution: '%dx%d'.", width, height); + message = Common::String::format(_("Could not switch to resolution '%dx%d'."), width, height); GUIErrorMessage(message); error("%s", message.c_str()); @@ -322,18 +321,16 @@ void initGraphics(int width, int height, const Graphics::PixelFormat *format) { #endif if (gfxError & OSystem::kTransactionModeSwitchFailed) { - Common::String message = _("Could not switch to video mode: '"); - message += ConfMan.get("gfx_mode"); - message += "'."; + Common::String message; + message = Common::String::format(_("Could not switch to video mode '%s'."), ConfMan.get("gfx_mode").c_str()); GUI::MessageDialog dialog(message); dialog.runModal(); } if (gfxError & OSystem::kTransactionStretchModeSwitchFailed) { - Common::String message = _("Could not switch to stretch mode: '"); - message += ConfMan.get("stretch_mode"); - message += "'."; + Common::String message; + message = Common::String::format(_("Could not switch to stretch mode '%s'."), ConfMan.get("stretch_mode").c_str()); GUI::MessageDialog dialog(message); dialog.runModal(); @@ -523,7 +520,7 @@ void Engine::openMainMenuDialog() { // Load savegame after main menu execution // (not from inside the menu loop to avoid - // mouse cursor glitches and simliar bugs, + // mouse cursor glitches and similar bugs, // e.g. #2822778). if (_saveSlotToLoad >= 0) { Common::Error status = loadGameState(_saveSlotToLoad); @@ -665,12 +662,7 @@ bool Engine::shouldQuit() { /* EnginePlugin *Engine::getMetaEnginePlugin() const { - - const EnginePlugin *plugin = 0; - Common::String gameid = ConfMan.get("gameid"); - gameid.toLowercase(); - EngineMan.findGame(gameid, &plugin); - return plugin; + return EngineMan.findPlugin(ConfMan.get("engineid")); } */ diff --git a/engines/game.cpp b/engines/game.cpp index 4f2664de272..171f424323e 100644 --- a/engines/game.cpp +++ b/engines/game.cpp @@ -49,8 +49,21 @@ PlainGameDescriptor PlainGameDescriptor::of(const char *gameId, const char *desc return pgd; } +QualifiedGameDescriptor::QualifiedGameDescriptor() : + PlainGameDescriptor() { + engineId = nullptr; + gameId = nullptr; + description = nullptr; +} + +QualifiedGameDescriptor::QualifiedGameDescriptor(const char *engine, const PlainGameDescriptor &pgd) : + PlainGameDescriptor() { + engineId = engine; + gameId = pgd.gameId; + description = pgd.description; +} + DetectedGame::DetectedGame() : - engineName(nullptr), hasUnknownFiles(false), canBeAdded(true), language(Common::UNK_LANG), @@ -58,8 +71,8 @@ DetectedGame::DetectedGame() : gameSupportLevel(kStableGame) { } -DetectedGame::DetectedGame(const PlainGameDescriptor &pgd) : - engineName(nullptr), +DetectedGame::DetectedGame(const Common::String &engine, const PlainGameDescriptor &pgd) : + engineId(engine), hasUnknownFiles(false), canBeAdded(true), language(Common::UNK_LANG), @@ -71,8 +84,8 @@ DetectedGame::DetectedGame(const PlainGameDescriptor &pgd) : description = pgd.description; } -DetectedGame::DetectedGame(const Common::String &id, const Common::String &d, Common::Language l, Common::Platform p, const Common::String &ex) : - engineName(nullptr), +DetectedGame::DetectedGame(const Common::String &engine, const Common::String &id, const Common::String &d, Common::Language l, Common::Platform p, const Common::String &ex) : + engineId(engine), hasUnknownFiles(false), canBeAdded(true), gameSupportLevel(kStableGame) { @@ -178,20 +191,20 @@ Common::String generateUnknownGameReport(const DetectedGames &detectedGames, boo FilePropertiesMap matchedFiles; - const char *currentEngineName = nullptr; + Common::String currentEngineId; for (uint i = 0; i < detectedGames.size(); i++) { const DetectedGame &game = detectedGames[i]; if (!game.hasUnknownFiles) continue; - if (!currentEngineName || strcmp(currentEngineName, game.engineName) != 0) { - currentEngineName = game.engineName; + if (currentEngineId.empty() || currentEngineId != game.engineId) { + currentEngineId = game.engineId; // If the engine is not the same as for the previous entry, print an engine line header report += "\n"; report += Common::String::format( translate ? _(reportEngineHeader) : reportEngineHeader, - game.engineName + game.engineId.c_str() ); report += " "; diff --git a/engines/game.h b/engines/game.h index 8a678cfd2ce..e378976cb15 100644 --- a/engines/game.h +++ b/engines/game.h @@ -63,6 +63,18 @@ public: } }; +/** + * The description of a game supported by an engine + */ +struct QualifiedGameDescriptor : public PlainGameDescriptor { + const char *engineId; + + QualifiedGameDescriptor(); + QualifiedGameDescriptor(const char *engine, const PlainGameDescriptor &pgd); +}; + +typedef Common::Array QualifiedGameList; + /** * Ths is an enum to describe how done a game is. This also indicates what level of support is expected. */ @@ -98,8 +110,8 @@ typedef Common::HashMap { public: - PlainGameDescriptor findGameInLoadedPlugins(const Common::String &gameName, const Plugin **plugin = NULL) const; - PlainGameDescriptor findGame(const Common::String &gameName, const Plugin **plugin = NULL) const; + /** + * Given a list of FSNodes in a given directory, detect a set of games contained within + * + * Returns an empty list if none are found. + */ DetectionResults detectGames(const Common::FSList &fslist) const; + + /** Find a plugin by its engine ID */ + const Plugin *findPlugin(const Common::String &engineId) const; + + /** Get the list of all engine plugins */ const PluginList &getPlugins() const; + /** Find a target */ + QualifiedGameDescriptor findTarget(const Common::String &target, const Plugin **plugin = NULL) const; + + /** + * List games matching the specified criteria + * + * If the engine id is not specified, this scans all the plugins, + * loading them from disk if necessary. This is a slow operation on + * some platforms and should not be used for the happy path. + */ + QualifiedGameList findGamesMatching(const Common::String &engineId, const Common::String &gameId) const; + /** * Create a target from the supplied game descriptor * * Returns the created target name. */ Common::String createTargetForGame(const DetectedGame &game); + + /** Upgrade a target to the current configuration format */ + void upgradeTargetIfNecessary(const Common::String &target) const; + +private: + /** Find a game across all loaded plugins */ + QualifiedGameList findGameInLoadedPlugins(const Common::String &gameId) const; + + /** Find a loaded plugin with the given engine ID */ + const Plugin *findLoadedPlugin(const Common::String &engineId) const; + + /** Use heuristics to complete a target lacking an engine ID */ + void upgradeTargetForEngineId(const Common::String &target) const; }; /** Convenience shortcut for accessing the engine manager. */ diff --git a/engines/myst3/detection.cpp b/engines/myst3/detection.cpp index 0f6a3ed68b6..693b97dcc42 100644 --- a/engines/myst3/detection.cpp +++ b/engines/myst3/detection.cpp @@ -203,21 +203,24 @@ static const ADExtraGuiOptionsMap optionsList[] = { class Myst3MetaEngine : public AdvancedMetaEngine { public: Myst3MetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(Myst3GameDescription), myst3Games, optionsList) { - _singleId = "myst3"; _guiOptions = GUIO5(GUIO_NOMIDI, GUIO_NOSFX, GUIO_NOSPEECH, GUIO_NOSUBTITLES, GAMEOPTION_WIDESCREEN_MOD); _maxScanDepth = 3; _directoryGlobs = directoryGlobs; } - virtual const char *getName() const { - return "Myst III Engine"; + const char *getName() const override { + return "Myst III"; } - virtual const char *getOriginalCopyright() const { + const char *getEngineId() const override { + return "myst3"; + } + + const char *getOriginalCopyright() const override { return "Myst III Exile (C) Presto Studios"; } - virtual bool hasFeature(MetaEngineFeature f) const { + bool hasFeature(MetaEngineFeature f) const override { return (f == kSupportsListSaves) || (f == kSupportsDeleteSave) || @@ -228,7 +231,7 @@ public: (f == kSavesSupportPlayTime); } - virtual SaveStateList listSaves(const char *target) const { + SaveStateList listSaves(const char *target) const override { Common::Platform platform = Common::parsePlatform(ConfMan.get("platform", target)); Common::StringArray filenames = Saves::list(g_system->getSavefileManager(), platform); @@ -252,7 +255,7 @@ public: return description; } - virtual SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const { + SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const override { SaveStateDescriptor saveInfos = getSaveDescription(target, slot); if (saveInfos.getDescription().empty()) { @@ -291,16 +294,16 @@ public: return saveInfos; } - void removeSaveState(const char *target, int slot) const { + void removeSaveState(const char *target, int slot) const override { SaveStateDescriptor saveInfos = getSaveDescription(target, slot); g_system->getSavefileManager()->removeSavefile(saveInfos.getDescription()); } - virtual int getMaximumSaveSlot() const { + int getMaximumSaveSlot() const override { return 999; } - virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; + bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override; }; bool Myst3MetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { diff --git a/engines/obsolete.cpp b/engines/obsolete.cpp index ea96cff42ee..40fe8323f19 100644 --- a/engines/obsolete.cpp +++ b/engines/obsolete.cpp @@ -58,8 +58,7 @@ void upgradeTargetIfNecessary(const ObsoleteGameID *obsoleteList) { PlainGameDescriptor findGameID( const char *gameid, const PlainGameDescriptor *gameids, - const ObsoleteGameID *obsoleteList - ) { + const ObsoleteGameID *obsoleteList) { // First search the list of supported gameids for a match. const PlainGameDescriptor *g = findPlainGameDescriptor(gameid, gameids); if (g) diff --git a/engines/obsolete.h b/engines/obsolete.h index 7c7249e52b7..c1bbad6a8cf 100644 --- a/engines/obsolete.h +++ b/engines/obsolete.h @@ -69,8 +69,7 @@ void upgradeTargetIfNecessary(const ObsoleteGameID *obsoleteList); PlainGameDescriptor findGameID( const char *gameid, const PlainGameDescriptor *gameids, - const ObsoleteGameID *obsoleteList = 0 - ); + const ObsoleteGameID *obsoleteList = 0); } // End of namespace Engines diff --git a/engines/stark/detection.cpp b/engines/stark/detection.cpp index a9c86070e96..96d5ef0d907 100644 --- a/engines/stark/detection.cpp +++ b/engines/stark/detection.cpp @@ -32,9 +32,8 @@ namespace Stark { static const PlainGameDescriptor starkGames[] = { - {"stark", "Stark Game"}, - {"tlj", "The Longest Journey"}, - {nullptr, nullptr} + { "tlj", "The Longest Journey" }, + { nullptr, nullptr } }; static const ADGameDescription gameDescriptions[] = { @@ -374,12 +373,15 @@ static const ADExtraGuiOptionsMap optionsList[] = { class StarkMetaEngine : public AdvancedMetaEngine { public: StarkMetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(ADGameDescription), starkGames, optionsList) { - _singleId = "stark"; _guiOptions = GUIO4(GUIO_NOMIDI, GAMEOPTION_ASSETS_MOD, GAMEOPTION_LINEAR_FILTERING, GAMEOPTION_FONT_ANTIALIASING); } const char *getName() const override { - return "Stark Engine"; + return "Stark"; + } + + const char *getEngineId() const override { + return "stark"; } const char *getOriginalCopyright() const override { diff --git a/graphics/VectorRenderer.cpp b/graphics/VectorRenderer.cpp index e92a09f8c91..bcab4bf5a25 100644 --- a/graphics/VectorRenderer.cpp +++ b/graphics/VectorRenderer.cpp @@ -32,34 +32,7 @@ namespace Graphics { /******************************************************************** * DRAWSTEP handling functions ********************************************************************/ -void VectorRenderer::drawStep(const Common::Rect &area, const DrawStep &step, uint32 extra) { - - if (step.bgColor.set) - setBgColor(step.bgColor.r, step.bgColor.g, step.bgColor.b); - - if (step.fgColor.set) - setFgColor(step.fgColor.r, step.fgColor.g, step.fgColor.b); - - if (step.bevelColor.set) - setBevelColor(step.bevelColor.r, step.bevelColor.g, step.bevelColor.b); - - if (step.gradColor1.set && step.gradColor2.set) - setGradientColors(step.gradColor1.r, step.gradColor1.g, step.gradColor1.b, - step.gradColor2.r, step.gradColor2.g, step.gradColor2.b); - - setShadowOffset(_disableShadows ? 0 : step.shadow); - setBevel(step.bevel); - setGradientFactor(step.factor); - setStrokeWidth(step.stroke); - setFillMode((FillMode)step.fillMode); - - _dynamicData = extra; - - Common::Rect noClip = Common::Rect(0, 0, 0, 0); - (this->*(step.drawingCall))(area, step, noClip); -} - -void VectorRenderer::drawStepClip(const Common::Rect &area, const Common::Rect &clip, const DrawStep &step, uint32 extra) { +void VectorRenderer::drawStep(const Common::Rect &area, const Common::Rect &clip, const DrawStep &step, uint32 extra) { if (step.bgColor.set) setBgColor(step.bgColor.r, step.bgColor.g, step.bgColor.b); @@ -79,10 +52,46 @@ void VectorRenderer::drawStepClip(const Common::Rect &area, const Common::Rect & setGradientFactor(step.factor); setStrokeWidth(step.stroke); setFillMode((FillMode)step.fillMode); + setClippingRect(applyStepClippingRect(area, clip, step)); _dynamicData = extra; - (this->*(step.drawingCall))(area, step, clip); + (this->*(step.drawingCall))(area, step); +} + +Common::Rect VectorRenderer::applyStepClippingRect(const Common::Rect &area, const Common::Rect &clip, const DrawStep &step) { + if (step.clip == Common::Rect()) { + return clip; + } + + Common::Rect finalClip = clip; + if (step.clip.left > 0) { + finalClip.left = area.left + step.clip.left; + } else if (step.clip.left < 0) { + finalClip.left = area.right + step.clip.left; + } + + if (step.clip.top > 0) { + finalClip.top = area.top + step.clip.top; + } else if (step.clip.top < 0) { + finalClip.top = area.bottom + step.clip.top; + } + + if (step.clip.right > 0) { + finalClip.right = area.left + step.clip.right; + } else if (step.clip.right < 0) { + finalClip.right = area.right + step.clip.right; + } + + if (step.clip.bottom > 0) { + finalClip.bottom = area.top + step.clip.bottom; + } else if (step.clip.bottom < 0) { + finalClip.bottom = area.bottom + step.clip.bottom; + } + + finalClip.clip(clip); + + return finalClip; } int VectorRenderer::stepGetRadius(const DrawStep &step, const Common::Rect &area) { @@ -128,7 +137,7 @@ void VectorRenderer::stepGetPositions(const DrawStep &step, const Common::Rect & } } else { in_x = area.left + step.padding.left; - in_w = area.width(); + in_w = area.width() - step.padding.left - step.padding.right; } if (!step.autoHeight) { @@ -159,7 +168,7 @@ void VectorRenderer::stepGetPositions(const DrawStep &step, const Common::Rect & } } else { in_y = area.top + step.padding.top; - in_h = area.height(); + in_h = area.height() - step.padding.top - step.padding.bottom; } if (step.scale != (1 << 16) && step.scale != 0) { diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h index 2abe0e0759b..7fa9b28aca2 100644 --- a/graphics/VectorRenderer.h +++ b/graphics/VectorRenderer.h @@ -39,7 +39,7 @@ class VectorRenderer; struct DrawStep; -typedef void (VectorRenderer::*DrawingFunctionCallback)(const Common::Rect &, const Graphics::DrawStep &, const Common::Rect &); +typedef void (VectorRenderer::*DrawingFunctionCallback)(const Common::Rect &, const Graphics::DrawStep &); struct DrawStep { @@ -58,6 +58,7 @@ struct DrawStep { negative values mean counting from the opposite direction */ Common::Rect padding; + Common::Rect clip; /**< Clipping rect restriction */ enum VectorAlignment { kVectorAlignManual, @@ -146,7 +147,6 @@ public: * @param y2 Vertical (Y) coordinate for the line end */ virtual void drawLine(int x1, int y1, int x2, int y2) = 0; - virtual void drawLineClip(int x1, int y1, int x2, int y2, Common::Rect clipping) = 0; /** * Draws a circle centered at (x,y) with radius r. @@ -156,7 +156,6 @@ public: * @param r Radius of the circle. */ virtual void drawCircle(int x, int y, int r) = 0; - virtual void drawCircleClip(int x, int y, int r, Common::Rect clipping) = 0; /** * Draws a square starting at (x,y) with the given width and height. @@ -167,7 +166,6 @@ public: * @param h Height of the square */ virtual void drawSquare(int x, int y, int w, int h) = 0; - virtual void drawSquareClip(int x, int y, int w, int h, Common::Rect clipping) = 0; /** * Draws a rounded square starting at (x,y) with the given width and height. @@ -180,7 +178,6 @@ public: * @param r Radius of the corners. */ virtual void drawRoundedSquare(int x, int y, int r, int w, int h) = 0; - virtual void drawRoundedSquareClip(int x, int y, int r, int w, int h, Common::Rect clipping) = 0; /** * Draws a triangle starting at (x,y) with the given base and height. @@ -194,7 +191,6 @@ public: * @param orient Orientation of the triangle. */ virtual void drawTriangle(int x, int y, int base, int height, TriangleOrientation orient) = 0; - virtual void drawTriangleClip(int x, int y, int base, int height, TriangleOrientation orient, Common::Rect clipping) = 0; /** * Draws a beveled square like the ones in the Classic GUI themes. @@ -207,8 +203,7 @@ public: * @param h Height of the square * @param bevel Amount of bevel. Must be positive. */ - virtual void drawBeveledSquare(int x, int y, int w, int h, int bevel) = 0; - virtual void drawBeveledSquareClip(int x, int y, int w, int h, int bevel, Common::Rect clipping) = 0; + virtual void drawBeveledSquare(int x, int y, int w, int h) = 0; /** * Draws a tab-like shape, specially thought for the Tab widget. @@ -222,8 +217,6 @@ public: * @param r Radius of the corners of the tab (0 for squared tabs). */ virtual void drawTab(int x, int y, int r, int w, int h) = 0; - virtual void drawTabClip(int x, int y, int r, int w, int h, Common::Rect clipping) = 0; - /** * Simple helper function to draw a cross. @@ -233,11 +226,6 @@ public: drawLine(x + w, y, x, y + h); } - virtual void drawCrossClip(int x, int y, int w, int h, Common::Rect clipping) { - drawLineClip(x, y, x + w, y + w, clipping); - drawLineClip(x + w, y, x, y + h, clipping); - } - /** * Set the active foreground painting color for the renderer. * All the foreground drawing from then on will be done with that color, unless @@ -301,7 +289,6 @@ public: * Defaults to using the active Foreground color for filling. */ virtual void fillSurface() = 0; - virtual void fillSurfaceClip(Common::Rect clipping) = 0; /** * Clears the active surface. @@ -364,6 +351,16 @@ public: _gradientFactor = factor; } + /** + * Sets the clipping rectangle to be used by draw calls. + * + * Draw calls are restricted to pixels that are inside of the clipping + * rectangle. Pixels outside the clipping rectangle are not modified. + * To disable the clipping rectangle, call this method with a rectangle + * the same size as the target surface. + */ + virtual void setClippingRect(const Common::Rect &clippingArea) = 0; + /** * Translates the position data inside a DrawStep into actual * screen drawing positions. @@ -376,77 +373,82 @@ public: */ int stepGetRadius(const DrawStep &step, const Common::Rect &area); + /** + * Restrict a draw call clipping rect with a step specific clipping rect + */ + Common::Rect applyStepClippingRect(const Common::Rect &area, const Common::Rect &clip, const DrawStep &step); + /** * DrawStep callback functions for each drawing feature */ - void drawCallback_CIRCLE(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { + void drawCallback_CIRCLE(const Common::Rect &area, const DrawStep &step) { uint16 x, y, w, h, radius; radius = stepGetRadius(step, area); stepGetPositions(step, area, x, y, w, h); - drawCircleClip(x + radius, y + radius, radius, clip); + drawCircle(x + radius, y + radius, radius); } - void drawCallback_SQUARE(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { + void drawCallback_SQUARE(const Common::Rect &area, const DrawStep &step) { uint16 x, y, w, h; stepGetPositions(step, area, x, y, w, h); - drawSquareClip(x, y, w, h, clip); + drawSquare(x, y, w, h); } - void drawCallback_LINE(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { + void drawCallback_LINE(const Common::Rect &area, const DrawStep &step) { uint16 x, y, w, h; stepGetPositions(step, area, x, y, w, h); - drawLineClip(x, y, x + w, y + w, clip); + drawLine(x, y, x + w, y + h); } - void drawCallback_ROUNDSQ(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { + void drawCallback_ROUNDSQ(const Common::Rect &area, const DrawStep &step) { uint16 x, y, w, h; stepGetPositions(step, area, x, y, w, h); - drawRoundedSquareClip(x, y, stepGetRadius(step, area), w, h, clip); + drawRoundedSquare(x, y, stepGetRadius(step, area), w, h); } - void drawCallback_FILLSURFACE(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { - fillSurfaceClip(clip); + void drawCallback_FILLSURFACE(const Common::Rect &area, const DrawStep &step) { + fillSurface(); } - void drawCallback_TRIANGLE(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { + void drawCallback_TRIANGLE(const Common::Rect &area, const DrawStep &step) { uint16 x, y, w, h; stepGetPositions(step, area, x, y, w, h); - drawTriangleClip(x, y, w, h, (TriangleOrientation)step.extraData, clip); + drawTriangle(x, y, w, h, (TriangleOrientation)step.extraData); } - void drawCallback_BEVELSQ(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { + void drawCallback_BEVELSQ(const Common::Rect &area, const DrawStep &step) { uint16 x, y, w, h; stepGetPositions(step, area, x, y, w, h); - drawBeveledSquareClip(x, y, w, h, _bevel, clip); + drawBeveledSquare(x, y, w, h); } - void drawCallback_TAB(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { + void drawCallback_TAB(const Common::Rect &area, const DrawStep &step) { uint16 x, y, w, h; stepGetPositions(step, area, x, y, w, h); - drawTabClip(x, y, stepGetRadius(step, area), w, h, clip); + drawTab(x, y, stepGetRadius(step, area), w, h); } - void drawCallback_BITMAP(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { + void drawCallback_BITMAP(const Common::Rect &area, const DrawStep &step) { uint16 x, y, w, h; stepGetPositions(step, area, x, y, w, h); - blitKeyBitmapClip(step.blitSrc, Common::Rect(x, y, x + w, y + h), clip); + blitKeyBitmap(step.blitSrc, Common::Point(x, y)); } - void drawCallback_ALPHABITMAP(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { + void drawCallback_ALPHABITMAP(const Common::Rect &area, const DrawStep &step) { uint16 x, y, w, h; stepGetPositions(step, area, x, y, w, h); blitAlphaBitmap(step.blitAlphaSrc, Common::Rect(x, y, x + w, y + h), step.autoscale, step.xAlign, step.yAlign); // TODO } - void drawCallback_CROSS(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { + void drawCallback_CROSS(const Common::Rect &area, const DrawStep &step) { uint16 x, y, w, h; stepGetPositions(step, area, x, y, w, h); - drawCrossClip(x, y, w, h, clip); + drawCross(x, y, w, h); } - void drawCallback_VOID(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) {} + void drawCallback_VOID(const Common::Rect &area, const DrawStep &step) {} /** * Draws the specified draw step on the screen. @@ -455,8 +457,7 @@ public: * @param area Zone to paint on * @param step Pointer to a DrawStep struct. */ - virtual void drawStep(const Common::Rect &area, const DrawStep &step, uint32 extra = 0); - virtual void drawStepClip(const Common::Rect &area, const Common::Rect &clip, const DrawStep &step, uint32 extra = 0); + virtual void drawStep(const Common::Rect &area, const Common::Rect &clip, const DrawStep &step, uint32 extra = 0); /** * Copies the part of the current frame to the system overlay. @@ -490,17 +491,11 @@ public: virtual void blitSurface(const Graphics::Surface *source, const Common::Rect &r) = 0; /** - * Blits a given graphics surface into a small area of the current drawing surface. - * - * Note that the given surface is expected to be smaller than the - * active drawing surface, hence the WHOLE source surface will be - * blitted into the active surface, at the position specified by "r". + * Blits a given graphics surface at the specified position of the current drawing surface. */ - virtual void blitSubSurface(const Graphics::Surface *source, const Common::Rect &r) = 0; - virtual void blitSubSurfaceClip(const Graphics::Surface *source, const Common::Rect &r, const Common::Rect &clipping) = 0; + virtual void blitSubSurface(const Graphics::Surface *source, const Common::Point &p) = 0; - virtual void blitKeyBitmap(const Graphics::Surface *source, const Common::Rect &r) = 0; - virtual void blitKeyBitmapClip(const Graphics::Surface *source, const Common::Rect &r, const Common::Rect &clipping) = 0; + virtual void blitKeyBitmap(const Graphics::Surface *source, const Common::Point &p) = 0; virtual void blitAlphaBitmap(Graphics::TransparentSurface *source, const Common::Rect &r, GUI::ThemeEngine::AutoScaleMode autoscale = GUI::ThemeEngine::kAutoScaleNone, diff --git a/graphics/VectorRendererSpec.cpp b/graphics/VectorRendererSpec.cpp index 2f7164cc9b6..935e7c6d12a 100644 --- a/graphics/VectorRendererSpec.cpp +++ b/graphics/VectorRendererSpec.cpp @@ -474,6 +474,7 @@ void colorFillClip(PixelType *first, PixelType *last, PixelType color, int realX if (realX < clippingArea.left) { int diff = (clippingArea.left - realX); realX += diff; + first += diff; count -= diff; } @@ -667,9 +668,9 @@ gradientFillClip(PixelType *ptr, int width, int x, int y, int realX, int realY) if (grad == 0 || _gradCache[curGrad] == _gradCache[curGrad + 1] || // no color change stripSize < 2) { // the stip is small - colorFill(ptr, ptr + width, _gradCache[curGrad]); + colorFillClip(ptr, ptr + width, _gradCache[curGrad], realX, realY, _clippingArea); } else if (grad == 3 && ox) { - colorFill(ptr, ptr + width, _gradCache[curGrad + 1]); + colorFillClip(ptr, ptr + width, _gradCache[curGrad + 1], realX, realY, _clippingArea); } else { for (int j = x; j < x + width; j++, ptr++) { if (realX + j - x < _clippingArea.left || realX + j - x >= _clippingArea.right) continue; @@ -688,46 +689,23 @@ gradientFillClip(PixelType *ptr, int width, int x, int y, int realX, int realY) template void VectorRendererSpec:: fillSurface() { - byte *ptr = (byte *)_activeSurface->getPixels(); + Common::Rect drawRect(0, 0, _activeSurface->w, _activeSurface->h); + drawRect.clip(_clippingArea); - int h = _activeSurface->h; - int pitch = _activeSurface->pitch; - - if (Base::_fillMode == kFillBackground) { - colorFill((PixelType *)ptr, (PixelType *)(ptr + pitch * h), _bgColor); - } else if (Base::_fillMode == kFillForeground) { - colorFill((PixelType *)ptr, (PixelType *)(ptr + pitch * h), _fgColor); - } else if (Base::_fillMode == kFillGradient) { - precalcGradient(h); - - for (int i = 0; i < h; i++) { - gradientFill((PixelType *)ptr, _activeSurface->w, 0, i); - - ptr += pitch; - } - } -} - -template -void VectorRendererSpec:: -fillSurfaceClip(Common::Rect clipping) { - int w = _activeSurface->w; - int h = _activeSurface->h; - if (clipping.isEmpty() || (clipping.left == 0 && clipping.top == 0 && clipping.right == w && clipping.bottom == h)) { - fillSurface(); + if (drawRect.isEmpty()) { return; } - byte *ptr = (byte *)_activeSurface->getPixels(); - int pitch = _activeSurface->pitch; + int h = _activeSurface->h; + int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel; + + PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(0, drawRect.top); if (Base::_fillMode == kFillBackground || Base::_fillMode == kFillForeground) { PixelType color = (Base::_fillMode == kFillBackground ? _bgColor : _fgColor); - byte *ptrLeft = (ptr + _clippingArea.left), *ptrRight = ptr + _clippingArea.right; - for (int i = 0; i < h; i++) { - if (_clippingArea.top <= i && i < _clippingArea.bottom) { - colorFill((PixelType *)ptrLeft, (PixelType *)ptrRight, color); - } + PixelType *ptrLeft = (ptr + drawRect.left), *ptrRight = ptr + drawRect.right; + for (int i = drawRect.top; i < drawRect.bottom; i++) { + colorFill(ptrLeft, ptrRight, color); ptrLeft += pitch; ptrRight += pitch; @@ -736,10 +714,8 @@ fillSurfaceClip(Common::Rect clipping) { } else if (Base::_fillMode == kFillGradient) { precalcGradient(h); - for (int i = 0; i < h; i++) { - if (_clippingArea.top <= i && i < _clippingArea.bottom) { - gradientFill((PixelType *)ptr + _clippingArea.left, _clippingArea.width(), 0, i); - } + for (int i = drawRect.top; i < drawRect.bottom; i++) { + gradientFill(ptr + drawRect.left, drawRect.width(), 0, i); ptr += pitch; } @@ -780,67 +756,25 @@ blitSurface(const Graphics::Surface *source, const Common::Rect &r) { template void VectorRendererSpec:: -blitSubSurface(const Graphics::Surface *source, const Common::Rect &r) { - byte *dst_ptr = (byte *)_activeSurface->getBasePtr(r.left, r.top); - const byte *src_ptr = (const byte *)source->getPixels(); +blitSubSurface(const Graphics::Surface *source, const Common::Point &p) { + Common::Rect drawRect(p.x, p.y, p.x + source->w, p.y + source->h); + drawRect.clip(_clippingArea); - const int dst_pitch = _activeSurface->pitch; - const int src_pitch = source->pitch; - - int h = r.height(); - const int w = r.width() * sizeof(PixelType); - - while (h--) { - memcpy(dst_ptr, src_ptr, w); - dst_ptr += dst_pitch; - src_ptr += src_pitch; - } -} - -template -void VectorRendererSpec:: -blitSubSurfaceClip(const Graphics::Surface *source, const Common::Rect &r, const Common::Rect &clipping) { - if (clipping.isEmpty() || clipping.contains(r)) { - blitSubSurface(source, r); + if (drawRect.isEmpty()) { return; } - int16 x = r.left; - int16 y = r.top; + int sourceOffsetX = drawRect.left - p.x; + int sourceOffsetY = drawRect.top - p.y; - if (r.width() > source->w) - x = x + (r.width() >> 1) - (source->w >> 1); - - if (r.height() > source->h) - y = y + (r.height() >> 1) - (source->h >> 1); - - int w = source->w, h = source->h; - int usedW = w, usedH = h; - int offsetX = 0, offsetY = 0; - - if (x > clipping.right || x + w < clipping.left) return; - if (y > clipping.bottom || y + h < clipping.top) return; - if (x < clipping.left) { - offsetX = clipping.left - x; - usedW -= offsetX; - x = clipping.left; - } - if (y < clipping.top) { - offsetY = clipping.top - y; - usedH -= offsetY; - y = clipping.top; - } - if (usedW > clipping.width()) usedW = clipping.width(); - if (usedH > clipping.height()) usedH = clipping.height(); - - byte *dst_ptr = (byte *)_activeSurface->getBasePtr(x, y); - const byte *src_ptr = (const byte *)source->getBasePtr(offsetX, offsetY); + byte *dst_ptr = (byte *)_activeSurface->getBasePtr(drawRect.left, drawRect.top); + const byte *src_ptr = (const byte *)source->getBasePtr(sourceOffsetX, sourceOffsetY); const int dst_pitch = _activeSurface->pitch; const int src_pitch = source->pitch; - int lines = usedH; - const int sz = usedW * sizeof(PixelType); + int lines = drawRect.height(); + const int sz = drawRect.width() * sizeof(PixelType); while (lines--) { memcpy(dst_ptr, src_ptr, sz); @@ -851,26 +785,27 @@ blitSubSurfaceClip(const Graphics::Surface *source, const Common::Rect &r, const template void VectorRendererSpec:: -blitKeyBitmap(const Graphics::Surface *source, const Common::Rect &r) { - int16 x = r.left; - int16 y = r.top; +blitKeyBitmap(const Graphics::Surface *source, const Common::Point &p) { + Common::Rect drawRect(p.x, p.y, p.x + source->w, p.y + source->h); + drawRect.clip(_clippingArea); - if (r.width() > source->w) - x = x + (r.width() >> 1) - (source->w >> 1); + if (drawRect.isEmpty()) { + return; + } - if (r.height() > source->h) - y = y + (r.height() >> 1) - (source->h >> 1); + int sourceOffsetX = drawRect.left - p.x; + int sourceOffsetY = drawRect.top - p.y; - PixelType *dst_ptr = (PixelType *)_activeSurface->getBasePtr(x, y); - const PixelType *src_ptr = (const PixelType *)source->getPixels(); + PixelType *dst_ptr = (PixelType *)_activeSurface->getBasePtr(drawRect.left, drawRect.top); + const PixelType *src_ptr = (const PixelType *)source->getBasePtr(sourceOffsetX, sourceOffsetY); int dst_pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel; int src_pitch = source->pitch / source->format.bytesPerPixel; - int w, h = source->h; + int w, h = drawRect.height(); while (h--) { - w = source->w; + w = drawRect.width(); while (w--) { if (*src_ptr != _bitmapAlphaColor) @@ -880,8 +815,8 @@ blitKeyBitmap(const Graphics::Surface *source, const Common::Rect &r) { src_ptr++; } - dst_ptr = dst_ptr - source->w + dst_pitch; - src_ptr = src_ptr - source->w + src_pitch; + dst_ptr = dst_ptr - drawRect.width() + dst_pitch; + src_ptr = src_ptr - drawRect.width() + src_pitch; } } @@ -919,57 +854,6 @@ blitAlphaBitmap(Graphics::TransparentSurface *source, const Common::Rect &r, GUI } } -template -void VectorRendererSpec:: -blitKeyBitmapClip(const Graphics::Surface *source, const Common::Rect &r, const Common::Rect &clipping) { - if (clipping.isEmpty() || clipping.contains(r)) { - blitKeyBitmap(source, r); - return; - } - - int16 x = r.left; - int16 y = r.top; - - if (r.width() > source->w) - x = x + (r.width() >> 1) - (source->w >> 1); - - if (r.height() > source->h) - y = y + (r.height() >> 1) - (source->h >> 1); - - Common::Rect drawRect(x, y, x + source->w, y + source->h); - drawRect.clip(clipping); - - if (drawRect.isEmpty()) { - return; - } - - int sourceOffsetX = drawRect.left - x; - int sourceOffsetY = drawRect.top - y; - - PixelType *dst_ptr = (PixelType *)_activeSurface->getBasePtr(drawRect.left, drawRect.top); - const PixelType *src_ptr = (const PixelType *)source->getBasePtr(sourceOffsetX, sourceOffsetY); - - int dst_pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel; - int src_pitch = source->pitch / source->format.bytesPerPixel; - - int w, h = drawRect.height(); - - while (h--) { - w = drawRect.width(); - - while (w--) { - if (*src_ptr != _bitmapAlphaColor) - *dst_ptr = *src_ptr; - - dst_ptr++; - src_ptr++; - } - - dst_ptr = dst_ptr - drawRect.width() + dst_pitch; - src_ptr = src_ptr - drawRect.width() + src_pitch; - } -} - template void VectorRendererSpec:: applyScreenShading(GUI::ThemeEngine::ShadingStyle shadingStyle) { @@ -1178,7 +1062,6 @@ drawString(const Graphics::Font *font, const Common::String &text, const Common: } } -/** LINES **/ template void VectorRendererSpec:: drawLine(int x1, int y1, int x2, int y2) { @@ -1207,87 +1090,35 @@ drawLine(int x1, int y1, int x2, int y2) { int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel; int st = Base::_strokeWidth >> 1; - if (dy == 0) { // horizontal lines - // these can be filled really fast with a single memset. - colorFill(ptr, ptr + dx + 1, (PixelType)_fgColor); - - for (int i = 0, p = pitch; i < st; ++i, p += pitch) { - colorFill(ptr + p, ptr + dx + 1 + p, (PixelType)_fgColor); - colorFill(ptr - p, ptr + dx + 1 - p, (PixelType)_fgColor); - } - - } else if (dx == 0) { // vertical lines - // these ones use a static pitch increase. - while (y1++ <= y2) { - colorFill(ptr - st, ptr + st, (PixelType)_fgColor); - ptr += pitch; - } - - } else if (dx == dy) { // diagonal lines - // these ones also use a fixed pitch increase - pitch += (x2 > x1) ? 1 : -1; - - while (dy--) { - colorFill(ptr - st, ptr + st, (PixelType)_fgColor); - ptr += pitch; - } - - } else { // generic lines, use the standard algorithm... - drawLineAlg(x1, y1, x2, y2, dx, dy, (PixelType)_fgColor); - } -} - -template -void VectorRendererSpec:: -drawLineClip(int x1, int y1, int x2, int y2, Common::Rect clipping) { - x1 = CLIP(x1, 0, (int)Base::_activeSurface->w); - x2 = CLIP(x2, 0, (int)Base::_activeSurface->w); - y1 = CLIP(y1, 0, (int)Base::_activeSurface->h); - y2 = CLIP(y2, 0, (int)Base::_activeSurface->h); - - // we draw from top to bottom - if (y2 < y1) { - SWAP(x1, x2); - SWAP(y1, y2); - } - - uint dx = ABS(x2 - x1); - uint dy = ABS(y2 - y1); - - // this is a point, not a line. stoopid. - if (dy == 0 && dx == 0) - return; - - if (Base::_strokeWidth == 0) - return; - - PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(x1, y1); - int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel; - int st = Base::_strokeWidth >> 1; - - Common::Rect backup = _clippingArea; - _clippingArea = clipping; - bool needsClipping = !_clippingArea.isEmpty() && (!_clippingArea.contains(x1, y1) || !_clippingArea.contains(x2, y2)); - if (!needsClipping) { - drawLine(x1, y1, x2, y2); - _clippingArea = backup; - return; - } + bool useClippingVersions = !_clippingArea.contains(x1, y1) || !_clippingArea.contains(x2, y2); int ptr_x = x1, ptr_y = y1; if (dy == 0) { // horizontal lines - colorFillClip(ptr, ptr + dx + 1, (PixelType)_fgColor, x1, y1, _clippingArea); + if (useClippingVersions) { + colorFillClip(ptr, ptr + dx + 1, (PixelType)_fgColor, x1, y1, _clippingArea); + } else { + colorFill(ptr, ptr + dx + 1, (PixelType)_fgColor); + } for (int i = 0, p = pitch; i < st; ++i, p += pitch) { - colorFillClip(ptr + p, ptr + dx + 1 + p, (PixelType)_fgColor, x1, y1 + p/pitch, _clippingArea); - colorFillClip(ptr - p, ptr + dx + 1 - p, (PixelType)_fgColor, x1, y1 - p/pitch, _clippingArea); + if (useClippingVersions) { + colorFillClip(ptr + p, ptr + dx + 1 + p, (PixelType)_fgColor, x1, y1 + p/pitch, _clippingArea); + colorFillClip(ptr - p, ptr + dx + 1 - p, (PixelType)_fgColor, x1, y1 - p/pitch, _clippingArea); + } else { + colorFill(ptr + p, ptr + dx + 1 + p, (PixelType)_fgColor); + colorFill(ptr - p, ptr + dx + 1 - p, (PixelType)_fgColor); + } } } else if (dx == 0) { // vertical lines // these ones use a static pitch increase. while (y1++ <= y2) { - colorFillClip(ptr - st, ptr + st, (PixelType)_fgColor, x1 - st, ptr_y, _clippingArea); + if (useClippingVersions) { + colorFillClip(ptr - st, ptr + st, (PixelType)_fgColor, x1 - st, ptr_y, _clippingArea); + } else { + colorFill(ptr - st, ptr + st, (PixelType)_fgColor); + } ptr += pitch; ++ptr_y; } @@ -1297,14 +1128,22 @@ drawLineClip(int x1, int y1, int x2, int y2, Common::Rect clipping) { pitch += (x2 > x1) ? 1 : -1; while (dy--) { - colorFillClip(ptr - st, ptr + st, (PixelType)_fgColor, ptr_x - st, ptr_y, _clippingArea); + if (useClippingVersions) { + colorFillClip(ptr - st, ptr + st, (PixelType)_fgColor, ptr_x - st, ptr_y, _clippingArea); + } else { + colorFill(ptr - st, ptr + st, (PixelType)_fgColor); + } ptr += pitch; ++ptr_y; if (x2 > x1) ++ptr_x; else --ptr_x; } } else { // generic lines, use the standard algorithm... - drawLineAlgClip(x1, y1, x2, y2, dx, dy, (PixelType)_fgColor); + if (useClippingVersions) { + drawLineAlgClip(x1, y1, x2, y2, dx, dy, (PixelType)_fgColor); + } else { + drawLineAlg(x1, y1, x2, y2, dx, dy, (PixelType)_fgColor); + } } } @@ -1316,47 +1155,7 @@ drawCircle(int x, int y, int r) { x - r < 0 || y - r < 0 || x == 0 || y == 0 || r <= 0) return; - if (Base::_fillMode != kFillDisabled && Base::_shadowOffset - && x + r + Base::_shadowOffset < Base::_activeSurface->w - && y + r + Base::_shadowOffset < Base::_activeSurface->h) { - drawCircleAlg(x + Base::_shadowOffset + 1, y + Base::_shadowOffset + 1, r, 0, kFillForeground); - } - - switch (Base::_fillMode) { - case kFillDisabled: - if (Base::_strokeWidth) - drawCircleAlg(x, y, r, _fgColor, kFillDisabled); - break; - - case kFillForeground: - drawCircleAlg(x, y, r, _fgColor, kFillForeground); - break; - - case kFillBackground: - if (Base::_strokeWidth > 1) { - drawCircleAlg(x, y, r, _fgColor, kFillForeground); - drawCircleAlg(x, y, r - Base::_strokeWidth, _bgColor, kFillBackground); - } else { - drawCircleAlg(x, y, r, _bgColor, kFillBackground); - drawCircleAlg(x, y, r, _fgColor, kFillDisabled); - } - break; - - case kFillGradient: - break; - } -} - -template -void VectorRendererSpec:: -drawCircleClip(int x, int y, int r, Common::Rect clipping) { - if (x + r > Base::_activeSurface->w || y + r > Base::_activeSurface->h || - x - r < 0 || y - r < 0 || x == 0 || y == 0 || r <= 0) - return; - - Common::Rect backup = _clippingArea; - _clippingArea = clipping; - bool useClippingVersions = !(_clippingArea.isEmpty() || _clippingArea.contains(Common::Rect(x - r, y - r, x + r, y + r))); + bool useClippingVersions = !_clippingArea.contains(Common::Rect(x - r, y - r, x + r, y + r)); if (Base::_fillMode != kFillDisabled && Base::_shadowOffset && x + r + Base::_shadowOffset < Base::_activeSurface->w @@ -1407,8 +1206,6 @@ drawCircleClip(int x, int y, int r, Common::Rect clipping) { case kFillGradient: break; } - - _clippingArea = backup; } /** SQUARES **/ @@ -1419,45 +1216,7 @@ drawSquare(int x, int y, int w, int h) { w <= 0 || h <= 0 || x < 0 || y < 0) return; - if (Base::_fillMode != kFillDisabled && Base::_shadowOffset - && x + w + Base::_shadowOffset < Base::_activeSurface->w - && y + h + Base::_shadowOffset < Base::_activeSurface->h) { - drawSquareShadow(x, y, w, h, Base::_shadowOffset); - } - - switch (Base::_fillMode) { - case kFillDisabled: - if (Base::_strokeWidth) - drawSquareAlg(x, y, w, h, _fgColor, kFillDisabled); - break; - - case kFillForeground: - drawSquareAlg(x, y, w, h, _fgColor, kFillForeground); - break; - - case kFillBackground: - drawSquareAlg(x, y, w, h, _bgColor, kFillBackground); - drawSquareAlg(x, y, w, h, _fgColor, kFillDisabled); - break; - - case kFillGradient: - VectorRendererSpec::drawSquareAlg(x, y, w, h, 0, kFillGradient); - if (Base::_strokeWidth) - drawSquareAlg(x, y, w, h, _fgColor, kFillDisabled); - break; - } -} - -template -void VectorRendererSpec:: -drawSquareClip(int x, int y, int w, int h, Common::Rect clipping) { - if (x + w > Base::_activeSurface->w || y + h > Base::_activeSurface->h || - w <= 0 || h <= 0 || x < 0 || y < 0) - return; - - Common::Rect backup = _clippingArea; - _clippingArea = clipping; - bool useClippingVersions = !(_clippingArea.isEmpty() || _clippingArea.contains(Common::Rect(x, y, x + w, y + h))); + bool useClippingVersions = !_clippingArea.contains(Common::Rect(x, y, x + w, y + h)); if (Base::_fillMode != kFillDisabled && Base::_shadowOffset && x + w + Base::_shadowOffset < Base::_activeSurface->w @@ -1505,8 +1264,6 @@ drawSquareClip(int x, int y, int w, int h, Common::Rect clipping) { } break; } - - _clippingArea = backup; } /** ROUNDED SQUARES **/ @@ -1517,38 +1274,13 @@ drawRoundedSquare(int x, int y, int r, int w, int h) { w <= 0 || h <= 0 || x < 0 || y < 0 || r <= 0) return; - if ((r * 2) > w || (r * 2) > h) - r = MIN(w /2, h / 2); - - if (r <= 0) - return; - - if (Base::_fillMode != kFillDisabled && Base::_shadowOffset - && x + w + Base::_shadowOffset + 1 < Base::_activeSurface->w - && y + h + Base::_shadowOffset + 1 < Base::_activeSurface->h - && h > (Base::_shadowOffset + 1) * 2) { - drawRoundedSquareShadow(x, y, r, w, h, Base::_shadowOffset); - } - - drawRoundedSquareAlg(x, y, r, w, h, _fgColor, Base::_fillMode); -} - -template -void VectorRendererSpec:: -drawRoundedSquareClip(int x, int y, int r, int w, int h, Common::Rect clipping) { - if (x + w > Base::_activeSurface->w || y + h > Base::_activeSurface->h || - w <= 0 || h <= 0 || x < 0 || y < 0 || r <= 0) - return; - if ((r * 2) > w || (r * 2) > h) r = MIN(w / 2, h / 2); if (r <= 0) return; - Common::Rect backup = _clippingArea; - _clippingArea = clipping; - bool useOriginal = (_clippingArea.isEmpty() || _clippingArea.contains(Common::Rect(x, y, x + w, y + h))); + bool useOriginal = _clippingArea.contains(Common::Rect(x, y, x + w, y + h)); if (Base::_fillMode != kFillDisabled && Base::_shadowOffset && x + w + Base::_shadowOffset + 1 < Base::_activeSurface->w @@ -1566,8 +1298,6 @@ drawRoundedSquareClip(int x, int y, int r, int w, int h, Common::Rect clipping) } else { drawRoundedSquareAlgClip(x, y, r, w, h, _fgColor, Base::_fillMode); } - - _clippingArea = backup; } template @@ -1577,64 +1307,23 @@ drawTab(int x, int y, int r, int w, int h) { w <= 0 || h <= 0 || x < 0 || y < 0 || r > w || r > h) return; - if (r == 0 && Base::_bevel > 0) { - drawBevelTabAlg(x, y, w, h, Base::_bevel, _bevelColor, _fgColor, (Base::_dynamicData >> 16), (Base::_dynamicData & 0xFFFF)); - return; - } - - if (r == 0) return; - - switch (Base::_fillMode) { - case kFillDisabled: - // FIXME: Implement this - return; - - case kFillGradient: - case kFillBackground: - // FIXME: This is broken for the AA renderer. - // See the rounded rect alg for how to fix it. (The border should - // be drawn before the interior, both inside drawTabAlg.) - drawTabShadow(x, y, w - 2, h, r); - drawTabAlg(x, y, w - 2, h, r, _bgColor, Base::_fillMode); - if (Base::_strokeWidth) - drawTabAlg(x, y, w, h, r, _fgColor, kFillDisabled, (Base::_dynamicData >> 16), (Base::_dynamicData & 0xFFFF)); - break; - - case kFillForeground: - drawTabAlg(x, y, w, h, r, _fgColor, Base::_fillMode); - break; - } -} - -template -void VectorRendererSpec:: -drawTabClip(int x, int y, int r, int w, int h, Common::Rect clipping) { - if (x + w > Base::_activeSurface->w || y + h > Base::_activeSurface->h || - w <= 0 || h <= 0 || x < 0 || y < 0 || r > w || r > h) - return; - - Common::Rect backup = _clippingArea; - _clippingArea = clipping; - bool useClippingVersions = !(_clippingArea.isEmpty() || _clippingArea.contains(Common::Rect(x, y, x + w, y + h))); + bool useClippingVersions = !_clippingArea.contains(Common::Rect(x, y, x + w, y + h)); if (r == 0 && Base::_bevel > 0) { if (useClippingVersions) drawBevelTabAlgClip(x, y, w, h, Base::_bevel, _bevelColor, _fgColor, (Base::_dynamicData >> 16), (Base::_dynamicData & 0xFFFF)); else drawBevelTabAlg(x, y, w, h, Base::_bevel, _bevelColor, _fgColor, (Base::_dynamicData >> 16), (Base::_dynamicData & 0xFFFF)); - _clippingArea = backup; return; } if (r == 0) { - _clippingArea = backup; return; } switch (Base::_fillMode) { case kFillDisabled: // FIXME: Implement this - _clippingArea = backup; return; case kFillGradient: @@ -1662,14 +1351,11 @@ drawTabClip(int x, int y, int r, int w, int h, Common::Rect clipping) { drawTabAlg(x, y, w, h, r, _fgColor, Base::_fillMode); break; } - - _clippingArea = backup; } template void VectorRendererSpec:: drawTriangle(int x, int y, int w, int h, TriangleOrientation orient) { - if (x + w > Base::_activeSurface->w || y + h > Base::_activeSurface->h) return; @@ -1689,76 +1375,7 @@ drawTriangle(int x, int y, int w, int h, TriangleOrientation orient) { if (Base::_dynamicData != 0) orient = (TriangleOrientation)Base::_dynamicData; - if (w == h) { - int newW = w; - - switch (orient) { - case kTriangleUp: - case kTriangleDown: - //drawTriangleFast(x, y, newW, (orient == kTriangleDown), color, Base::_fillMode); - drawTriangleVertAlg(x, y, newW, newW, (orient == kTriangleDown), color, Base::_fillMode); - break; - - case kTriangleLeft: - case kTriangleRight: - case kTriangleAuto: - break; - } - - if (Base::_strokeWidth > 0) - if (Base::_fillMode == kFillBackground || Base::_fillMode == kFillGradient) { - //drawTriangleFast(x, y, newW, (orient == kTriangleDown), _fgColor, kFillDisabled); - drawTriangleVertAlg(x, y, newW, newW, (orient == kTriangleDown), color, Base::_fillMode); - } - } else { - int newW = w; - int newH = h; - - switch (orient) { - case kTriangleUp: - case kTriangleDown: - drawTriangleVertAlg(x, y, newW, newH, (orient == kTriangleDown), color, Base::_fillMode); - break; - - case kTriangleLeft: - case kTriangleRight: - case kTriangleAuto: - break; - } - - if (Base::_strokeWidth > 0) { - if (Base::_fillMode == kFillBackground || Base::_fillMode == kFillGradient) { - drawTriangleVertAlg(x, y, newW, newH, (orient == kTriangleDown), _fgColor, kFillDisabled); - } - } - } -} - -template -void VectorRendererSpec:: -drawTriangleClip(int x, int y, int w, int h, TriangleOrientation orient, Common::Rect clipping) { - if (x + w > Base::_activeSurface->w || y + h > Base::_activeSurface->h) - return; - - PixelType color = 0; - - if (Base::_strokeWidth <= 1) { - if (Base::_fillMode == kFillForeground) - color = _fgColor; - else if (Base::_fillMode == kFillBackground) - color = _bgColor; - } else { - if (Base::_fillMode == kFillDisabled) - return; - color = _fgColor; - } - - if (Base::_dynamicData != 0) - orient = (TriangleOrientation)Base::_dynamicData; - - Common::Rect backup = _clippingArea; - _clippingArea = clipping; - bool useClippingVersions = !(_clippingArea.isEmpty() || _clippingArea.contains(Common::Rect(x, y, x + w, y + h))); + bool useClippingVersions = !_clippingArea.contains(Common::Rect(x, y, x + w, y + h)); if (w == h) { int newW = w; @@ -1813,8 +1430,6 @@ drawTriangleClip(int x, int y, int w, int h, TriangleOrientation orient, Common: } } } - - _clippingArea = backup; } @@ -1842,7 +1457,7 @@ drawTabAlg(int x1, int y1, int w, int h, int r, PixelType color, VectorRenderer: PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1); int real_radius = r; - int short_h = h - r + 2; + int short_h = h - r; int long_h = h; if (fill_m == kFillDisabled) { @@ -1947,7 +1562,7 @@ drawTabAlgClip(int x1, int y1, int w, int h, int r, PixelType color, VectorRende int fill_x = x1, fill_y = y1; int real_radius = r; - int short_h = h - r + 2; + int short_h = h - r; int long_h = h; if (fill_m == kFillDisabled) { @@ -2064,7 +1679,7 @@ drawTabShadow(int x1, int y1, int w, int h, int r) { PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(xstart + width - r, ystart + r); PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(xstart, ystart); - int short_h = height - (2 * r) + 2; + int short_h = height - (2 * r); PixelType color = _format.RGBToColor(0, 0, 0); BE_RESET(); @@ -2128,7 +1743,7 @@ drawTabShadowClip(int x1, int y1, int w, int h, int r) { int tl_x = xstart + r, tl_y = ystart + r; int fill_x = xstart, fill_y = ystart; - int short_h = height - (2 * r) + 2; + int short_h = height - (2 * r); PixelType color = _format.RGBToColor(0, 0, 0); BE_RESET(); @@ -2344,7 +1959,7 @@ drawSquareAlgClip(int x, int y, int w, int h, PixelType color, VectorRenderer::F /** SQUARE ALGORITHM **/ template void VectorRendererSpec:: -drawBevelSquareAlg(int x, int y, int w, int h, int bevel, PixelType top_color, PixelType bottom_color, bool fill) { +drawBevelSquareAlg(int x, int y, int w, int h, int bevel, PixelType top_color, PixelType bottom_color) { int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel; int i, j; PixelType *ptr_left; @@ -2404,7 +2019,7 @@ drawBevelSquareAlg(int x, int y, int w, int h, int bevel, PixelType top_color, P template void VectorRendererSpec:: -drawBevelSquareAlgClip(int x, int y, int w, int h, int bevel, PixelType top_color, PixelType bottom_color, bool fill) { +drawBevelSquareAlgClip(int x, int y, int w, int h, int bevel, PixelType top_color, PixelType bottom_color) { int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel; int i, j; PixelType *ptr_left; @@ -3080,9 +2695,6 @@ drawBorderRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, while (x++ < (y - 2)) { BE_ALGORITHM(); - if (x < _clippingArea.left || x > _clippingArea.right) continue; - if (y < _clippingArea.top || y > _clippingArea.bottom) continue; - BE_DRAWCIRCLE_BCOLOR_TR_CW(ptr_tr, x, y, px, py, (uint8)(alpha_r + (alphaStep_tr * x))); BE_DRAWCIRCLE_BCOLOR_BR_CW(ptr_br, x, y, px, py, (uint8)(alpha_b + (alphaStep_br * x))); BE_DRAWCIRCLE_BCOLOR_BL_CW(ptr_bl, x, y, px, py, (uint8)(alpha_l + (alphaStep_bl * x))); @@ -3867,7 +3479,7 @@ drawTabAlg(int x1, int y1, int w, int h, int r, PixelType color, VectorRenderer: } } - int short_h = h - r + 2; + int short_h = h - r; ptr_fill += pitch * real_radius; while (short_h--) { @@ -3898,7 +3510,7 @@ drawTabAlg(int x1, int y1, int w, int h, int r, PixelType color, VectorRenderer: color1 = color2 = color; int long_h = h; - int short_h = h - real_radius + 2; + int short_h = h - real_radius; x = real_radius; y = 0; T = 0; diff --git a/graphics/VectorRendererSpec.h b/graphics/VectorRendererSpec.h index 958ad0717b7..e903451a149 100644 --- a/graphics/VectorRendererSpec.h +++ b/graphics/VectorRendererSpec.h @@ -51,29 +51,18 @@ public: VectorRendererSpec(PixelFormat format); void drawLine(int x1, int y1, int x2, int y2); - void drawLineClip(int x1, int y1, int x2, int y2, Common::Rect clipping); void drawCircle(int x, int y, int r); - void drawCircleClip(int x, int y, int r, Common::Rect clipping); void drawSquare(int x, int y, int w, int h); - void drawSquareClip(int x, int y, int w, int h, Common::Rect clipping); void drawRoundedSquare(int x, int y, int r, int w, int h); - void drawRoundedSquareClip(int x, int y, int r, int w, int h, Common::Rect clipping); void drawTriangle(int x, int y, int base, int height, TriangleOrientation orient); - void drawTriangleClip(int x, int y, int base, int height, TriangleOrientation orient, Common::Rect clipping); void drawTab(int x, int y, int r, int w, int h); - void drawTabClip(int x, int y, int r, int w, int h, Common::Rect clipping); - void drawBeveledSquare(int x, int y, int w, int h, int bevel) { - drawBevelSquareAlg(x, y, w, h, bevel, _bevelColor, _fgColor, Base::_fillMode != kFillDisabled); - } - void drawBeveledSquareClip(int x, int y, int w, int h, int bevel, Common::Rect clipping) { - bool useClippingVersions = !(clipping.isEmpty() || clipping.contains(Common::Rect(x, y, x + w, y + h))); + + void drawBeveledSquare(int x, int y, int w, int h) { + bool useClippingVersions = !_clippingArea.contains(Common::Rect(x, y, x + w, y + h)); if (useClippingVersions) { - Common::Rect backup = _clippingArea; - _clippingArea = clipping; - drawBevelSquareAlgClip(x, y, w, h, bevel, _bevelColor, _fgColor, Base::_fillMode != kFillDisabled); - _clippingArea = backup; + drawBevelSquareAlgClip(x, y, w, h, _bevel, _bevelColor, _fgColor); } else { - drawBevelSquareAlg(x, y, w, h, bevel, _bevelColor, _fgColor, Base::_fillMode != kFillDisabled); + drawBevelSquareAlg(x, y, w, h, _bevel, _bevelColor, _fgColor); } } void drawString(const Graphics::Font *font, const Common::String &text, @@ -84,17 +73,15 @@ public: void setBgColor(uint8 r, uint8 g, uint8 b) { _bgColor = _format.RGBToColor(r, g, b); } void setBevelColor(uint8 r, uint8 g, uint8 b) { _bevelColor = _format.RGBToColor(r, g, b); } void setGradientColors(uint8 r1, uint8 g1, uint8 b1, uint8 r2, uint8 g2, uint8 b2); + void setClippingRect(const Common::Rect &clippingArea) override { _clippingArea = clippingArea; } void copyFrame(OSystem *sys, const Common::Rect &r); void copyWholeFrame(OSystem *sys) { copyFrame(sys, Common::Rect(0, 0, _activeSurface->w, _activeSurface->h)); } void fillSurface(); - void fillSurfaceClip(Common::Rect clipping); void blitSurface(const Graphics::Surface *source, const Common::Rect &r); - void blitSubSurface(const Graphics::Surface *source, const Common::Rect &r); - void blitSubSurfaceClip(const Graphics::Surface *source, const Common::Rect &r, const Common::Rect &clipping); - void blitKeyBitmap(const Graphics::Surface *source, const Common::Rect &r); - void blitKeyBitmapClip(const Graphics::Surface *source, const Common::Rect &r, const Common::Rect &clipping); + void blitSubSurface(const Graphics::Surface *source, const Common::Point &p); + void blitKeyBitmap(const Graphics::Surface *source, const Common::Point &p); void blitAlphaBitmap(Graphics::TransparentSurface *source, const Common::Rect &r, GUI::ThemeEngine::AutoScaleMode autoscale = GUI::ThemeEngine::kAutoScaleNone, Graphics::DrawStep::VectorAlignment xAlign = Graphics::DrawStep::kVectorAlignManual, @@ -223,10 +210,10 @@ protected: bool inverted, PixelType color, FillMode fill_m); virtual void drawBevelSquareAlg(int x, int y, int w, int h, - int bevel, PixelType top_color, PixelType bottom_color, bool fill); + int bevel, PixelType top_color, PixelType bottom_color); virtual void drawBevelSquareAlgClip(int x, int y, int w, int h, - int bevel, PixelType top_color, PixelType bottom_color, bool fill); + int bevel, PixelType top_color, PixelType bottom_color); virtual void drawTabAlg(int x, int y, int w, int h, int r, PixelType color, VectorRenderer::FillMode fill_m, diff --git a/graphics/cursorman.cpp b/graphics/cursorman.cpp index 678b074360c..751554ffb75 100644 --- a/graphics/cursorman.cpp +++ b/graphics/cursorman.cpp @@ -147,6 +147,14 @@ void CursorManager::replaceCursor(const void *buf, uint w, uint h, int hotspotX, g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, dontScale, format); } +void CursorManager::replaceCursor(const Graphics::Cursor *cursor) { + replaceCursor(cursor->getSurface(), cursor->getWidth(), cursor->getHeight(), cursor->getHotspotX(), + cursor->getHotspotY(), cursor->getKeyColor()); + + if (cursor->getPalette()) + replaceCursorPalette(cursor->getPalette(), cursor->getPaletteStartIndex(), cursor->getPaletteCount()); +} + bool CursorManager::supportsCursorPalettes() { return g_system->hasFeature(OSystem::kFeatureCursorPalette); } diff --git a/graphics/cursorman.h b/graphics/cursorman.h index f4a0ebbd82e..36215d03e2d 100644 --- a/graphics/cursorman.h +++ b/graphics/cursorman.h @@ -26,6 +26,7 @@ #include "common/scummsys.h" #include "common/stack.h" #include "common/singleton.h" +#include "graphics/cursor.h" #include "graphics/pixelformat.h" namespace Graphics { @@ -99,6 +100,15 @@ public: */ void replaceCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL); + /** + * Replace the current cursor on the stack. If the stack is empty, the + * cursor is pushed instead. It's a slightly more optimized way of + * popping the old cursor before pushing the new one. + * + * @param cursor the new cursor + */ + void replaceCursor(const Graphics::Cursor *cursor); + /** * Pop all of the cursors and cursor palettes from their respective stacks. * The purpose is to ensure that all unecessary cursors are removed from the @@ -185,6 +195,9 @@ private: uint _size; + // _format set to default by Graphics::PixelFormat default constructor + Cursor() : _data(0), _visible(false), _width(0), _height(0), _hotspotX(0), _hotspotY(0), _keycolor(0), _dontScale(false), _size(0) {} + Cursor(const void *data, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL); ~Cursor(); }; @@ -197,6 +210,8 @@ private: bool _disabled; + Palette() : _data(0), _start(0), _num(0), _size(0), _disabled(false) {} + Palette(const byte *colors, uint start, uint num); ~Palette(); }; diff --git a/graphics/font.cpp b/graphics/font.cpp index 32d2852b896..3bcfad22c3a 100644 --- a/graphics/font.cpp +++ b/graphics/font.cpp @@ -142,15 +142,21 @@ struct WordWrapper { line.clear(); w = 0; } + + void clear() { + lines.clear(); + actualMaxLineWidth = 0; + } }; template -int wordWrapTextImpl(const Font &font, const StringType &str, int maxWidth, Common::Array &lines, int initWidth) { +int wordWrapTextImpl(const Font &font, const StringType &str, int maxWidth, Common::Array &lines, int initWidth, bool evenWidthLinesModeEnabled, bool wrapOnExplicitNewLines) { WordWrapper wrapper(lines); StringType line; StringType tmpStr; int lineWidth = initWidth; int tmpWidth = 0; + int fullTextWidthEWL = initWidth; // this replaces new line characters (if any) with single spaces - it is used in Even Width Lines mode // The rough idea behind this algorithm is as follows: // We accumulate characters into the string tmpStr. Whenever a full word @@ -166,80 +172,143 @@ int wordWrapTextImpl(const Font &font, const StringType &str, int maxWidth, Comm // lines. typename StringType::unsigned_type last = 0; - for (typename StringType::const_iterator x = str.begin(); x != str.end(); ++x) { - typename StringType::unsigned_type c = *x; - // Convert Windows and Mac line breaks into plain \n - if (c == '\r') { - if (x != str.end() && *(x + 1) == '\n') { - ++x; + // When EvenWidthLines mode is enabled then we require an early loop over the entire string + // in order to get the full width of the text + // + // "Wrap On Explicit New Lines" and "Even Width Lines" modes are mutually exclusive, + // If both are set to true and there are new line characters in the text, + // then "Even Width Lines" mode is disabled. + // + if (evenWidthLinesModeEnabled) { + // Early loop to get the full width of the text + for (typename StringType::const_iterator x = str.begin(); x != str.end(); ++x) { + typename StringType::unsigned_type c = *x; + + // Check for Windows and Mac line breaks + if (c == '\r') { + if (x != str.end() && *(x + 1) == '\n') { + ++x; + } + c = '\n'; } - c = '\n'; + + if (c == '\n') { + if (!wrapOnExplicitNewLines) { + c = ' '; + } else { + evenWidthLinesModeEnabled = false; + break; + } + } + + const int w = font.getCharWidth(c) + font.getKerningOffset(last, c); + last = c; + fullTextWidthEWL += w; } + } - const int currentCharWidth = font.getCharWidth(c); - const int w = currentCharWidth + font.getKerningOffset(last, c); - last = c; - const bool wouldExceedWidth = (lineWidth + tmpWidth + w > maxWidth); - - // If this char is a whitespace, then it represents a potential - // 'wrap point' where wrapping could take place. Everything that - // came before it can now safely be added to the line, as we know - // that it will not have to be wrapped. - if (Common::isSpace(c)) { - line += tmpStr; - lineWidth += tmpWidth; - - tmpStr.clear(); - tmpWidth = 0; - - // If we encounter a line break (\n), or if the new space would - // cause the line to overflow: start a new line - if (c == '\n' || wouldExceedWidth) { - wrapper.add(line, lineWidth); + int targetTotalLinesNumberEWL = 0; + int targetMaxLineWidth = 0; + do { + if (evenWidthLinesModeEnabled) { + wrapper.clear(); + targetTotalLinesNumberEWL += 1; + // We add +2 to the fullTextWidthEWL to account for possible shadow pixels + // We add +10 * font.getCharWidth(' ') to the quotient since we want to allow some extra margin (about an extra wprd's length) + // since that yields better looking results + targetMaxLineWidth = ((fullTextWidthEWL + 2) / targetTotalLinesNumberEWL) + 10 * font.getCharWidth(' '); + if (targetMaxLineWidth > maxWidth) { + // repeat the loop with increased targetTotalLinesNumberEWL continue; } + } else { + targetMaxLineWidth = maxWidth; } - // If the max line width would be exceeded by adding this char, - // insert a line break. - if (wouldExceedWidth) { - // Commit what we have so far, *if* we have anything. - // If line is empty, then we are looking at a word - // which exceeds the maximum line width. - if (lineWidth > 0) { - wrapper.add(line, lineWidth); - // Trim left side - while (tmpStr.size() && Common::isSpace(tmpStr[0])) { - tmpStr.deleteChar(0); - // This is not very fast, but it is the simplest way to - // assure we do not mess something up because of kerning. - tmpWidth = font.getStringWidth(tmpStr); + last = 0; + tmpWidth = 0; + + for (typename StringType::const_iterator x = str.begin(); x != str.end(); ++x) { + typename StringType::unsigned_type c = *x; + + // Convert Windows and Mac line breaks into plain \n + if (c == '\r') { + if (x != str.end() && *(x + 1) == '\n') { + ++x; } + c = '\n'; + } + // if wrapping on explicit new lines is disabled, then new line characters should be treated as a single white space char + if (!wrapOnExplicitNewLines && c == '\n') { + c = ' '; + } - if (tmpStr.empty()) { - // If tmpStr is empty, we might have removed the space before 'c'. - // That means we have to recompute the kerning. + const int currentCharWidth = font.getCharWidth(c); + const int w = currentCharWidth + font.getKerningOffset(last, c); + last = c; + const bool wouldExceedWidth = (lineWidth + tmpWidth + w > targetMaxLineWidth); - tmpWidth += currentCharWidth + font.getKerningOffset(0, c); - tmpStr += c; + // If this char is a whitespace, then it represents a potential + // 'wrap point' where wrapping could take place. Everything that + // came before it can now safely be added to the line, as we know + // that it will not have to be wrapped. + if (Common::isSpace(c)) { + line += tmpStr; + lineWidth += tmpWidth; + + tmpStr.clear(); + tmpWidth = 0; + + // If we encounter a line break (\n), or if the new space would + // cause the line to overflow: start a new line + if ((wrapOnExplicitNewLines && c == '\n') || wouldExceedWidth) { + wrapper.add(line, lineWidth); continue; } - } else { - wrapper.add(tmpStr, tmpWidth); } + + // If the max line width would be exceeded by adding this char, + // insert a line break. + if (wouldExceedWidth) { + // Commit what we have so far, *if* we have anything. + // If line is empty, then we are looking at a word + // which exceeds the maximum line width. + if (lineWidth > 0) { + wrapper.add(line, lineWidth); + // Trim left side + while (tmpStr.size() && Common::isSpace(tmpStr[0])) { + tmpStr.deleteChar(0); + // This is not very fast, but it is the simplest way to + // assure we do not mess something up because of kerning. + tmpWidth = font.getStringWidth(tmpStr); + } + + if (tmpStr.empty()) { + // If tmpStr is empty, we might have removed the space before 'c'. + // That means we have to recompute the kerning. + + tmpWidth += currentCharWidth + font.getKerningOffset(0, c); + tmpStr += c; + continue; + } + } else { + wrapper.add(tmpStr, tmpWidth); + } + } + + tmpWidth += w; + tmpStr += c; } - tmpWidth += w; - tmpStr += c; - } - - // If some text is left over, add it as the final line - line += tmpStr; - lineWidth += tmpWidth; - if (lineWidth > 0) { - wrapper.add(line, lineWidth); - } + // If some text is left over, add it as the final line + line += tmpStr; + lineWidth += tmpWidth; + if (lineWidth > 0) { + wrapper.add(line, lineWidth); + } + } while (evenWidthLinesModeEnabled + && (targetMaxLineWidth > maxWidth)); return wrapper.actualMaxLineWidth; } @@ -318,12 +387,12 @@ void Font::drawString(ManagedSurface *dst, const Common::U32String &str, int x, } } -int Font::wordWrapText(const Common::String &str, int maxWidth, Common::Array &lines, int initWidth) const { - return wordWrapTextImpl(*this, str, maxWidth, lines, initWidth); +int Font::wordWrapText(const Common::String &str, int maxWidth, Common::Array &lines, int initWidth, bool evenWidthLinesModeEnabled, bool wrapOnExplicitNewLines) const { + return wordWrapTextImpl(*this, str, maxWidth, lines, initWidth, evenWidthLinesModeEnabled, wrapOnExplicitNewLines); } -int Font::wordWrapText(const Common::U32String &str, int maxWidth, Common::Array &lines, int initWidth) const { - return wordWrapTextImpl(*this, str, maxWidth, lines, initWidth); +int Font::wordWrapText(const Common::U32String &str, int maxWidth, Common::Array &lines, int initWidth, bool evenWidthLinesModeEnabled, bool wrapOnExplicitNewLines) const { + return wordWrapTextImpl(*this, str, maxWidth, lines, initWidth, evenWidthLinesModeEnabled, wrapOnExplicitNewLines); } Common::String Font::handleEllipsis(const Common::String &input, int w) const { diff --git a/graphics/font.h b/graphics/font.h index 48330dedfaf..d9f81cca8ca 100644 --- a/graphics/font.h +++ b/graphics/font.h @@ -173,10 +173,12 @@ public: * @param maxWidth the maximum width a line may have * @param lines the string list to which the text lines from str are appended * @param initWidth the starting width of the first line, for partially filled lines (optional) + * @param evenWidthLinesModeEnabled if enabled, the resulting line segments will be close to the same width (optional) + * @param wrapOnExplicitNewLines if enabled, forces wrapping on new line characters, otherwise treats them as single white space (optional) * @return the maximal width of any of the lines added to lines */ - int wordWrapText(const Common::String &str, int maxWidth, Common::Array &lines, int initWidth = 0) const; - int wordWrapText(const Common::U32String &str, int maxWidth, Common::Array &lines, int initWidth = 0) const; + int wordWrapText(const Common::String &str, int maxWidth, Common::Array &lines, int initWidth = 0, bool evenWidthLinesModeEnabled = false, bool wrapOnExplicitNewLines = true) const; + int wordWrapText(const Common::U32String &str, int maxWidth, Common::Array &lines, int initWidth = 0, bool evenWidthLinesModeEnabled = false, bool wrapOnExplicitNewLines = true) const; private: Common::String handleEllipsis(const Common::String &str, int w) const; diff --git a/gui/EventRecorder.cpp b/gui/EventRecorder.cpp index 560df0ec356..0d1acdde271 100644 --- a/gui/EventRecorder.cpp +++ b/gui/EventRecorder.cpp @@ -600,7 +600,7 @@ void EventRecorder::setFileHeader() { return; } TimeDate t; - PlainGameDescriptor desc = EngineMan.findGame(ConfMan.getActiveDomainName()); + QualifiedGameDescriptor desc = EngineMan.findTarget(ConfMan.getActiveDomainName()); g_system->getTimeAndDate(t); if (_author.empty()) { setAuthor("Unknown Author"); @@ -619,9 +619,7 @@ SDL_Surface *EventRecorder::getSurface(int width, int height) { } bool EventRecorder::switchMode() { - const Common::String gameId = ConfMan.get("gameid"); - const Plugin *plugin = nullptr; - EngineMan.findGame(gameId, &plugin); + const Plugin *plugin = EngineMan.findPlugin(ConfMan.get("engineid")); bool metaInfoSupport = plugin->get().hasFeature(MetaEngine::kSavesSupportMetaInfo); bool featuresSupport = metaInfoSupport && g_engine->canSaveGameStateCurrently() && @@ -631,8 +629,10 @@ bool EventRecorder::switchMode() { return false; } + const Common::String target = ConfMan.getActiveDomainName(); + SaveStateList saveList = plugin->get().listSaves(target.c_str()); + int emptySlot = 1; - SaveStateList saveList = plugin->get().listSaves(gameId.c_str()); for (SaveStateList::const_iterator x = saveList.begin(); x != saveList.end(); ++x) { int saveSlot = x->getSaveSlot(); if (saveSlot == 0) { @@ -667,10 +667,9 @@ bool EventRecorder::checkForContinueGame() { void EventRecorder::deleteTemporarySave() { if (_temporarySlot == -1) return; - const Common::String gameId = ConfMan.get("gameid"); - const Plugin *plugin = 0; - EngineMan.findGame(gameId, &plugin); - plugin->get().removeSaveState(gameId.c_str(), _temporarySlot); + const Plugin *plugin = EngineMan.findPlugin(ConfMan.get("engineid")); + const Common::String target = ConfMan.getActiveDomainName(); + plugin->get().removeSaveState(target.c_str(), _temporarySlot); _temporarySlot = -1; } diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index 9a2bf9f8b9e..ea2c96cf577 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -61,10 +61,6 @@ const char *const ThemeEngine::kImageStopSmallButton = "stopbtn_small.bmp"; const char *const ThemeEngine::kImageEditSmallButton = "editbtn_small.bmp"; const char *const ThemeEngine::kImageSwitchModeSmallButton = "switchbtn_small.bmp"; const char *const ThemeEngine::kImageFastReplaySmallButton = "fastreplay_small.bmp"; -const char *const ThemeEngine::kImageDropboxLogo = "dropbox.bmp"; -const char *const ThemeEngine::kImageOneDriveLogo = "onedrive.bmp"; -const char *const ThemeEngine::kImageGoogleDriveLogo = "googledrive.bmp"; -const char *const ThemeEngine::kImageBoxLogo = "box.bmp"; struct TextDrawData { const Graphics::Font *_fontPtr; @@ -130,9 +126,16 @@ static const DrawDataInfo kDrawDataDefaults[] = { {kDDWidgetBackgroundSlider, "widget_slider", kDrawLayerBackground, kDDNone}, {kDDButtonIdle, "button_idle", kDrawLayerBackground, kDDNone}, - {kDDButtonHover, "button_hover", kDrawLayerForeground, kDDButtonIdle}, + {kDDButtonHover, "button_hover", kDrawLayerForeground, kDDButtonIdle}, {kDDButtonDisabled, "button_disabled", kDrawLayerBackground, kDDNone}, - {kDDButtonPressed, "button_pressed", kDrawLayerForeground, kDDButtonIdle}, + {kDDButtonPressed, "button_pressed", kDrawLayerForeground, kDDButtonIdle}, + + {kDDDropDownButtonIdle, "dropdown_button_idle", kDrawLayerBackground, kDDNone}, + {kDDDropDownButtonHoverLeft, "dropdown_button_hover_left", kDrawLayerForeground, kDDDropDownButtonIdle}, + {kDDDropDownButtonHoverRight, "dropdown_button_hover_right", kDrawLayerForeground, kDDDropDownButtonIdle}, + {kDDDropDownButtonDisabled, "dropdown_button_disabled", kDrawLayerForeground, kDDNone}, + {kDDDropDownButtonPressedLeft, "dropdown_button_pressed_left", kDrawLayerForeground, kDDDropDownButtonIdle}, + {kDDDropDownButtonPressedRight, "dropdown_button_pressed_right", kDrawLayerForeground, kDDDropDownButtonIdle}, {kDDSliderFull, "slider_full", kDrawLayerForeground, kDDNone}, {kDDSliderHover, "slider_hover", kDrawLayerForeground, kDDNone}, @@ -869,7 +872,7 @@ void ThemeEngine::drawDD(DrawData type, const Common::Rect &r, uint32 dynamic, b if (drawData->_layer == _layerToDraw) { Common::List::const_iterator step; for (step = drawData->_steps.begin(); step != drawData->_steps.end(); ++step) { - _vectorRenderer->drawStepClip(area, _clip, *step, dynamic); + _vectorRenderer->drawStep(area, _clip, *step, dynamic); } addDirtyRect(extendedRect); @@ -906,23 +909,6 @@ void ThemeEngine::drawDDText(TextData type, TextColor color, const Common::Rect addDirtyRect(dirty); } -void ThemeEngine::drawBitmap(const Graphics::Surface *bitmap, const Common::Rect &r, bool alpha) { - if (_layerToDraw == kDrawLayerBackground) - return; - - Common::Rect area = r; - area.clip(_screen.w, _screen.h); - - if (alpha) - _vectorRenderer->blitKeyBitmapClip(bitmap, area, _clip); - else - _vectorRenderer->blitSubSurfaceClip(bitmap, area, _clip); - - Common::Rect dirtyRect = area; - dirtyRect.clip(_clip); - addDirtyRect(dirtyRect); -} - /********************************************************** * Widget drawing functions *********************************************************/ @@ -946,6 +932,35 @@ void ThemeEngine::drawButton(const Common::Rect &r, const Common::String &str, W _widgets[dd]->_textAlignV); } +void ThemeEngine::drawDropDownButton(const Common::Rect &r, uint32 dropdownWidth, const Common::String &str, + ThemeEngine::WidgetStateInfo buttonState, bool inButton, bool inDropdown) { + if (!ready()) + return; + + DrawData dd; + if (buttonState == kStateHighlight && inButton) + dd = kDDDropDownButtonHoverLeft; + else if (buttonState == kStateHighlight && inDropdown) + dd = kDDDropDownButtonHoverRight; + else if (buttonState == kStateDisabled) + dd = kDDDropDownButtonDisabled; + else if (buttonState == kStatePressed && inButton) + dd = kDDDropDownButtonPressedLeft; + else if (buttonState == kStatePressed && inDropdown) + dd = kDDDropDownButtonPressedRight; + else + dd = kDDDropDownButtonIdle; + + drawDD(dd, r); + + // Center the text in the button without using the area of the drop down button + Common::Rect textRect = r; + textRect.left = r.left + dropdownWidth; + textRect.right = r.right - dropdownWidth; + drawDDText(getTextData(dd), getTextColor(dd), textRect, str, false, true, _widgets[dd]->_textAlignH, + _widgets[dd]->_textAlignV); +} + void ThemeEngine::drawLineSeparator(const Common::Rect &r) { if (!ready()) return; @@ -1034,7 +1049,7 @@ void ThemeEngine::drawScrollbar(const Common::Rect &r, int sliderY, int sliderHe drawDD(kDDScrollbarBase, r); Common::Rect r2 = r; - const int buttonExtra = (r.width() * 120) / 100; + const int buttonExtra = r.width() + 1; // scrollbar.cpp's UP_DOWN_BOX_HEIGHT r2.bottom = r2.top + buttonExtra; drawDD(scrollState == kScrollbarStateUp ? kDDScrollbarButtonHover : kDDScrollbarButtonIdle, r2, @@ -1114,11 +1129,22 @@ void ThemeEngine::drawPopUpWidget(const Common::Rect &r, const Common::String &s } } -void ThemeEngine::drawSurface(const Common::Rect &r, const Graphics::Surface &surface, bool themeTrans) { +void ThemeEngine::drawSurface(const Common::Point &p, const Graphics::Surface &surface, bool themeTrans) { if (!ready()) return; - drawBitmap(&surface, r, themeTrans); + if (_layerToDraw == kDrawLayerBackground) + return; + + _vectorRenderer->setClippingRect(_clip); + if (themeTrans) + _vectorRenderer->blitKeyBitmap(&surface, p); + else + _vectorRenderer->blitSubSurface(&surface, p); + + Common::Rect dirtyRect = Common::Rect(p.x, p.y, p.x + surface.w, p.y + surface.h); + dirtyRect.clip(_clip); + addDirtyRect(dirtyRect); } void ThemeEngine::drawWidgetBackground(const Common::Rect &r, uint16 hints, WidgetBackground background) { @@ -1898,4 +1924,8 @@ Common::Rect ThemeEngine::swapClipRect(const Common::Rect &newRect) { return oldRect; } +void ThemeEngine::disableClipRect() { + _clip = Common::Rect(_screen.w, _screen.h); +} + } // End of namespace GUI. diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h index 0fd7e9ecb5c..db2794cd91b 100644 --- a/gui/ThemeEngine.h +++ b/gui/ThemeEngine.h @@ -37,7 +37,7 @@ #include "graphics/pixelformat.h" -#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.27" +#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.28" class OSystem; @@ -80,6 +80,13 @@ enum DrawData { kDDButtonDisabled, kDDButtonPressed, + kDDDropDownButtonIdle, + kDDDropDownButtonHoverLeft, + kDDDropDownButtonHoverRight, + kDDDropDownButtonDisabled, + kDDDropDownButtonPressedLeft, + kDDDropDownButtonPressedRight, + kDDSliderFull, kDDSliderHover, kDDSliderDisabled, @@ -263,10 +270,6 @@ public: static const char *const kImageEditSmallButton; ///< Edit recording metadata in recorder onscreen dialog (for 320xY) static const char *const kImageSwitchModeSmallButton; ///< Switch mode button in recorder onscreen dialog (for 320xY) static const char *const kImageFastReplaySmallButton; ///< Fast playback mode button in recorder onscreen dialog (for 320xY) - static const char *const kImageDropboxLogo; ///< Dropbox logo used in the StorageWizardDialog - static const char *const kImageOneDriveLogo; ///< OneDrive logo used in the StorageWizardDialog - static const char *const kImageGoogleDriveLogo; ///< Google Drive logo used in the StorageWizardDialog - static const char *const kImageBoxLogo; ///< Box logo used in the StorageWizardDialog /** * Graphics mode enumeration. @@ -391,6 +394,11 @@ public: */ Common::Rect swapClipRect(const Common::Rect &newRect); + /** + * Set the clipping rect to allow rendering on the whole surface. + */ + void disableClipRect(); + /** @name WIDGET DRAWING METHODS */ //@{ @@ -399,7 +407,10 @@ public: void drawButton(const Common::Rect &r, const Common::String &str, WidgetStateInfo state = kStateEnabled, uint16 hints = 0); - void drawSurface(const Common::Rect &r, const Graphics::Surface &surface, bool themeTrans = false); + void drawDropDownButton(const Common::Rect &r, uint32 dropdownWidth, const Common::String &str, + WidgetStateInfo buttonState, bool inButton, bool inDropdown); + + void drawSurface(const Common::Point &p, const Graphics::Surface &surface, bool themeTrans = false); void drawSlider(const Common::Rect &r, int width, WidgetStateInfo state = kStateEnabled); @@ -637,7 +648,6 @@ protected: bool elipsis, Graphics::TextAlign alignH = Graphics::kTextAlignLeft, TextAlignVertical alignV = kTextAlignVTop, int deltax = 0, const Common::Rect &drawableTextArea = Common::Rect(0, 0, 0, 0)); - void drawBitmap(const Graphics::Surface *bitmap, const Common::Rect &clippingRect, bool alpha); /** * DEBUG: Draws a white square and writes some text next to it. diff --git a/gui/ThemeLayout.cpp b/gui/ThemeLayout.cpp index 71e4b2c9fdf..a05ac8797e3 100644 --- a/gui/ThemeLayout.cpp +++ b/gui/ThemeLayout.cpp @@ -181,6 +181,7 @@ void ThemeLayoutStacked::reflowLayoutVertical() { int curX, curY; int resize[8]; int rescount = 0; + bool fixedWidth = _w != -1; curX = _padding.left; curY = _padding.top; @@ -203,7 +204,7 @@ void ThemeLayoutStacked::reflowLayoutVertical() { _children[i]->offsetY(curY); // Center child if it this has been requested *and* the space permits it. - if (_centered && _children[i]->getWidth() < _w && _w != -1) { + if (_centered && _children[i]->getWidth() < (_w - _padding.left - _padding.right) && _w != -1) { _children[i]->offsetX((_w >> 1) - (_children[i]->getWidth() >> 1)); } else _children[i]->offsetX(curX); @@ -213,7 +214,9 @@ void ThemeLayoutStacked::reflowLayoutVertical() { curY += _children[i]->getHeight() + _spacing; // Update width and height of this stack layout - _w = MAX(_w, (int16)(_children[i]->getWidth() + _padding.left + _padding.right)); + if (!fixedWidth) { + _w = MAX(_w, (int16)(_children[i]->getWidth() + _padding.left + _padding.right)); + } _h += _children[i]->getHeight() + _spacing; } @@ -244,6 +247,7 @@ void ThemeLayoutStacked::reflowLayoutHorizontal() { int curX, curY; int resize[8]; int rescount = 0; + bool fixedHeight = _h != -1; curX = _padding.left; curY = _padding.top; @@ -266,7 +270,7 @@ void ThemeLayoutStacked::reflowLayoutHorizontal() { _children[i]->offsetX(curX); // Center child if it this has been requested *and* the space permits it. - if (_centered && _children[i]->getHeight() < _h && _h != -1) + if (_centered && _children[i]->getHeight() < (_h - _padding.top - _padding.bottom) && _h != -1) _children[i]->offsetY((_h >> 1) - (_children[i]->getHeight() >> 1)); else _children[i]->offsetY(curY); @@ -277,7 +281,9 @@ void ThemeLayoutStacked::reflowLayoutHorizontal() { // Update width and height of this stack layout _w += _children[i]->getWidth() + _spacing; - _h = MAX(_h, (int16)(_children[i]->getHeight() + _padding.top + _padding.bottom)); + if (!fixedHeight) { + _h = MAX(_h, (int16)(_children[i]->getHeight() + _padding.top + _padding.bottom)); + } } // If there are any children at all, then we added the spacing value once diff --git a/gui/ThemeParser.cpp b/gui/ThemeParser.cpp index bf62bcc792c..56d89319b17 100644 --- a/gui/ThemeParser.cpp +++ b/gui/ThemeParser.cpp @@ -631,6 +631,17 @@ bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawst } } + if (stepNode->values.contains("clip")) { + val = stepNode->values["clip"]; + int cl, ct, cr, cb; + if (parseIntegerKey(val, 4, &cl, &ct, &cr, &cb)) { + drawstep->clip.left = cl; + drawstep->clip.top = ct; + drawstep->clip.right = cr; + drawstep->clip.bottom = cb; + } + } + #undef PARSER_ASSIGN_INT #undef PARSER_ASSIGN_RGB diff --git a/gui/ThemeParser.h b/gui/ThemeParser.h index 155731467f7..f55a24aa80f 100644 --- a/gui/ThemeParser.h +++ b/gui/ThemeParser.h @@ -147,6 +147,7 @@ protected: XML_PROP(orientation, false) XML_PROP(file, false) XML_PROP(autoscale, false) + XML_PROP(clip, false) KEY_END() XML_KEY(text) diff --git a/gui/Tooltip.cpp b/gui/Tooltip.cpp index 50f10272fb3..dfa1d54ec72 100644 --- a/gui/Tooltip.cpp +++ b/gui/Tooltip.cpp @@ -49,8 +49,8 @@ void Tooltip::setup(Dialog *parent, Widget *widget, int x, int y) { const Graphics::Font *tooltipFont = g_gui.theme()->getFont(ThemeEngine::kFontStyleTooltip); _wrappedLines.clear(); - _w = tooltipFont->wordWrapText(widget->getTooltip(), _maxWidth - 4, _wrappedLines); - _h = (tooltipFont->getFontHeight() + 2) * _wrappedLines.size(); + _w = tooltipFont->wordWrapText(widget->getTooltip(), _maxWidth - 4, _wrappedLines) + 4; + _h = (tooltipFont->getFontHeight() + 2) * _wrappedLines.size() + 4; _x = MIN(parent->_x + x + _xdelta, g_gui.getWidth() - _w - 3); _y = MIN(parent->_y + y + _ydelta, g_gui.getHeight() - _h - 3); @@ -62,9 +62,11 @@ void Tooltip::drawDialog(DrawLayer layerToDraw) { Dialog::drawDialog(layerToDraw); + int16 textX = _x + 3; // including 2px padding and 1px original code shift + int16 textY = _y + 3; for (Common::StringArray::const_iterator i = _wrappedLines.begin(); i != _wrappedLines.end(); ++i, ++num) { g_gui.theme()->drawText( - Common::Rect(_x + 1, _y + 1 + num * h, _x + 1 + _w, _y + 1 + (num + 1) * h), + Common::Rect(textX, textY + num * h, textX + _w, textY + (num + 1) * h), *i, ThemeEngine::kStateEnabled, Graphics::kTextAlignLeft, diff --git a/gui/console.cpp b/gui/console.cpp index 79df4135344..a47f5b9afd7 100644 --- a/gui/console.cpp +++ b/gui/console.cpp @@ -523,7 +523,7 @@ void ConsoleDialog::specialKeys(Common::KeyCode keycode) { g_gui.scheduleTopDialogRedraw(); break; case Common::KEYCODE_v: - if (g_system->hasFeature(OSystem::kFeatureClipboardSupport) && g_system->hasTextInClipboard()) { + if (g_system->hasTextInClipboard()) { Common::String text = g_system->getTextFromClipboard(); insertIntoPrompt(text.c_str()); scrollToCurrent(); @@ -531,7 +531,7 @@ void ConsoleDialog::specialKeys(Common::KeyCode keycode) { } break; case Common::KEYCODE_c: - if (g_system->hasFeature(OSystem::kFeatureClipboardSupport)) { + { Common::String userInput = getUserInput(); if (!userInput.empty()) g_system->setTextInClipboard(userInput); diff --git a/gui/debugger.cpp b/gui/debugger.cpp index 43f600922ad..2e8ae1ca013 100644 --- a/gui/debugger.cpp +++ b/gui/debugger.cpp @@ -139,7 +139,7 @@ void Debugger::debugPrintColumns(const Common::StringArray &list) { for (j = 0; j < columns; j++) { uint pos = i + j * lines; if (pos < list.size()) { - debugPrintf("%*s", -columnWidth, list[pos].c_str()); + debugPrintf("%*s", -1 * columnWidth, list[pos].c_str()); } } debugPrintf("\n"); diff --git a/gui/dialog.cpp b/gui/dialog.cpp index 781de330e27..a1d69b7c77c 100644 --- a/gui/dialog.cpp +++ b/gui/dialog.cpp @@ -163,6 +163,7 @@ void Dialog::drawDialog(DrawLayer layerToDraw) { if (!isVisible()) return; + g_gui.theme()->disableClipRect(); g_gui.theme()->_layerToDraw = layerToDraw; g_gui.theme()->drawDialogBackground(Common::Rect(_x, _y, _x + _w, _y + _h), _backgroundType); diff --git a/gui/downloaddialog.cpp b/gui/downloaddialog.cpp index 0ce52f7f8af..8092d3d5164 100644 --- a/gui/downloaddialog.cpp +++ b/gui/downloaddialog.cpp @@ -24,6 +24,7 @@ #include "backends/cloud/cloudmanager.h" #include "common/config-manager.h" #include "common/translation.h" +#include "common/util.h" #include "engines/metaengine.h" #include "gui/browser.h" #include "gui/chooser.h" @@ -207,43 +208,6 @@ void DownloadDialog::reflowLayout() { refreshWidgets(); } -namespace { -Common::String getHumanReadableBytes(uint64 bytes, Common::String &unitsOut) { - Common::String result = Common::String::format("%lu", bytes); - unitsOut = "B"; - - if (bytes >= 1024) { - bytes /= 1024; - result = Common::String::format("%lu", bytes); - unitsOut = "KB"; - } - - double floating = bytes; - - if (bytes >= 1024) { - bytes /= 1024; - floating /= 1024.0; - unitsOut = "MB"; - } - - if (bytes >= 1024) { - bytes /= 1024; - floating /= 1024.0; - unitsOut = "GB"; - } - - if (bytes >= 1024) { // woah - bytes /= 1024; - floating /= 1024.0; - unitsOut = "TB"; - } - - // print one digit after floating point - result = Common::String::format("%.1f", floating); - return result; -} -} - Common::String DownloadDialog::getSizeLabelText() { Common::String downloaded, downloadedUnits, total, totalUnits; downloaded = getHumanReadableBytes(CloudMan.getDownloadBytesNumber(), downloadedUnits); diff --git a/gui/editgamedialog.cpp b/gui/editgamedialog.cpp index ac030d7678d..1b34a4753d3 100644 --- a/gui/editgamedialog.cpp +++ b/gui/editgamedialog.cpp @@ -100,16 +100,14 @@ protected: EditGameDialog::EditGameDialog(const String &domain) : OptionsDialog(domain, "GameOptions") { + EngineMan.upgradeTargetIfNecessary(domain); + // Retrieve all game specific options. - const Plugin *plugin = nullptr; - // To allow for game domains without a gameid. - // TODO: Is it intentional that this is still supported? - String gameId(ConfMan.get("gameid", domain)); - if (gameId.empty()) - gameId = domain; + // Retrieve the plugin, since we need to access the engine's MetaEngine // implementation. - PlainGameDescriptor pgd = EngineMan.findGame(gameId, &plugin); + const Plugin *plugin = nullptr; + QualifiedGameDescriptor qgd = EngineMan.findTarget(domain, &plugin); if (plugin) { _engineOptions = plugin->get().getExtraGuiOptions(domain); } else { @@ -123,8 +121,8 @@ EditGameDialog::EditGameDialog(const String &domain) // GAME: Determine the description string String description(ConfMan.get("description", domain)); - if (description.empty() && pgd.description) { - description = pgd.description; + if (description.empty() && qgd.description) { + description = qgd.description; } // GUI: Add tab widget diff --git a/gui/launcher.cpp b/gui/launcher.cpp index 81ae339822a..22732526834 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -66,9 +66,11 @@ enum { kAboutCmd = 'ABOU', kOptionsCmd = 'OPTN', kAddGameCmd = 'ADDG', + kMassAddGameCmd = 'MADD', kEditGameCmd = 'EDTG', kRemoveGameCmd = 'REMG', kLoadGameCmd = 'LOAD', + kRecordGameCmd = 'RECG', kQuitCmd = 'QUIT', kSearchCmd = 'SRCH', kListSearchCmd = 'LSSR', @@ -145,20 +147,30 @@ void LauncherDialog::build() { _startButton = new ButtonWidget(this, "Launcher.StartButton", _("~S~tart"), _("Start selected game"), kStartCmd); - _loadButton = - new ButtonWidget(this, "Launcher.LoadGameButton", _("~L~oad..."), _("Load saved game for selected game"), kLoadGameCmd); + DropdownButtonWidget *loadButton = + new DropdownButtonWidget(this, "Launcher.LoadGameButton", _("~L~oad..."), _("Load saved game for selected game"), kLoadGameCmd); +#ifdef ENABLE_EVENTRECORDER + loadButton->appendEntry(_s("Record..."), kRecordGameCmd); +#endif + _loadButton = loadButton; // Above the lowest button rows: two more buttons (directly below the list box) if (g_system->getOverlayWidth() > 320) { - _addButton = - new ButtonWidget(this, "Launcher.AddGameButton", _("~A~dd Game..."), _("Hold Shift for Mass Add"), kAddGameCmd); + DropdownButtonWidget *addButton = + new DropdownButtonWidget(this, "Launcher.AddGameButton", _("~A~dd Game..."), _("Add games to the list"), kAddGameCmd); + addButton->appendEntry(_s("Mass Add..."), kMassAddGameCmd); + _addButton = addButton; + _editButton = new ButtonWidget(this, "Launcher.EditGameButton", _("~E~dit Game..."), _("Change game options"), kEditGameCmd); _removeButton = new ButtonWidget(this, "Launcher.RemoveGameButton", _("~R~emove Game"), _("Remove game from the list. The game data files stay intact"), kRemoveGameCmd); } else { - _addButton = - new ButtonWidget(this, "Launcher.AddGameButton", _c("~A~dd Game...", "lowres"), _("Hold Shift for Mass Add"), kAddGameCmd); + DropdownButtonWidget *addButton = + new DropdownButtonWidget(this, "Launcher.AddGameButton", _c("~A~dd Game...", "lowres"), _("Add games to the list"), kAddGameCmd); + addButton->appendEntry(_c("Mass Add...", "lowres"), kMassAddGameCmd); + _addButton = addButton; + _editButton = new ButtonWidget(this, "Launcher.EditGameButton", _c("~E~dit Game...", "lowres"), _("Change game options"), kEditGameCmd); _removeButton = @@ -269,8 +281,9 @@ void LauncherDialog::updateListing() { if (gameid.empty()) gameid = iter->_key; + if (description.empty()) { - PlainGameDescriptor g = EngineMan.findGame(gameid); + QualifiedGameDescriptor g = EngineMan.findTarget(iter->_key); if (g.description) description = g.description; } @@ -317,38 +330,6 @@ void LauncherDialog::updateListing() { } void LauncherDialog::addGame() { - -#ifndef DISABLE_MASS_ADD - const bool massAdd = checkModifier(Common::KBD_SHIFT); - - if (massAdd) { - MessageDialog alert(_("Do you really want to run the mass game detector? " - "This could potentially add a huge number of games."), _("Yes"), _("No")); - if (alert.runModal() == GUI::kMessageOK && _browser->runModal() > 0) { - MassAddDialog massAddDlg(_browser->getResult()); - - massAddDlg.runModal(); - - // Update the ListWidget and force a redraw - - // If new target(s) were added, update the ListWidget and move - // the selection to to first newly detected game. - Common::String newTarget = massAddDlg.getFirstAddedTarget(); - if (!newTarget.empty()) { - updateListing(); - selectTarget(newTarget); - } - - g_gui.scheduleTopDialogRedraw(); - } - - // We need to update the buttons here, so "Mass add" will revert to "Add game" - // without any additional event. - updateButtons(); - return; - } -#endif - // Allow user to add a new game to the list. // 1) show a dir selection dialog which lets the user pick the directory // the game data resides in. @@ -391,6 +372,28 @@ void LauncherDialog::addGame() { } while (looping); } +void LauncherDialog::massAddGame() { + MessageDialog alert(_("Do you really want to run the mass game detector? " + "This could potentially add a huge number of games."), _("Yes"), _("No")); + if (alert.runModal() == GUI::kMessageOK && _browser->runModal() > 0) { + MassAddDialog massAddDlg(_browser->getResult()); + + massAddDlg.runModal(); + + // Update the ListWidget and force a redraw + + // If new target(s) were added, update the ListWidget and move + // the selection to to first newly detected game. + Common::String newTarget = massAddDlg.getFirstAddedTarget(); + if (!newTarget.empty()) { + updateListing(); + selectTarget(newTarget); + } + + g_gui.scheduleTopDialogRedraw(); + } +} + void LauncherDialog::removeGame(int item) { MessageDialog alert(_("Do you really want to remove this game configuration?"), _("Yes"), _("No")); @@ -416,9 +419,6 @@ void LauncherDialog::editGame(int item) { // This is useful because e.g. MonkeyVGA needs AdLib music to have decent // music support etc. assert(item >= 0); - String gameId(ConfMan.get("gameid", _domains[item])); - if (gameId.empty()) - gameId = _domains[item]; EditGameDialog editDialog(_domains[item]); if (editDialog.runModal() > 0) { @@ -434,20 +434,6 @@ void LauncherDialog::editGame(int item) { } } -void LauncherDialog::loadGameButtonPressed(int item) { -#ifdef ENABLE_EVENTRECORDER - const bool shiftPressed = checkModifier(Common::KBD_SHIFT); - if (shiftPressed) { - recordGame(item); - } else { - loadGame(item); - } - updateButtons(); -#else - loadGame(item); -#endif -} - #ifdef ENABLE_EVENTRECORDER void LauncherDialog::recordGame(int item) { RecorderDialog recorderDialog; @@ -478,17 +464,15 @@ void LauncherDialog::recordGame(int item) { #endif void LauncherDialog::loadGame(int item) { - String gameId = ConfMan.get("gameid", _domains[item]); - if (gameId.empty()) - gameId = _domains[item]; - - const Plugin *plugin = nullptr; - - EngineMan.findGame(gameId, &plugin); - String target = _domains[item]; target.toLowercase(); + EngineMan.upgradeTargetIfNecessary(target); + + // Look for the plugin + const Plugin *plugin = nullptr; + EngineMan.findTarget(target, &plugin); + if (plugin) { const MetaEngine &metaEngine = plugin->get(); if (metaEngine.hasFeature(MetaEngine::kSupportsListSaves) && @@ -642,6 +626,9 @@ void LauncherDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat case kAddGameCmd: addGame(); break; + case kMassAddGameCmd: + massAddGame(); + break; case kRemoveGameCmd: removeGame(item); break; @@ -649,8 +636,13 @@ void LauncherDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat editGame(item); break; case kLoadGameCmd: - loadGameButtonPressed(item); + loadGame(item); break; +#ifdef ENABLE_EVENTRECORDER + case kRecordGameCmd: + recordGame(item); + break; +#endif case kOptionsCmd: { GlobalOptionsDialog options(this); options.runModal(); @@ -719,28 +711,8 @@ void LauncherDialog::updateButtons() { _loadButton->setEnabled(en); _loadButton->markAsDirty(); } - switchButtonsText(_addButton, "~A~dd Game...", _s("Mass Add...")); -#ifdef ENABLE_EVENTRECORDER - switchButtonsText(_loadButton, "~L~oad...", _s("Record...")); -#endif } -// Update the label of the button depending on whether shift is pressed or not -void LauncherDialog::switchButtonsText(ButtonWidget *button, const char *normalText, const char *shiftedText) { - const bool shiftPressed = checkModifier(Common::KBD_SHIFT); - const bool lowRes = g_system->getOverlayWidth() <= 320; - - const char *newAddButtonLabel = shiftPressed - ? (lowRes ? _c(shiftedText, "lowres") : _(shiftedText)) - : (lowRes ? _c(normalText, "lowres") : _(normalText)); - - if (button->getLabel() != newAddButtonLabel) - button->setLabel(newAddButtonLabel); -} - - - - void LauncherDialog::reflowLayout() { #ifndef DISABLE_FANCY_THEMES if (g_gui.xmlEval()->getVar("Globals.ShowLauncherLogo") == 1 && g_gui.theme()->supportsImages()) { diff --git a/gui/launcher.h b/gui/launcher.h index 5bb386f9a04..7009b993f2c 100644 --- a/gui/launcher.h +++ b/gui/launcher.h @@ -82,7 +82,6 @@ protected: void updateListing(); void updateButtons(); - void switchButtonsText(ButtonWidget *button, const char *normalText, const char *shiftedText); void build(); void clean(); @@ -94,6 +93,7 @@ protected: * Handle "Add game..." button. */ virtual void addGame(); + void massAddGame(); /** * Handle "Remove game..." button. @@ -105,11 +105,6 @@ protected: */ void editGame(int item); - /** - * Facade for "Load..."/"Record..." buttons. - */ - void loadGameButtonPressed(int item); - /** * Handle "Record..." button. */ diff --git a/gui/massadd.cpp b/gui/massadd.cpp index f4d857a528d..1d1d1193036 100644 --- a/gui/massadd.cpp +++ b/gui/massadd.cpp @@ -207,7 +207,7 @@ void MassAddDialog::handleTickle() { while (path != "/" && path.lastChar() == '/') path.deleteLastChar(); - // Check for existing config entries for this path/gameid/lang/platform combination + // Check for existing config entries for this path/engineid/gameid/lang/platform combination if (_pathToTargets.contains(path)) { Common::String resultPlatformCode = Common::getPlatformCode(result.platform); Common::String resultLanguageCode = Common::getLanguageCode(result.language); @@ -215,11 +215,12 @@ void MassAddDialog::handleTickle() { bool duplicate = false; const StringArray &targets = _pathToTargets[path]; for (StringArray::const_iterator iter = targets.begin(); iter != targets.end(); ++iter) { - // If the gameid, platform and language match -> skip it + // If the engineid, gameid, platform and language match -> skip it Common::ConfigManager::Domain *dom = ConfMan.getDomain(*iter); assert(dom); - if ((*dom)["gameid"] == result.gameId && + if ((*dom)["engineid"] == result.engineId && + (*dom)["gameid"] == result.gameId && (*dom)["platform"] == resultPlatformCode && (*dom)["language"] == resultLanguageCode) { duplicate = true; diff --git a/gui/module.mk b/gui/module.mk index 87f8dec3b23..799c4e7d61a 100644 --- a/gui/module.mk +++ b/gui/module.mk @@ -43,8 +43,7 @@ ifdef USE_CLOUD ifdef USE_LIBCURL MODULE_OBJS += \ downloaddialog.o \ - remotebrowser.o \ - storagewizarddialog.o + remotebrowser.o endif endif diff --git a/gui/options.cpp b/gui/options.cpp index 53a47d01ad6..1d2aafc553f 100644 --- a/gui/options.cpp +++ b/gui/options.cpp @@ -38,6 +38,7 @@ #include "common/textconsole.h" #include "common/translation.h" #include "common/updates.h" +#include "common/util.h" #include "audio/mididrv.h" #include "audio/musicplugin.h" @@ -50,7 +51,6 @@ #ifdef USE_LIBCURL #include "backends/cloud/cloudmanager.h" #include "gui/downloaddialog.h" -#include "gui/storagewizarddialog.h" #endif #ifdef USE_SDL_NET @@ -107,14 +107,18 @@ enum { #ifdef USE_CLOUD enum { - kConfigureStorageCmd = 'cfst', - kRefreshStorageCmd = 'rfst', + kSyncSavesStorageCmd = 'ssst', kDownloadStorageCmd = 'dlst', kRunServerCmd = 'rnsv', kCloudTabContainerReflowCmd = 'ctcr', kServerPortClearCmd = 'spcl', kChooseRootDirCmd = 'chrp', - kRootPathClearCmd = 'clrp' + kRootPathClearCmd = 'clrp', + kConnectStorageCmd = 'Cnnt', + kOpenUrlStorageCmd = 'OpUr', + kPasteCodeStorageCmd = 'PsCd', + kDisconnectStorageCmd = 'DcSt', + kEnableStorageCmd = 'EnSt' }; #endif @@ -317,13 +321,13 @@ void OptionsDialog::build() { } #endif -#ifdef GUI_ONLY_FULLSCREEN - _fullscreenCheckbox->setState(true); - _fullscreenCheckbox->setEnabled(false); -#else // !GUI_ONLY_FULLSCREEN // Fullscreen setting - _fullscreenCheckbox->setState(ConfMan.getBool("fullscreen", _domain)); -#endif // GUI_ONLY_FULLSCREEN + if (g_system->hasFeature(OSystem::kFeatureFullscreenMode)) { + _fullscreenCheckbox->setState(ConfMan.getBool("fullscreen", _domain)); + } else { + _fullscreenCheckbox->setState(true); + _fullscreenCheckbox->setEnabled(false); + } // Filtering setting if (g_system->hasFeature(OSystem::kFeatureFilteringMode)) @@ -808,7 +812,7 @@ void OptionsDialog::apply() { } void OptionsDialog::close() { - if (getResult()) + if (getResult() > 0) apply(); Dialog::close(); @@ -923,18 +927,17 @@ void OptionsDialog::setGraphicSettingsState(bool enabled) { _filteringCheckbox->setEnabled(enabled); #endif #ifndef GUI_ENABLE_KEYSDIALOG -#ifndef GUI_ONLY_FULLSCREEN - _fullscreenCheckbox->setEnabled(enabled); -#endif // !GUI_ONLY_FULLSCREEN + + if (g_system->hasFeature(OSystem::kFeatureFullscreenMode)) + _fullscreenCheckbox->setEnabled(enabled); + else + _fullscreenCheckbox->setEnabled(false); + if (_guioptions.contains(GUIO_NOASPECT)) _aspectCheckbox->setEnabled(false); else _aspectCheckbox->setEnabled(enabled); #endif // !GUI_ENABLE_KEYSDIALOG - // ResidualVM specific: - _vsyncCheckbox->setEnabled(enabled); - _rendererTypePopUp->setEnabled(enabled); - _antiAliasPopUp->setEnabled(enabled); } void OptionsDialog::setAudioSettingsState(bool enabled) { @@ -1542,7 +1545,7 @@ void OptionsDialog::setupGraphicsTab() { GlobalOptionsDialog::GlobalOptionsDialog(LauncherDialog *launcher) - : OptionsDialog(Common::ConfigManager::kApplicationDomain, "GlobalOptions"), _launcher(launcher) { + : OptionsDialog(Common::ConfigManager::kApplicationDomain, "GlobalOptions"), CommandSender(nullptr), _launcher(launcher) { #ifdef GUI_ENABLE_KEYSDIALOG _keysDialog = 0; #endif @@ -1574,20 +1577,35 @@ GlobalOptionsDialog::GlobalOptionsDialog(LauncherDialog *launcher) #ifdef USE_CLOUD #ifdef USE_LIBCURL _selectedStorageIndex = CloudMan.getStorageIndex(); -#else - _selectedStorageIndex = 0; -#endif _storagePopUpDesc = 0; _storagePopUp = 0; + _storageDisabledHint = 0; + _storageEnableButton = 0; _storageUsernameDesc = 0; _storageUsername = 0; _storageUsedSpaceDesc = 0; _storageUsedSpace = 0; + _storageSyncHint = 0; _storageLastSyncDesc = 0; _storageLastSync = 0; - _storageConnectButton = 0; - _storageRefreshButton = 0; + _storageSyncSavesButton = 0; + _storageDownloadHint = 0; _storageDownloadButton = 0; + _storageDisconnectHint = 0; + _storageDisconnectButton = 0; + + _connectingStorage = false; + _storageWizardNotConnectedHint = 0; + _storageWizardOpenLinkHint = 0; + _storageWizardLink = 0; + _storageWizardCodeHint = 0; + _storageWizardCodeBox = 0; + _storageWizardPasteButton = 0; + _storageWizardConnectButton = 0; + _storageWizardConnectionStatusHint = 0; + _redrawCloudTab = false; +#endif +#ifdef USE_SDL_NET _runServerButton = 0; _serverInfoLabel = 0; _rootPathButton = 0; @@ -1596,8 +1614,8 @@ GlobalOptionsDialog::GlobalOptionsDialog(LauncherDialog *launcher) _serverPortDesc = 0; _serverPort = 0; _serverPortClearButton = 0; - _redrawCloudTab = false; -#ifdef USE_SDL_NET + _featureDescriptionLine1 = 0; + _featureDescriptionLine2 = 0; _serverWasRunning = false; #endif #endif @@ -1710,10 +1728,10 @@ void GlobalOptionsDialog::build() { _themePathClearButton = addClearButton(tab, "GlobalOptions_Paths.ThemePathClearButton", kThemePathClearCmd); if (g_system->getOverlayWidth() > 320) - new ButtonWidget(tab, "GlobalOptions_Paths.ExtraButton", _("Extra Path:"), _("Specifies path to additional data used by all games or ScummVM"), kChooseExtraDirCmd); + new ButtonWidget(tab, "GlobalOptions_Paths.ExtraButton", _("Extra Path:"), _("Specifies path to additional data used by all games or ResidualVM"), kChooseExtraDirCmd); else - new ButtonWidget(tab, "GlobalOptions_Paths.ExtraButton", _c("Extra Path:", "lowres"), _("Specifies path to additional data used by all games or ScummVM"), kChooseExtraDirCmd); - _extraPath = new StaticTextWidget(tab, "GlobalOptions_Paths.ExtraPath", _c("None", "path"), _("Specifies path to additional data used by all games or ScummVM")); + new ButtonWidget(tab, "GlobalOptions_Paths.ExtraButton", _c("Extra Path:", "lowres"), _("Specifies path to additional data used by all games or ResidualVM"), kChooseExtraDirCmd); + _extraPath = new StaticTextWidget(tab, "GlobalOptions_Paths.ExtraPath", _c("None", "path"), _("Specifies path to additional data used by all games or ResidualVM")); _extraPathClearButton = addClearButton(tab, "GlobalOptions_Paths.ExtraPathClearButton", kExtraPathClearCmd); @@ -1831,8 +1849,9 @@ void GlobalOptionsDialog::build() { #endif #ifdef USE_CLOUD +#ifdef USE_LIBCURL // - // 7) The cloud tab + // 7) The Cloud tab (remote storages) // if (g_system->getOverlayWidth() > 320) tab->addTab(_("Cloud")); @@ -1842,53 +1861,20 @@ void GlobalOptionsDialog::build() { ScrollContainerWidget *container = new ScrollContainerWidget(tab, "GlobalOptions_Cloud.Container", kCloudTabContainerReflowCmd); container->setTarget(this); container->setBackgroundType(ThemeEngine::kDialogBackgroundNone); + setTarget(container); - _storagePopUpDesc = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StoragePopupDesc", _("Storage:"), _("Active cloud storage")); - _storagePopUp = new PopUpWidget(container, "GlobalOptions_Cloud_Container.StoragePopup"); -#ifdef USE_LIBCURL - Common::StringArray list = CloudMan.listStorages(); - for (uint32 i = 0; i < list.size(); ++i) - _storagePopUp->appendEntry(list[i], i); -#else - _storagePopUp->appendEntry(_(""), 0); -#endif - _storagePopUp->setSelected(_selectedStorageIndex); - - _storageUsernameDesc = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageUsernameDesc", _("Username:"), _("Username used by this storage")); - _storageUsername = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageUsernameLabel", ""); - - _storageUsedSpaceDesc = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageUsedSpaceDesc", _("Used space:"), _("Space used by ScummVM's saved games on this storage")); - _storageUsedSpace = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageUsedSpaceLabel", "0 bytes"); - - _storageLastSyncDesc = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageLastSyncDesc", _("Last sync time:"), _("When the last saved games sync for this storage occured")); - _storageLastSync = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageLastSyncLabel", ""); - - _storageConnectButton = new ButtonWidget(container, "GlobalOptions_Cloud_Container.ConnectButton", _("Connect"), _("Open wizard dialog to connect your cloud storage account"), kConfigureStorageCmd); - _storageRefreshButton = new ButtonWidget(container, "GlobalOptions_Cloud_Container.RefreshButton", _("Refresh"), _("Refresh current cloud storage information (username and usage)"), kRefreshStorageCmd); - _storageDownloadButton = new ButtonWidget(container, "GlobalOptions_Cloud_Container.DownloadButton", _("Download"), _("Open downloads manager dialog"), kDownloadStorageCmd); - - _runServerButton = new ButtonWidget(container, "GlobalOptions_Cloud_Container.RunServerButton", _("Run server"), _("Run local webserver"), kRunServerCmd); - _serverInfoLabel = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.ServerInfoLabel", _("Not running")); - - // Root path - if (g_system->getOverlayWidth() > 320) - _rootPathButton = new ButtonWidget(container, "GlobalOptions_Cloud_Container.RootPathButton", _("/root/ Path:"), _("Specifies which directory the Files Manager can access"), kChooseRootDirCmd); - else - _rootPathButton = new ButtonWidget(container, "GlobalOptions_Cloud_Container.RootPathButton", _c("/root/ Path:", "lowres"), _("Specifies which directory the Files Manager can access"), kChooseRootDirCmd); - _rootPath = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.RootPath", "/foo/bar", _("Specifies which directory the Files Manager can access")); - - _rootPathClearButton = addClearButton(container, "GlobalOptions_Cloud_Container.RootPathClearButton", kRootPathClearCmd); - + addCloudControls(container, "GlobalOptions_Cloud_Container.", g_system->getOverlayWidth() <= 320); +#endif // USE_LIBCURL #ifdef USE_SDL_NET - uint32 port = Networking::LocalWebserver::getPort(); -#else - uint32 port = 0; // the following widgets are hidden anyway -#endif - _serverPortDesc = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.ServerPortDesc", _("Server's port:"), _("Which port is used by the server\nAuth with server is not available with non-default port")); - _serverPort = new EditTextWidget(container, "GlobalOptions_Cloud_Container.ServerPortEditText", Common::String::format("%u", port), 0); - _serverPortClearButton = addClearButton(container, "GlobalOptions_Cloud_Container.ServerPortClearButton", kServerPortClearCmd); - - setupCloudTab(); + // + // 8) The LAN tab (local "cloud" webserver) + // + if (g_system->getOverlayWidth() > 320) + tab->addTab(_("LAN")); + else + tab->addTab(_c("LAN", "lowres")); + addNetworkControls(tab, "GlobalOptions_Network.", g_system->getOverlayWidth() <= 320); +#endif // USE_SDL_NET #endif // USE_CLOUD // Activate the first tab @@ -1958,6 +1944,7 @@ void GlobalOptionsDialog::build() { _rendererPopUp->setSelectedTag(mode); #ifdef USE_CLOUD +#ifdef USE_SDL_NET Common::String rootPath(ConfMan.get("rootpath", "cloud")); if (rootPath.empty() || !ConfMan.hasKey("rootpath", "cloud")) { _rootPath->setLabel(_c("None", "path")); @@ -1965,6 +1952,7 @@ void GlobalOptionsDialog::build() { _rootPath->setLabel(rootPath); } #endif +#endif } void GlobalOptionsDialog::clean() { @@ -1981,6 +1969,100 @@ void GlobalOptionsDialog::clean() { OptionsDialog::clean(); } +#ifdef USE_CLOUD +#ifdef USE_LIBCURL +void GlobalOptionsDialog::addCloudControls(GuiObject *boss, const Common::String &prefix, bool lowres) { + _storagePopUpDesc = new StaticTextWidget(boss, prefix + "StoragePopupDesc", _("Active storage:"), _("Active cloud storage")); + _storagePopUp = new PopUpWidget(boss, prefix + "StoragePopup"); + Common::StringArray list = CloudMan.listStorages(); + for (uint32 i = 0; i < list.size(); ++i) + _storagePopUp->appendEntry(list[i], i); + _storagePopUp->setSelected(_selectedStorageIndex); + + if (lowres) + _storageDisabledHint = new StaticTextWidget(boss, prefix + "StorageDisabledHint", _c("4. Storage is not yet enabled. Verify that username is correct and enable it:", "lowres")); + else + _storageDisabledHint = new StaticTextWidget(boss, prefix + "StorageDisabledHint", _("4. Storage is not yet enabled. Verify that username is correct and enable it:")); + _storageEnableButton = new ButtonWidget(boss, prefix + "StorageEnableButton", _("Enable storage"), _("Confirm you want to use this account for this storage"), kEnableStorageCmd); + + _storageUsernameDesc = new StaticTextWidget(boss, prefix + "StorageUsernameDesc", _("Username:"), _("Username used by this storage")); + _storageUsername = new StaticTextWidget(boss, prefix + "StorageUsernameLabel", _(""), "", ThemeEngine::kFontStyleNormal); + + _storageUsedSpaceDesc = new StaticTextWidget(boss, prefix + "StorageUsedSpaceDesc", _("Used space:"), _("Space used by ResidualVM's saved games on this storage")); + _storageUsedSpace = new StaticTextWidget(boss, prefix + "StorageUsedSpaceLabel", "0 bytes", "", ThemeEngine::kFontStyleNormal); + + _storageLastSyncDesc = new StaticTextWidget(boss, prefix + "StorageLastSyncDesc", _("Last sync:"), _("When was the last time saved games were synced with this storage")); + _storageLastSync = new StaticTextWidget(boss, prefix + "StorageLastSyncLabel", _(""), "", ThemeEngine::kFontStyleNormal); + if (lowres) + _storageSyncHint = new StaticTextWidget(boss, prefix + "StorageSyncHint", _c("Saved games sync automatically on launch, after saving and on loading.", "lowres"), "", ThemeEngine::kFontStyleNormal); + else + _storageSyncHint = new StaticTextWidget(boss, prefix + "StorageSyncHint", _("Saved games sync automatically on launch, after saving and on loading."), "", ThemeEngine::kFontStyleNormal); + _storageSyncSavesButton = new ButtonWidget(boss, prefix + "SyncSavesButton", _("Sync now"), _("Start saved games sync"), kSyncSavesStorageCmd); + + if (lowres) + _storageDownloadHint = new StaticTextWidget(boss, prefix + "StorageDownloadHint", _c("You can download game files from your cloud ResidualVM folder:", "lowres")); + else + _storageDownloadHint = new StaticTextWidget(boss, prefix + "StorageDownloadHint", _("You can download game files from your cloud ResidualVM folder:")); + _storageDownloadButton = new ButtonWidget(boss, prefix + "DownloadButton", _("Download game files"), _("Open downloads manager dialog"), kDownloadStorageCmd); + + if (lowres) + _storageDisconnectHint = new StaticTextWidget(boss, prefix + "StorageDisconnectHint", _c("To change account for this storage, disconnect and connect again:", "lowres")); + else + _storageDisconnectHint = new StaticTextWidget(boss, prefix + "StorageDisconnectHint", _("To change account for this storage, disconnect and connect again:")); + _storageDisconnectButton = new ButtonWidget(boss, prefix + "DisconnectButton", _("Disconnect"), _("Stop using this storage on this device"), kDisconnectStorageCmd); + + if (lowres) + _storageWizardNotConnectedHint = new StaticTextWidget(boss, prefix + "StorageWizardNotConnectedHint", _c("This storage is not connected yet! To connect,", "lowres")); + else + _storageWizardNotConnectedHint = new StaticTextWidget(boss, prefix + "StorageWizardNotConnectedHint", _("This storage is not connected yet! To connect,")); + _storageWizardOpenLinkHint = new StaticTextWidget(boss, prefix + "StorageWizardOpenLinkHint", _("1. Open this link:")); + _storageWizardLink = new ButtonWidget(boss, prefix + "StorageWizardLink", "https://cloud.scummvm.org/", _("Open URL"), kOpenUrlStorageCmd); + if (lowres) + _storageWizardCodeHint = new StaticTextWidget(boss, prefix + "StorageWizardCodeHint", _c("2. Get the code and enter it here:", "lowres")); + else + _storageWizardCodeHint = new StaticTextWidget(boss, prefix + "StorageWizardCodeHint", _("2. Get the code and enter it here:")); + _storageWizardCodeBox = new EditTextWidget(boss, prefix + "StorageWizardCodeBox", "", 0, 0, 0, ThemeEngine::kFontStyleConsole); + _storageWizardPasteButton = new ButtonWidget(boss, prefix + "StorageWizardPasteButton", _("Paste"), _("Paste code from clipboard"), kPasteCodeStorageCmd); + _storageWizardConnectButton = new ButtonWidget(boss, prefix + "StorageWizardConnectButton", _("3. Connect"), _("Connect your cloud storage account"), kConnectStorageCmd); + _storageWizardConnectionStatusHint = new StaticTextWidget(boss, prefix + "StorageWizardConnectionStatusHint", "..."); + + setupCloudTab(); +} +#endif // USE_LIBCURL + +#ifdef USE_SDL_NET +void GlobalOptionsDialog::addNetworkControls(GuiObject *boss, const Common::String &prefix, bool lowres) { + _runServerButton = new ButtonWidget(boss, prefix + "RunServerButton", _("Run server"), _("Run local webserver"), kRunServerCmd); + _serverInfoLabel = new StaticTextWidget(boss, prefix + "ServerInfoLabel", _("Not running")); + + // Root path + if (lowres) + _rootPathButton = new ButtonWidget(boss, prefix + "RootPathButton", _c("/root/ Path:", "lowres"), _("Select which directory will be shown as /root/ in the Files Manager"), kChooseRootDirCmd); + else + _rootPathButton = new ButtonWidget(boss, prefix + "RootPathButton", _("/root/ Path:"), _("Select which directory will be shown as /root/ in the Files Manager"), kChooseRootDirCmd); + _rootPath = new StaticTextWidget(boss, prefix + "RootPath", "/foo/bar", _("Select which directory will be shown as /root/ in the Files Manager")); + _rootPathClearButton = addClearButton(boss, prefix + "RootPathClearButton", kRootPathClearCmd); + + uint32 port = Networking::LocalWebserver::getPort(); + + _serverPortDesc = new StaticTextWidget(boss, prefix + "ServerPortDesc", _("Server's port:"), _("Port for server to use")); + _serverPort = new EditTextWidget(boss, prefix + "ServerPortEditText", Common::String::format("%u", port), 0); + _serverPortClearButton = addClearButton(boss, prefix + "ServerPortClearButton", kServerPortClearCmd); + + if (lowres) { + _featureDescriptionLine1 = new StaticTextWidget(boss, prefix + "FeatureDescriptionLine1", _c("Run server to manage files with browser (in the same network).", "lowres"), "", ThemeEngine::kFontStyleNormal); + _featureDescriptionLine2 = new StaticTextWidget(boss, prefix + "FeatureDescriptionLine2", _c("Closing options dialog will stop the server.", "lowres"), "", ThemeEngine::kFontStyleNormal); + } else { + _featureDescriptionLine1 = new StaticTextWidget(boss, prefix + "FeatureDescriptionLine1", _("Run server to manage files with browser (in the same network)."), "", ThemeEngine::kFontStyleNormal); + _featureDescriptionLine2 = new StaticTextWidget(boss, prefix + "FeatureDescriptionLine2", _("Closing options dialog will stop the server."), "", ThemeEngine::kFontStyleNormal); + } + + reflowNetworkTabLayout(); + +} +#endif // USE_SDL_NET +#endif // USE_CLOUD + void GlobalOptionsDialog::apply() { OptionsDialog::apply(); @@ -2013,11 +2095,13 @@ void GlobalOptionsDialog::apply() { #endif #ifdef USE_CLOUD +#ifdef USE_SDL_NET Common::String rootPath(_rootPath->getLabel()); if (!rootPath.empty() && (rootPath != _c("None", "path"))) ConfMan.set("rootpath", rootPath, "cloud"); else ConfMan.removeKey("rootpath", "cloud"); +#endif #endif ConfMan.setInt("autosave_period", _autosavePeriodPopUp->getSelectedTag(), _domain); @@ -2201,6 +2285,7 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3 } #endif #ifdef USE_CLOUD +#ifdef USE_SDL_NET case kChooseRootDirCmd: { BrowserDialog browser(_("Select directory for Files Manager /root/"), true); if (browser.runModal() > 0) { @@ -2214,6 +2299,7 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3 } break; } +#endif #endif case kThemePathClearCmd: _themePath->setLabel(_c("None", "path")); @@ -2225,9 +2311,11 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3 _savePath->setLabel(_("Default")); break; #ifdef USE_CLOUD +#ifdef USE_SDL_NET case kRootPathClearCmd: _rootPath->setLabel(_c("None", "path")); break; +#endif #endif case kChooseSoundFontCmd: { BrowserDialog browser(_("Select SoundFont"), false); @@ -2256,18 +2344,146 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3 break; } #ifdef USE_CLOUD - case kCloudTabContainerReflowCmd: +#ifdef USE_LIBCURL + case kCloudTabContainerReflowCmd: { setupCloudTab(); break; -#ifdef USE_LIBCURL - case kPopUpItemSelectedCmd: - { + } + case kPopUpItemSelectedCmd: { + if (_storageWizardCodeBox) + _storageWizardCodeBox->setEditString(""); // update container's scrollbar reflowLayout(); break; } - case kConfigureStorageCmd: - { + case kEnableStorageCmd: { + CloudMan.enableStorage(); + _redrawCloudTab = true; + + // also, automatically start saves sync when user enables the storage + } + // fall through + case kSyncSavesStorageCmd: { + CloudMan.syncSaves( + new Common::Callback(this, &GlobalOptionsDialog::storageSavesSyncedCallback) + ); + break; + } + case kDownloadStorageCmd: { + DownloadDialog dialog(_selectedStorageIndex, _launcher); + dialog.runModal(); + break; + } + case kOpenUrlStorageCmd: { + Common::String url = "https://cloud.scummvm.org/"; + switch (_selectedStorageIndex) { + case Cloud::kStorageDropboxId: + url += "dropbox"; + break; + case Cloud::kStorageOneDriveId: + url += "onedrive"; + break; + case Cloud::kStorageGoogleDriveId: + url += "gdrive"; + break; + case Cloud::kStorageBoxId: + url += "box"; + break; + } + + if (!g_system->openUrl(url)) { + MessageDialog alert(_("Failed to open URL!\nPlease navigate to this page manually.")); + alert.runModal(); + } + break; + } + case kPasteCodeStorageCmd: { + if (g_system->hasTextInClipboard()) { + Common::String message = g_system->getTextFromClipboard(); + if (!message.empty()) { + _storageWizardCodeBox->setEditString(message); + _redrawCloudTab = true; + } + } + break; + } + case kConnectStorageCmd: { + Common::String code = ""; + if (_storageWizardCodeBox) + code = _storageWizardCodeBox->getEditString(); + if (code.size() == 0) + return; + + if (CloudMan.isWorking()) { + bool cancel = true; + + MessageDialog alert(_("Another Storage is working now. Do you want to interrupt it?"), _("Yes"), _("No")); + if (alert.runModal() == GUI::kMessageOK) { + if (CloudMan.isDownloading()) + CloudMan.cancelDownload(); + if (CloudMan.isSyncing()) + CloudMan.cancelSync(); + + // I believe it still would return `true` here, but just in case + if (CloudMan.isWorking()) { + MessageDialog alert2(_("Wait until current Storage finishes up and try again.")); + alert2.runModal(); + } else { + cancel = false; + } + } + + if (cancel) { + return; + } + } + + if (_storageWizardConnectionStatusHint) + _storageWizardConnectionStatusHint->setLabel(_("Connecting...")); + CloudMan.connectStorage( + _selectedStorageIndex, code, + new Common::Callback(this, &GlobalOptionsDialog::storageConnectionCallback) + ); + _connectingStorage = true; + _redrawCloudTab = true; + break; + } + case kDisconnectStorageCmd: { + if (_storageWizardCodeBox) + _storageWizardCodeBox->setEditString(""); + + if (_selectedStorageIndex == CloudMan.getStorageIndex() && CloudMan.isWorking()) { + bool cancel = true; + + MessageDialog alert(_("This Storage is working now. Do you want to interrupt it?"), _("Yes"), _("No")); + if (alert.runModal() == GUI::kMessageOK) { + if (CloudMan.isDownloading()) + CloudMan.cancelDownload(); + if (CloudMan.isSyncing()) + CloudMan.cancelSync(); + + // I believe it still would return `true` here, but just in case + if (CloudMan.isWorking()) { + MessageDialog alert2(_("Wait until current Storage finishes up and try again.")); + alert2.runModal(); + } else { + cancel = false; + } + } + + if (cancel) { + return; + } + } + + CloudMan.disconnectStorage(_selectedStorageIndex); + _redrawCloudTab = true; + sendCommand(kSetPositionCmd, 0); + break; + } +#endif // USE_LIBCURL +#ifdef USE_SDL_NET + case kRunServerCmd: { #ifdef NETWORKING_LOCALWEBSERVER_ENABLE_PORT_OVERRIDE // save server's port uint32 port = Networking::LocalWebserver::getPort(); @@ -2279,58 +2495,14 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3 ConfMan.setInt("local_server_port", port); ConfMan.flushToDisk(); #endif // NETWORKING_LOCALWEBSERVER_ENABLE_PORT_OVERRIDE - StorageWizardDialog dialog(_selectedStorageIndex); - dialog.runModal(); - //update container's scrollbar - reflowLayout(); + + if (LocalServer.isRunning()) + LocalServer.stopOnIdle(); + else + LocalServer.start(); + break; } - case kRefreshStorageCmd: - { - CloudMan.info( - new Common::Callback(this, &GlobalOptionsDialog::storageInfoCallback), - new Common::Callback(this, &GlobalOptionsDialog::storageErrorCallback) - ); - Common::String dir = CloudMan.savesDirectoryPath(); - if (dir.lastChar() == '/') - dir.deleteLastChar(); - CloudMan.listDirectory( - dir, - new Common::Callback(this, &GlobalOptionsDialog::storageListDirectoryCallback), - new Common::Callback(this, &GlobalOptionsDialog::storageErrorCallback) - ); - break; - } - case kDownloadStorageCmd: - { - DownloadDialog dialog(_selectedStorageIndex, _launcher); - dialog.runModal(); - break; - } -#endif // USE_LIBCURL -#ifdef USE_SDL_NET - case kRunServerCmd: - { -#ifdef NETWORKING_LOCALWEBSERVER_ENABLE_PORT_OVERRIDE - // save server's port - uint32 port = Networking::LocalWebserver::getPort(); - if (_serverPort) { - uint64 contents = _serverPort->getEditString().asUint64(); - if (contents != 0) - port = contents; - } - ConfMan.setInt("local_server_port", port); - ConfMan.flushToDisk(); -#endif // NETWORKING_LOCALWEBSERVER_ENABLE_PORT_OVERRIDE - - if (LocalServer.isRunning()) - LocalServer.stopOnIdle(); - else - LocalServer.start(); - - break; - } - case kServerPortClearCmd: { if (_serverPort) { _serverPort->setEditString(Common::String::format("%u", Networking::LocalWebserver::DEFAULT_SERVER_PORT)); @@ -2364,18 +2536,19 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3 void GlobalOptionsDialog::handleTickle() { OptionsDialog::handleTickle(); #ifdef USE_CLOUD +#ifdef USE_LIBCURL + if (_redrawCloudTab) { + reflowLayout(); // recalculates scrollbar as well + _redrawCloudTab = false; + } +#endif // USE_LIBCURL #ifdef USE_SDL_NET if (LocalServer.isRunning() != _serverWasRunning) { _serverWasRunning = !_serverWasRunning; - _redrawCloudTab = true; + reflowNetworkTabLayout(); } -#endif - if (_redrawCloudTab) { - setupCloudTab(); - g_gui.scheduleTopDialogRedraw(); - _redrawCloudTab = false; - } -#endif +#endif // USE_SDL_NET +#endif // USE_CLOUD } void GlobalOptionsDialog::reflowLayout() { @@ -2417,35 +2590,67 @@ void GlobalOptionsDialog::reflowLayout() { OptionsDialog::reflowLayout(); #ifdef USE_CLOUD +#ifdef USE_LIBCURL setupCloudTab(); -#endif +#endif // USE_LIBCURL +#ifdef USE_SDL_NET + reflowNetworkTabLayout(); +#endif // USE_SDL_NET +#endif // USE_CLOUD } #ifdef USE_CLOUD -void GlobalOptionsDialog::setupCloudTab() { - int serverLabelPosition = -1; //no override #ifdef USE_LIBCURL - _selectedStorageIndex = (_storagePopUp ? _storagePopUp->getSelectedTag() : (uint32) Cloud::kStorageNoneId); +void GlobalOptionsDialog::setupCloudTab() { + _selectedStorageIndex = (_storagePopUp ? _storagePopUp->getSelectedTag() : (uint32)Cloud::kStorageNoneId); if (_storagePopUpDesc) _storagePopUpDesc->setVisible(true); if (_storagePopUp) _storagePopUp->setVisible(true); + Common::String username = CloudMan.getStorageUsername(_selectedStorageIndex); + bool storageConnected = (username != ""); bool shown = (_selectedStorageIndex != Cloud::kStorageNoneId); - if (_storageUsernameDesc) _storageUsernameDesc->setVisible(shown); - if (_storageUsername) { - Common::String username = CloudMan.getStorageUsername(_selectedStorageIndex); - if (username == "") - username = _(""); - _storageUsername->setLabel(username); - _storageUsername->setVisible(shown); + bool shownConnectedInfo = (shown && storageConnected); + bool showingCurrentStorage = (shownConnectedInfo && _selectedStorageIndex == CloudMan.getStorageIndex()); + bool enabled = (shownConnectedInfo && CloudMan.isStorageEnabled()); + + // there goes layout for connected Storage + + if (_storageDisabledHint) _storageDisabledHint->setVisible(showingCurrentStorage && !enabled); + if (_storageEnableButton) _storageEnableButton->setVisible(showingCurrentStorage && !enabled); + + // calculate shift + int16 x, y; + uint16 w, h; + int16 shiftUp = 0; + if (!showingCurrentStorage || enabled) { + // "storage is disabled" hint is not shown, shift everything up + if (!g_gui.xmlEval()->getWidgetData("GlobalOptions_Cloud_Container.StorageDisabledHint", x, y, w, h)) + warning("GlobalOptions_Cloud_Container.StorageUsernameDesc's position is undefined"); + shiftUp = y; + if (!g_gui.xmlEval()->getWidgetData("GlobalOptions_Cloud_Container.StorageUsernameDesc", x, y, w, h)) + warning("GlobalOptions_Cloud_Container.StorageWizardNotConnectedHint's position is undefined"); + shiftUp = y - shiftUp; } - if (_storageUsedSpaceDesc) _storageUsedSpaceDesc->setVisible(shown); + + if (_storageUsernameDesc) _storageUsernameDesc->setVisible(shownConnectedInfo); + if (_storageUsername) { + _storageUsername->setLabel(username); + _storageUsername->setVisible(shownConnectedInfo); + } + if (_storageUsedSpaceDesc) _storageUsedSpaceDesc->setVisible(shownConnectedInfo); if (_storageUsedSpace) { uint64 usedSpace = CloudMan.getStorageUsedSpace(_selectedStorageIndex); - _storageUsedSpace->setLabel(Common::String::format(_("%llu bytes"), usedSpace)); - _storageUsedSpace->setVisible(shown); + Common::String usedSpaceNumber, usedSpaceUnits; + usedSpaceNumber = Common::getHumanReadableBytes(usedSpace, usedSpaceUnits); + _storageUsedSpace->setLabel(Common::String::format("%s %s", usedSpaceNumber.c_str(), _(usedSpaceUnits.c_str()))); + _storageUsedSpace->setVisible(shownConnectedInfo); } - if (_storageLastSyncDesc) _storageLastSyncDesc->setVisible(shown); + if (_storageSyncHint) { + _storageSyncHint->setVisible(shownConnectedInfo); + _storageSyncHint->setEnabled(false); + } + if (_storageLastSyncDesc) _storageLastSyncDesc->setVisible(shownConnectedInfo); if (_storageLastSync) { Common::String sync = CloudMan.getStorageLastSync(_selectedStorageIndex); if (sync == "") { @@ -2455,124 +2660,134 @@ void GlobalOptionsDialog::setupCloudTab() { sync = _(""); } _storageLastSync->setLabel(sync); - _storageLastSync->setVisible(shown); + _storageLastSync->setVisible(shownConnectedInfo); + } + if (_storageSyncSavesButton) { + _storageSyncSavesButton->setVisible(showingCurrentStorage); + _storageSyncSavesButton->setEnabled(enabled); } - if (_storageConnectButton) - _storageConnectButton->setVisible(shown); - if (_storageRefreshButton) - _storageRefreshButton->setVisible(shown && _selectedStorageIndex == CloudMan.getStorageIndex()); - if (_storageDownloadButton) - _storageDownloadButton->setVisible(shown && _selectedStorageIndex == CloudMan.getStorageIndex()); - if (!shown) - serverLabelPosition = (_storageUsernameDesc ? _storageUsernameDesc->getRelY() : 0); -#else // USE_LIBCURL - _selectedStorageIndex = 0; - if (_storagePopUpDesc) - _storagePopUpDesc->setVisible(false); - if (_storagePopUp) - _storagePopUp->setVisible(false); - if (_storageUsernameDesc) - _storageUsernameDesc->setVisible(false); - if (_storageUsernameDesc) - _storageUsernameDesc->setVisible(false); - if (_storageUsername) - _storageUsername->setVisible(false); - if (_storageUsedSpaceDesc) - _storageUsedSpaceDesc->setVisible(false); - if (_storageUsedSpace) - _storageUsedSpace->setVisible(false); - if (_storageLastSyncDesc) - _storageLastSyncDesc->setVisible(false); - if (_storageLastSync) - _storageLastSync->setVisible(false); - if (_storageConnectButton) - _storageConnectButton->setVisible(false); - if (_storageRefreshButton) - _storageRefreshButton->setVisible(false); - if (_storageDownloadButton) - _storageDownloadButton->setVisible(false); + bool showDownloadButton = (showingCurrentStorage && _selectedStorageIndex != Cloud::kStorageGoogleDriveId); // cannot download via Google Drive + if (_storageDownloadHint) _storageDownloadHint->setVisible(showDownloadButton); + if (_storageDownloadButton) { + _storageDownloadButton->setVisible(showDownloadButton); + _storageDownloadButton->setEnabled(enabled); + } + if (_storageDisconnectHint) _storageDisconnectHint->setVisible(shownConnectedInfo); + if (_storageDisconnectButton) _storageDisconnectButton->setVisible(shownConnectedInfo); + + int16 disconnectWidgetsAdditionalShift = 0; + if (!showDownloadButton) { + if (!g_gui.xmlEval()->getWidgetData("GlobalOptions_Cloud_Container.StorageDownloadHint", x, y, w, h)) + warning("GlobalOptions_Cloud_Container.StorageDownloadHint's position is undefined"); + disconnectWidgetsAdditionalShift = y; + if (!g_gui.xmlEval()->getWidgetData("GlobalOptions_Cloud_Container.StorageDisconnectHint", x, y, w, h)) + warning("GlobalOptions_Cloud_Container.DownloadButton's position is undefined"); + disconnectWidgetsAdditionalShift = y - disconnectWidgetsAdditionalShift; + } + + shiftWidget(_storageUsernameDesc, "GlobalOptions_Cloud_Container.StorageUsernameDesc", 0, -shiftUp); + shiftWidget(_storageUsername, "GlobalOptions_Cloud_Container.StorageUsernameLabel", 0, -shiftUp); + shiftWidget(_storageUsedSpaceDesc, "GlobalOptions_Cloud_Container.StorageUsedSpaceDesc", 0, -shiftUp); + shiftWidget(_storageUsedSpace, "GlobalOptions_Cloud_Container.StorageUsedSpaceLabel", 0, -shiftUp); + shiftWidget(_storageSyncHint, "GlobalOptions_Cloud_Container.StorageSyncHint", 0, -shiftUp); + shiftWidget(_storageLastSyncDesc, "GlobalOptions_Cloud_Container.StorageLastSyncDesc", 0, -shiftUp); + shiftWidget(_storageLastSync, "GlobalOptions_Cloud_Container.StorageLastSyncLabel", 0, -shiftUp); + shiftWidget(_storageSyncSavesButton, "GlobalOptions_Cloud_Container.SyncSavesButton", 0, -shiftUp); + shiftWidget(_storageDownloadHint, "GlobalOptions_Cloud_Container.StorageDownloadHint", 0, -shiftUp); + shiftWidget(_storageDownloadButton, "GlobalOptions_Cloud_Container.DownloadButton", 0, -shiftUp); + shiftWidget(_storageDisconnectHint, "GlobalOptions_Cloud_Container.StorageDisconnectHint", 0, -shiftUp - disconnectWidgetsAdditionalShift); + shiftWidget(_storageDisconnectButton, "GlobalOptions_Cloud_Container.DisconnectButton", 0, -shiftUp - disconnectWidgetsAdditionalShift); + + // there goes layout for non-connected Storage (connection wizard) + + shown = (!shownConnectedInfo && shown); + bool wizardEnabled = !_connectingStorage; + if (_storageWizardNotConnectedHint) _storageWizardNotConnectedHint->setVisible(shown); + if (_storageWizardOpenLinkHint) _storageWizardOpenLinkHint->setVisible(shown); + if (_storageWizardLink) { + _storageWizardLink->setVisible(shown); + _storageWizardLink->setEnabled(g_system->hasFeature(OSystem::kFeatureOpenUrl) && wizardEnabled); + } + if (_storageWizardCodeHint) _storageWizardCodeHint->setVisible(shown); + if (_storageWizardCodeBox) { + _storageWizardCodeBox->setVisible(shown); + _storageWizardCodeBox->setEnabled(wizardEnabled); + } + if (_storageWizardPasteButton) { + _storageWizardPasteButton->setVisible(shown && g_system->hasFeature(OSystem::kFeatureClipboardSupport)); + _storageWizardPasteButton->setEnabled(wizardEnabled); + } + if (_storageWizardConnectButton) { + _storageWizardConnectButton->setVisible(shown); + _storageWizardConnectButton->setEnabled(wizardEnabled); + } + if (_storageWizardConnectionStatusHint) { + _storageWizardConnectionStatusHint->setVisible(shown && _storageWizardConnectionStatusHint->getLabel() != "..."); + _storageWizardConnectionStatusHint->setEnabled(wizardEnabled); + } + + if (!shownConnectedInfo) { + if (!g_gui.xmlEval()->getWidgetData("GlobalOptions_Cloud_Container.StorageDisabledHint", x, y, w, h)) + warning("GlobalOptions_Cloud_Container.StorageUsernameDesc's position is undefined"); + shiftUp = y; + if (!g_gui.xmlEval()->getWidgetData("GlobalOptions_Cloud_Container.StorageWizardNotConnectedHint", x, y, w, h)) + warning("GlobalOptions_Cloud_Container.StorageWizardNotConnectedHint's position is undefined"); + shiftUp = y - shiftUp; + + shiftWidget(_storageWizardNotConnectedHint, "GlobalOptions_Cloud_Container.StorageWizardNotConnectedHint", 0, -shiftUp); + shiftWidget(_storageWizardOpenLinkHint, "GlobalOptions_Cloud_Container.StorageWizardOpenLinkHint", 0, -shiftUp); + shiftWidget(_storageWizardLink, "GlobalOptions_Cloud_Container.StorageWizardLink", 0, -shiftUp); + shiftWidget(_storageWizardCodeHint, "GlobalOptions_Cloud_Container.StorageWizardCodeHint", 0, -shiftUp); + shiftWidget(_storageWizardCodeBox, "GlobalOptions_Cloud_Container.StorageWizardCodeBox", 0, -shiftUp); + shiftWidget(_storageWizardPasteButton, "GlobalOptions_Cloud_Container.StorageWizardPasteButton", 0, -shiftUp); + shiftWidget(_storageWizardConnectButton, "GlobalOptions_Cloud_Container.StorageWizardConnectButton", 0, -shiftUp); + shiftWidget(_storageWizardConnectionStatusHint, "GlobalOptions_Cloud_Container.StorageWizardConnectionStatusHint", 0, -shiftUp); + } +} + +void GlobalOptionsDialog::shiftWidget(Widget *widget, const char *widgetName, int32 xOffset, int32 yOffset) { + if (!widget) return; - serverLabelPosition = (_storagePopUpDesc ? _storagePopUpDesc->getRelY() : 0); -#endif // USE_LIBCURL -#ifdef USE_SDL_NET - //determine original widget's positions int16 x, y; uint16 w, h; - int serverButtonY, serverInfoY; - int serverRootButtonY, serverRootY, serverRootClearButtonY; - int serverPortDescY, serverPortY, serverPortClearButtonY; - if (!g_gui.xmlEval()->getWidgetData("GlobalOptions_Cloud_Container.RunServerButton", x, y, w, h)) - warning("GlobalOptions_Cloud_Container.RunServerButton's position is undefined"); - serverButtonY = y; - if (!g_gui.xmlEval()->getWidgetData("GlobalOptions_Cloud_Container.ServerInfoLabel", x, y, w, h)) - warning("GlobalOptions_Cloud_Container.ServerInfoLabel's position is undefined"); - serverInfoY = y; + if (!g_gui.xmlEval()->getWidgetData(widgetName, x, y, w, h)) + warning("%s's position is undefined", widgetName); - if (!g_gui.xmlEval()->getWidgetData("GlobalOptions_Cloud_Container.RootPathButton", x, y, w, h)) - warning("GlobalOptions_Cloud_Container.RootPathButton's position is undefined"); - serverRootButtonY = y; - if (!g_gui.xmlEval()->getWidgetData("GlobalOptions_Cloud_Container.RootPath", x, y, w, h)) - warning("GlobalOptions_Cloud_Container.RootPath's position is undefined"); - serverRootY = y; - if (!g_gui.xmlEval()->getWidgetData("GlobalOptions_Cloud_Container.RootPathClearButton", x, y, w, h)) - warning("GlobalOptions_Cloud_Container.RootPathClearButton's position is undefined"); - serverRootClearButtonY = y; - - if (!g_gui.xmlEval()->getWidgetData("GlobalOptions_Cloud_Container.ServerPortDesc", x, y, w, h)) - warning("GlobalOptions_Cloud_Container.ServerPortDesc's position is undefined"); - serverPortDescY = y; - if (!g_gui.xmlEval()->getWidgetData("GlobalOptions_Cloud_Container.ServerPortEditText", x, y, w, h)) - warning("GlobalOptions_Cloud_Container.ServerPortEditText's position is undefined"); - serverPortY = y; - if (!g_gui.xmlEval()->getWidgetData("GlobalOptions_Cloud_Container.ServerPortClearButton", x, y, w, h)) - warning("GlobalOptions_Cloud_Container.ServerPortClearButton's position is undefined"); - serverPortClearButtonY = y; + widget->setPos(x + xOffset, y + yOffset); +} +#endif // USE_LIBCURL +#ifdef USE_SDL_NET +void GlobalOptionsDialog::reflowNetworkTabLayout() { bool serverIsRunning = LocalServer.isRunning(); - if (serverLabelPosition < 0) - serverLabelPosition = serverInfoY; if (_runServerButton) { _runServerButton->setVisible(true); - _runServerButton->setPos(_runServerButton->getRelX(), serverLabelPosition + serverButtonY - serverInfoY); _runServerButton->setLabel(_(serverIsRunning ? "Stop server" : "Run server")); _runServerButton->setTooltip(_(serverIsRunning ? "Stop local webserver" : "Run local webserver")); } if (_serverInfoLabel) { _serverInfoLabel->setVisible(true); - _serverInfoLabel->setPos(_serverInfoLabel->getRelX(), serverLabelPosition); if (serverIsRunning) _serverInfoLabel->setLabel(LocalServer.getAddress()); else _serverInfoLabel->setLabel(_("Not running")); } - if (_rootPathButton) { - _rootPathButton->setVisible(true); - _rootPathButton->setPos(_rootPathButton->getRelX(), serverLabelPosition + serverRootButtonY - serverInfoY); - } - if (_rootPath) { - _rootPath->setVisible(true); - _rootPath->setPos(_rootPath->getRelX(), serverLabelPosition + serverRootY - serverInfoY); - } - if (_rootPathClearButton) { - _rootPathClearButton->setVisible(true); - _rootPathClearButton->setPos(_rootPathClearButton->getRelX(), serverLabelPosition + serverRootClearButtonY - serverInfoY); - } + if (_rootPathButton) _rootPathButton->setVisible(true); + if (_rootPath) _rootPath->setVisible(true); + if (_rootPathClearButton) _rootPathClearButton->setVisible(true); #ifdef NETWORKING_LOCALWEBSERVER_ENABLE_PORT_OVERRIDE if (_serverPortDesc) { _serverPortDesc->setVisible(true); - _serverPortDesc->setPos(_serverPortDesc->getRelX(), serverLabelPosition + serverPortDescY - serverInfoY); _serverPortDesc->setEnabled(!serverIsRunning); } if (_serverPort) { _serverPort->setVisible(true); - _serverPort->setPos(_serverPort->getRelX(), serverLabelPosition + serverPortY - serverInfoY); _serverPort->setEnabled(!serverIsRunning); } if (_serverPortClearButton) { _serverPortClearButton->setVisible(true); - _serverPortClearButton->setPos(_serverPortClearButton->getRelX(), serverLabelPosition + serverPortClearButtonY - serverInfoY); _serverPortClearButton->setEnabled(!serverIsRunning); } #else // NETWORKING_LOCALWEBSERVER_ENABLE_PORT_OVERRIDE @@ -2583,43 +2798,41 @@ void GlobalOptionsDialog::setupCloudTab() { if (_serverPortClearButton) _serverPortClearButton->setVisible(false); #endif // NETWORKING_LOCALWEBSERVER_ENABLE_PORT_OVERRIDE -#else // USE_SDL_NET - if (_runServerButton) - _runServerButton->setVisible(false); - if (_serverInfoLabel) { - _serverInfoLabel->setPos(_serverInfoLabel->getRelX(), serverLabelPosition); // Prevent compiler warning from serverLabelPosition being unused. - _serverInfoLabel->setVisible(false); + + // if port override isn't supported, there will be a gap between these lines and options -- it's OK + + if (_featureDescriptionLine1) { + _featureDescriptionLine1->setVisible(true); + _featureDescriptionLine1->setEnabled(false); + } + if (_featureDescriptionLine2) { + _featureDescriptionLine2->setVisible(true); + _featureDescriptionLine2->setEnabled(false); } - if (_rootPathButton) - _rootPathButton->setVisible(false); - if (_rootPath) - _rootPath->setVisible(false); - if (_rootPathClearButton) - _rootPathClearButton->setVisible(false); - if (_serverPortDesc) - _serverPortDesc->setVisible(false); - if (_serverPort) - _serverPort->setVisible(false); - if (_serverPortClearButton) - _serverPortClearButton->setVisible(false); -#endif // USE_SDL_NET } +#endif // USE_SDL_NET #ifdef USE_LIBCURL -void GlobalOptionsDialog::storageInfoCallback(Cloud::Storage::StorageInfoResponse response) { - //we could've used response.value.email() - //but Storage already notified CloudMan - //so we just set the flag to redraw our cloud tab +void GlobalOptionsDialog::storageConnectionCallback(Networking::ErrorResponse response) { + Common::String message = "..."; + if (!response.failed && !response.interrupted) { + // success + g_system->displayMessageOnOSD(_("Storage connected.")); + } else { + message = _("Failed to connect storage."); + if (response.failed) { + message = Common::String(_("Failed to connect storage: ")) + _(response.response.c_str()); + } + } + + if (_storageWizardConnectionStatusHint) + _storageWizardConnectionStatusHint->setLabel(message); + _redrawCloudTab = true; + _connectingStorage = false; } -void GlobalOptionsDialog::storageListDirectoryCallback(Cloud::Storage::ListDirectoryResponse response) { - Common::Array &files = response.value; - uint64 totalSize = 0; - for (uint32 i = 0; i < files.size(); ++i) - if (!files[i].isDirectory()) - totalSize += files[i].size(); - CloudMan.setStorageUsedSpace(CloudMan.getStorageIndex(), totalSize); +void GlobalOptionsDialog::storageSavesSyncedCallback(Cloud::Storage::BoolResponse response) { _redrawCloudTab = true; } diff --git a/gui/options.h b/gui/options.h index 49ba3266b05..a09cc2f8814 100644 --- a/gui/options.h +++ b/gui/options.h @@ -242,7 +242,7 @@ protected: }; -class GlobalOptionsDialog : public OptionsDialog { +class GlobalOptionsDialog : public OptionsDialog, public CommandSender { public: GlobalOptionsDialog(LauncherDialog *launcher); ~GlobalOptionsDialog(); @@ -296,41 +296,68 @@ protected: #endif #ifdef USE_CLOUD +#ifdef USE_LIBCURL // // Cloud controls // uint32 _selectedStorageIndex; StaticTextWidget *_storagePopUpDesc; - PopUpWidget *_storagePopUp; + PopUpWidget *_storagePopUp; + StaticTextWidget *_storageDisabledHint; + ButtonWidget *_storageEnableButton; StaticTextWidget *_storageUsernameDesc; StaticTextWidget *_storageUsername; StaticTextWidget *_storageUsedSpaceDesc; StaticTextWidget *_storageUsedSpace; + StaticTextWidget *_storageSyncHint; StaticTextWidget *_storageLastSyncDesc; StaticTextWidget *_storageLastSync; - ButtonWidget *_storageConnectButton; - ButtonWidget *_storageRefreshButton; + ButtonWidget *_storageSyncSavesButton; + StaticTextWidget *_storageDownloadHint; ButtonWidget *_storageDownloadButton; + StaticTextWidget *_storageDisconnectHint; + ButtonWidget *_storageDisconnectButton; + + bool _connectingStorage; + StaticTextWidget *_storageWizardNotConnectedHint; + StaticTextWidget *_storageWizardOpenLinkHint; + StaticTextWidget *_storageWizardLink; + StaticTextWidget *_storageWizardCodeHint; + EditTextWidget *_storageWizardCodeBox; + ButtonWidget *_storageWizardPasteButton; + ButtonWidget *_storageWizardConnectButton; + StaticTextWidget *_storageWizardConnectionStatusHint; + bool _redrawCloudTab; + + void addCloudControls(GuiObject *boss, const Common::String &prefix, bool lowres); + void setupCloudTab(); + void shiftWidget(Widget *widget, const char *widgetName, int32 xOffset, int32 yOffset); + + void storageConnectionCallback(Networking::ErrorResponse response); + void storageSavesSyncedCallback(Cloud::Storage::BoolResponse response); + void storageErrorCallback(Networking::ErrorResponse response); +#endif // USE_LIBCURL + +#ifdef USE_SDL_NET + // + // LAN controls + // ButtonWidget *_runServerButton; StaticTextWidget *_serverInfoLabel; ButtonWidget *_rootPathButton; StaticTextWidget *_rootPath; ButtonWidget *_rootPathClearButton; StaticTextWidget *_serverPortDesc; - EditTextWidget *_serverPort; + EditTextWidget *_serverPort; ButtonWidget *_serverPortClearButton; - bool _redrawCloudTab; -#ifdef USE_SDL_NET + StaticTextWidget *_featureDescriptionLine1; + StaticTextWidget *_featureDescriptionLine2; bool _serverWasRunning; -#endif - void setupCloudTab(); + void addNetworkControls(GuiObject *boss, const Common::String &prefix, bool lowres); + void reflowNetworkTabLayout(); +#endif // USE_SDL_NET -#ifdef USE_LIBCURL - void storageInfoCallback(Cloud::Storage::StorageInfoResponse response); - void storageListDirectoryCallback(Cloud::Storage::ListDirectoryResponse response); - void storageErrorCallback(Networking::ErrorResponse response); -#endif #endif // USE_CLOUD }; diff --git a/gui/recorderdialog.cpp b/gui/recorderdialog.cpp index 7a2cd048f40..cbe90c93b81 100644 --- a/gui/recorderdialog.cpp +++ b/gui/recorderdialog.cpp @@ -166,8 +166,7 @@ void RecorderDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat break; case kRecordCmd: { TimeDate t; - Common::String gameId = ConfMan.get("gameid", _target); - PlainGameDescriptor desc = EngineMan.findGame(gameId); + QualifiedGameDescriptor desc = EngineMan.findTarget(_target); g_system->getTimeAndDate(t); EditRecordDialog editDlg(_("Unknown Author"), Common::String::format("%.2d.%.2d.%.4d ", t.tm_mday, t.tm_mon, 1900 + t.tm_year) + desc.description, ""); if (editDlg.runModal() != kOKCmd) { diff --git a/gui/saveload.cpp b/gui/saveload.cpp index a893f3c0db6..cb9e7126ebf 100644 --- a/gui/saveload.cpp +++ b/gui/saveload.cpp @@ -74,11 +74,7 @@ Common::String SaveLoadChooser::createDefaultSaveDescription(const int slot) con } int SaveLoadChooser::runModalWithCurrentTarget() { - const Common::String gameId = ConfMan.get("gameid"); - - const Plugin *plugin = 0; - EngineMan.findGame(gameId, &plugin); - + const Plugin *plugin = EngineMan.findPlugin(ConfMan.get("engineid")); return runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); } diff --git a/gui/themes/default.inc b/gui/themes/default.inc index 6f98a29d364..4bb7bcbe55b 100644 --- a/gui/themes/default.inc +++ b/gui/themes/default.inc @@ -17,6 +17,9 @@ const char *defaultXML1 = "" "" +"" "" "" "" "" "" "" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" "" "" "" "" +"" "" "" "" +"" +"" "" ; const char *defaultXML4 = "" @@ -2275,6 +2577,7 @@ const char *defaultXML1 = "" "" "" "" +"" "" @@ -3855,6 +4158,8 @@ const char *defaultXML1 = "" "" "" "" +"" +"" "" ; const char *defaultXML[] = { defaultXML1, defaultXML2, defaultXML3, defaultXML4 }; diff --git a/gui/themes/fonts/clR6x12-iso-8859-7.bdf b/gui/themes/fonts/clR6x12-iso-8859-7.bdf index cd389bd660f..4f7be9f4628 100644 --- a/gui/themes/fonts/clR6x12-iso-8859-7.bdf +++ b/gui/themes/fonts/clR6x12-iso-8859-7.bdf @@ -1,32 +1,32 @@ STARTFONT 2.1 -COMMENT AUTOMATICALLY GENERATED FILE. DO NOT EDIT! -COMMENT Generated with 'ucs2any clR6x12.bdf /usr/share/fonts/X11/util/map-ISO8859-7 ISO8859-7' -COMMENT from an ISO10646-1 encoded source BDF font. -COMMENT ucs2any by Ben Collver , 2003, based on -COMMENT ucs2any.pl by Markus Kuhn , 2000. -COMMENT $XConsortium: clR6x12.bdf,v 1.2 94/04/11 12:08:30 gildea Exp $ -COMMENT -COMMENT Copyright 1989 Dale Schumacher, dal@syntel.mn.org -COMMENT 399 Beacon Ave. -COMMENT St. Paul, MN 55104-3527 -COMMENT -COMMENT Permission to use, copy, modify, and distribute this software and -COMMENT its documentation for any purpose and without fee is hereby -COMMENT granted, provided that the above copyright notice appear in all -COMMENT copies and that both that copyright notice and this permission -COMMENT notice appear in supporting documentation, and that the name of -COMMENT Dale Schumacher not be used in advertising or publicity pertaining to -COMMENT distribution of the software without specific, written prior -COMMENT permission. Dale Schumacher makes no representations about the -COMMENT suitability of this software for any purpose. It is provided "as -COMMENT is" without express or implied warranty. -COMMENT -COMMENT -COMMENT Modified by Robert Brady, -COMMENT FONT -Schumacher-Clean-Medium-R-Normal--12-120-75-75-C-60-ISO8859-7 SIZE 12 75 75 -FONTBOUNDINGBOX 6 12 0 -3 +FONTBOUNDINGBOX 8 12 -2 -3 +COMMENT "Generated by fontforge, http://fontforge.sourceforge.net" +COMMENT "AUTOMATICALLY GENERATED FILE. DO NOT EDIT!" +COMMENT "Generated with 'ucs2any.pl clR6x12.bdf ../../../fonts/util/map-ISO8859-1 ISO8859-1'" +COMMENT "from an ISO10646-1 encoded source BDF font." +COMMENT "ucs2any.pl by Markus Kuhn , 2000." +COMMENT "$Xorg: clR6x12.bdf,v 1.3 2000/08/18 15:17:40 xorgcvs Exp $" +COMMENT "" +COMMENT "Copyright 1989 Dale Schumacher, dal@syntel.mn.org" +COMMENT "399 Beacon Ave." +COMMENT "St. Paul, MN 55104-3527" +COMMENT "" +COMMENT "Permission to use, copy, modify, and distribute this software and" +COMMENT "its documentation for any purpose and without fee is hereby" +COMMENT "granted, provided that the above copyright notice appear in all" +COMMENT "copies and that both that copyright notice and this permission" +COMMENT "notice appear in supporting documentation, and that the name of" +COMMENT "Dale Schumacher not be used in advertising or publicity pertaining to" +COMMENT "distribution of the software without specific, written prior" +COMMENT "permission. Dale Schumacher makes no representations about the" +COMMENT "suitability of this software for any purpose. It is provided "as" +COMMENT "is" without express or implied warranty." +COMMENT "" +COMMENT "" +COMMENT "Modified by Robert Brady, " +COMMENT "" STARTPROPERTIES 21 FONTNAME_REGISTRY "" FOUNDRY "Schumacher" @@ -50,15 +50,13 @@ COPYRIGHT "Copyright 1989 Dale Schumacher, 1999 Robert Brady." CAP_HEIGHT 8 X_HEIGHT 5 ENDPROPERTIES -CHARS 220 -STARTCHAR defaultchar +CHARS 223 +STARTCHAR uni0000 ENCODING 0 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 A8 00 88 @@ -66,30 +64,20 @@ A8 88 00 A8 -00 -00 -00 ENDCHAR -STARTCHAR uni25C6 +STARTCHAR uni0001 ENCODING 1 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 0 BITMAP -00 -00 -00 -00 20 70 F8 70 20 -00 -00 -00 ENDCHAR -STARTCHAR shade +STARTCHAR uni0002 ENCODING 2 SWIDTH 480 0 DWIDTH 6 0 @@ -108,13 +96,12 @@ A8 A8 54 ENDCHAR -STARTCHAR uni2409 +STARTCHAR uni0003 ENCODING 3 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 6 9 0 -1 BITMAP -00 A0 A0 E0 @@ -124,16 +111,13 @@ BC 08 08 08 -00 -00 ENDCHAR -STARTCHAR uni240C +STARTCHAR uni0004 ENCODING 4 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 6 8 0 0 BITMAP -00 E0 80 C0 @@ -142,17 +126,13 @@ C0 1C 10 10 -00 -00 -00 ENDCHAR -STARTCHAR uni240D +STARTCHAR uni0005 ENCODING 5 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 6 8 0 0 BITMAP -00 60 80 80 @@ -161,17 +141,13 @@ BITMAP 18 14 14 -00 -00 -00 ENDCHAR -STARTCHAR uni240A +STARTCHAR uni0006 ENCODING 6 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 6 8 0 0 BITMAP -00 80 80 80 @@ -180,37 +156,24 @@ F0 18 10 10 -00 -00 -00 ENDCHAR -STARTCHAR degree +STARTCHAR uni0007 ENCODING 7 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 4 1 4 BITMAP -00 -30 -48 -48 -30 -00 -00 -00 -00 -00 -00 -00 +60 +90 +90 +60 ENDCHAR -STARTCHAR plusminus +STARTCHAR uni0008 ENCODING 8 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 20 20 F8 @@ -218,15 +181,12 @@ F8 20 00 F8 -00 -00 -00 ENDCHAR -STARTCHAR uni2424 +STARTCHAR uni0009 ENCODING 9 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 6 9 0 0 BITMAP A0 E0 @@ -237,17 +197,13 @@ B0 10 10 1C -00 -00 -00 ENDCHAR -STARTCHAR uni240B +STARTCHAR uni000A ENCODING 10 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 6 8 0 0 BITMAP -00 A0 A0 A0 @@ -256,15 +212,12 @@ A0 08 08 08 -00 -00 -00 ENDCHAR -STARTCHAR SF040000 +STARTCHAR uni000B ENCODING 11 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 3 7 0 2 BITMAP 20 20 @@ -273,24 +226,13 @@ BITMAP 20 20 E0 -00 -00 -00 -00 -00 ENDCHAR -STARTCHAR SF030000 +STARTCHAR uni000C ENCODING 12 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 3 6 0 -3 BITMAP -00 -00 -00 -00 -00 -00 E0 20 20 @@ -298,45 +240,34 @@ E0 20 20 ENDCHAR -STARTCHAR SF010000 +STARTCHAR uni000D ENCODING 13 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 6 2 -3 BITMAP -00 -00 -00 -00 -00 -00 -3F -20 -20 -20 -20 -20 +FC +80 +80 +80 +80 +80 ENDCHAR -STARTCHAR SF020000 +STARTCHAR uni000E ENCODING 14 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 7 2 2 BITMAP -20 -20 -20 -20 -20 -20 -3F -00 -00 -00 -00 -00 +80 +80 +80 +80 +80 +80 +FC ENDCHAR -STARTCHAR SF050000 +STARTCHAR uni000F ENCODING 15 SWIDTH 480 0 DWIDTH 6 0 @@ -355,125 +286,70 @@ FF 20 20 ENDCHAR -STARTCHAR uni23BA +STARTCHAR uni0010 ENCODING 16 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 6 1 0 8 BITMAP FC -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 ENDCHAR -STARTCHAR uni23BB +STARTCHAR uni0011 ENCODING 17 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 6 1 0 5 BITMAP -00 -00 -00 FC -00 -00 -00 -00 -00 -00 -00 -00 ENDCHAR -STARTCHAR SF100000 +STARTCHAR uni0012 ENCODING 18 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 6 1 0 2 BITMAP -00 -00 -00 -00 -00 -00 FC -00 -00 -00 -00 -00 ENDCHAR -STARTCHAR uni23BC +STARTCHAR uni0013 ENCODING 19 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 6 1 0 0 BITMAP -00 -00 -00 -00 -00 -00 -00 -00 FC -00 -00 -00 ENDCHAR -STARTCHAR uni23BD +STARTCHAR uni0014 ENCODING 20 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 6 1 0 -3 BITMAP -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 FC ENDCHAR -STARTCHAR SF080000 +STARTCHAR uni0015 ENCODING 21 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 12 2 -3 BITMAP -20 -20 -20 -20 -20 -20 -3F -20 -20 -20 -20 -20 +80 +80 +80 +80 +80 +80 +FC +80 +80 +80 +80 +80 ENDCHAR -STARTCHAR SF090000 +STARTCHAR uni0016 ENCODING 22 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 3 12 0 -3 BITMAP 20 20 @@ -488,11 +364,11 @@ E0 20 20 ENDCHAR -STARTCHAR SF070000 +STARTCHAR uni0017 ENCODING 23 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 6 7 0 2 BITMAP 20 20 @@ -501,24 +377,13 @@ BITMAP 20 20 FF -00 -00 -00 -00 -00 ENDCHAR -STARTCHAR SF060000 +STARTCHAR uni0018 ENCODING 24 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 6 6 0 -3 BITMAP -00 -00 -00 -00 -00 -00 FF 20 20 @@ -526,33 +391,31 @@ FF 20 20 ENDCHAR -STARTCHAR SF110000 +STARTCHAR uni0019 ENCODING 25 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 1 12 2 -3 BITMAP -20 -20 -20 -20 -20 -20 -20 -20 -20 -20 -20 -20 +80 +80 +80 +80 +80 +80 +80 +80 +80 +80 +80 +80 ENDCHAR -STARTCHAR lessequal +STARTCHAR uni001A ENCODING 26 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 18 60 80 @@ -560,18 +423,13 @@ BITMAP 18 00 F8 -00 -00 -00 ENDCHAR -STARTCHAR greaterequal +STARTCHAR uni001B ENCODING 27 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 C0 30 08 @@ -579,37 +437,25 @@ C0 C0 00 F8 -00 -00 -00 ENDCHAR -STARTCHAR pi +STARTCHAR uni001C ENCODING 28 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 0 BITMAP -00 -00 -00 -00 F8 88 88 88 88 -00 -00 -00 ENDCHAR -STARTCHAR notequal +STARTCHAR uni001D ENCODING 29 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 10 10 F8 @@ -617,17 +463,13 @@ F8 F8 40 40 -00 -00 -00 ENDCHAR -STARTCHAR sterling +STARTCHAR uni001E ENCODING 30 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 0 BITMAP -00 30 48 40 @@ -636,94 +478,54 @@ E0 40 48 B0 -00 -00 -00 ENDCHAR -STARTCHAR periodcentered +STARTCHAR uni001F ENCODING 31 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 2 1 2 2 BITMAP -00 -00 -00 -00 -00 -00 -30 -00 -00 -00 -00 -00 +C0 ENDCHAR STARTCHAR space ENCODING 32 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 1 1 5 -3 BITMAP 00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 ENDCHAR STARTCHAR exclam ENCODING 33 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 1 8 2 0 BITMAP +80 +80 +80 +80 +80 +80 00 -20 -20 -20 -20 -20 -20 -00 -20 -00 -00 -00 +80 ENDCHAR STARTCHAR quotedbl ENCODING 34 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 3 3 1 5 BITMAP -00 -50 -50 -50 -00 -00 -00 -00 -00 -00 -00 -00 +A0 +A0 +A0 ENDCHAR STARTCHAR numbersign ENCODING 35 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 50 50 F8 @@ -731,18 +533,13 @@ F8 F8 50 50 -00 -00 -00 ENDCHAR STARTCHAR dollar ENCODING 36 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 20 78 A0 @@ -750,18 +547,13 @@ A0 28 F0 20 -00 -00 -00 ENDCHAR STARTCHAR percent ENCODING 37 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 C0 C8 10 @@ -769,18 +561,13 @@ C8 40 98 18 -00 -00 -00 ENDCHAR STARTCHAR ampersand ENCODING 38 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 70 80 80 @@ -788,167 +575,110 @@ BITMAP A8 90 68 -00 -00 -00 ENDCHAR STARTCHAR quotesingle ENCODING 39 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 1 3 2 5 BITMAP -00 -20 -20 -20 -00 -00 -00 -00 -00 -00 -00 -00 +80 +80 +80 ENDCHAR STARTCHAR parenleft ENCODING 40 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 3 11 2 -2 BITMAP -08 -10 -10 20 +40 +40 +80 +80 +80 +80 +80 +40 +40 20 -20 -20 -20 -10 -10 -08 -00 ENDCHAR STARTCHAR parenright ENCODING 41 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 3 11 1 -2 BITMAP +80 +40 40 20 20 -10 -10 -10 -10 -10 +20 20 20 40 -00 +40 +80 ENDCHAR STARTCHAR asterisk ENCODING 42 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 1 BITMAP -00 -00 -00 20 A8 70 A8 20 -00 -00 -00 -00 ENDCHAR STARTCHAR plus ENCODING 43 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 1 BITMAP -00 -00 -00 20 20 F8 20 20 -00 -00 -00 -00 ENDCHAR STARTCHAR comma ENCODING 44 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 3 4 1 -2 BITMAP -00 -00 -00 -00 -00 -00 -00 -30 -30 -20 +60 +60 40 -00 +80 ENDCHAR STARTCHAR hyphen ENCODING 45 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 1 0 3 BITMAP -00 -00 -00 -00 -00 F8 -00 -00 -00 -00 -00 -00 ENDCHAR STARTCHAR period ENCODING 46 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 2 2 2 0 BITMAP -00 -00 -00 -00 -00 -00 -00 -30 -30 -00 -00 -00 +C0 +C0 ENDCHAR STARTCHAR slash ENCODING 47 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 10 0 -1 BITMAP 08 08 @@ -960,16 +690,13 @@ BITMAP 40 80 80 -00 -00 ENDCHAR STARTCHAR zero ENCODING 48 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 0 BITMAP -00 70 88 98 @@ -978,36 +705,28 @@ C8 88 88 70 -00 -00 -00 ENDCHAR STARTCHAR one ENCODING 49 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 2 8 2 0 BITMAP -00 -10 -30 -10 -10 -10 -10 -10 -10 -00 -00 -00 +40 +C0 +40 +40 +40 +40 +40 +40 ENDCHAR STARTCHAR two ENCODING 50 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 0 BITMAP -00 70 88 08 @@ -1016,17 +735,13 @@ BITMAP 40 80 F8 -00 -00 -00 ENDCHAR STARTCHAR three ENCODING 51 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 0 BITMAP -00 70 88 08 @@ -1035,17 +750,13 @@ BITMAP 08 88 70 -00 -00 -00 ENDCHAR STARTCHAR four ENCODING 52 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 0 BITMAP -00 10 30 30 @@ -1054,17 +765,13 @@ BITMAP F8 10 38 -00 -00 -00 ENDCHAR STARTCHAR five ENCODING 53 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 0 BITMAP -00 F8 80 80 @@ -1073,17 +780,13 @@ F0 08 88 70 -00 -00 -00 ENDCHAR STARTCHAR six ENCODING 54 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 0 BITMAP -00 30 40 80 @@ -1092,17 +795,13 @@ F0 88 88 70 -00 -00 -00 ENDCHAR STARTCHAR seven ENCODING 55 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 0 BITMAP -00 F8 88 08 @@ -1111,17 +810,13 @@ F8 10 20 20 -00 -00 -00 ENDCHAR STARTCHAR eight ENCODING 56 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 0 BITMAP -00 70 88 88 @@ -1130,17 +825,13 @@ BITMAP 88 88 70 -00 -00 -00 ENDCHAR STARTCHAR nine ENCODING 57 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 0 BITMAP -00 70 88 88 @@ -1149,112 +840,75 @@ BITMAP 08 10 60 -00 -00 -00 ENDCHAR STARTCHAR colon ENCODING 58 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 2 6 2 0 BITMAP +C0 +C0 00 00 -00 -30 -30 -00 -00 -30 -30 -00 -00 -00 +C0 +C0 ENDCHAR STARTCHAR semicolon ENCODING 59 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 3 8 1 -2 BITMAP +60 +60 00 00 -00 -30 -30 -00 -00 -30 -30 -20 +60 +60 40 -00 +80 ENDCHAR STARTCHAR less ENCODING 60 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 6 5 0 1 BITMAP -00 -00 -00 0C 30 C0 30 0C -00 -00 -00 -00 ENDCHAR STARTCHAR equal ENCODING 61 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 3 0 2 BITMAP -00 -00 -00 -00 F8 00 F8 -00 -00 -00 -00 -00 ENDCHAR STARTCHAR greater ENCODING 62 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 6 5 0 1 BITMAP -00 -00 -00 C0 30 0C 30 C0 -00 -00 -00 -00 ENDCHAR STARTCHAR question ENCODING 63 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 0 BITMAP -00 70 88 08 @@ -1263,18 +917,13 @@ BITMAP 20 00 20 -00 -00 -00 ENDCHAR STARTCHAR at ENCODING 64 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 70 88 B8 @@ -1282,18 +931,13 @@ B8 B0 80 70 -00 -00 -00 ENDCHAR STARTCHAR A ENCODING 65 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 20 50 88 @@ -1301,18 +945,13 @@ BITMAP F8 88 88 -00 -00 -00 ENDCHAR STARTCHAR B ENCODING 66 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 F0 88 88 @@ -1320,18 +959,13 @@ F0 88 88 F0 -00 -00 -00 ENDCHAR STARTCHAR C ENCODING 67 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 70 88 80 @@ -1339,18 +973,13 @@ BITMAP 80 88 70 -00 -00 -00 ENDCHAR STARTCHAR D ENCODING 68 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 E0 90 88 @@ -1358,18 +987,13 @@ E0 88 90 E0 -00 -00 -00 ENDCHAR STARTCHAR E ENCODING 69 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 F8 80 80 @@ -1377,18 +1001,13 @@ F0 80 80 F8 -00 -00 -00 ENDCHAR STARTCHAR F ENCODING 70 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 F8 80 80 @@ -1396,18 +1015,13 @@ F0 80 80 80 -00 -00 -00 ENDCHAR STARTCHAR G ENCODING 71 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 70 88 80 @@ -1415,18 +1029,13 @@ BITMAP 88 88 78 -00 -00 -00 ENDCHAR STARTCHAR H ENCODING 72 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 88 88 88 @@ -1434,18 +1043,13 @@ F8 88 88 88 -00 -00 -00 ENDCHAR STARTCHAR I ENCODING 73 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 F8 20 20 @@ -1453,18 +1057,13 @@ F8 20 20 F8 -00 -00 -00 ENDCHAR STARTCHAR J ENCODING 74 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 38 08 08 @@ -1472,18 +1071,13 @@ BITMAP 88 88 70 -00 -00 -00 ENDCHAR STARTCHAR K ENCODING 75 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 88 90 A0 @@ -1491,18 +1085,13 @@ C0 A0 90 88 -00 -00 -00 ENDCHAR STARTCHAR L ENCODING 76 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 80 80 80 @@ -1510,18 +1099,13 @@ BITMAP 80 80 F8 -00 -00 -00 ENDCHAR STARTCHAR M ENCODING 77 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 88 D8 A8 @@ -1529,18 +1113,13 @@ A8 88 88 88 -00 -00 -00 ENDCHAR STARTCHAR N ENCODING 78 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 88 C8 C8 @@ -1548,18 +1127,13 @@ A8 98 98 88 -00 -00 -00 ENDCHAR STARTCHAR O ENCODING 79 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 70 88 88 @@ -1567,18 +1141,13 @@ BITMAP 88 88 70 -00 -00 -00 ENDCHAR STARTCHAR P ENCODING 80 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 F0 88 88 @@ -1586,18 +1155,13 @@ F0 80 80 80 -00 -00 -00 ENDCHAR STARTCHAR Q ENCODING 81 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 -1 BITMAP -00 -00 70 88 88 @@ -1606,17 +1170,13 @@ BITMAP 88 70 18 -00 -00 ENDCHAR STARTCHAR R ENCODING 82 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 F0 88 88 @@ -1624,18 +1184,13 @@ F0 A0 90 88 -00 -00 -00 ENDCHAR STARTCHAR S ENCODING 83 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 70 88 80 @@ -1643,18 +1198,13 @@ BITMAP 08 88 70 -00 -00 -00 ENDCHAR STARTCHAR T ENCODING 84 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 F8 20 20 @@ -1662,18 +1212,13 @@ F8 20 20 20 -00 -00 -00 ENDCHAR STARTCHAR U ENCODING 85 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 88 88 88 @@ -1681,18 +1226,13 @@ BITMAP 88 88 70 -00 -00 -00 ENDCHAR STARTCHAR V ENCODING 86 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 88 88 88 @@ -1700,18 +1240,13 @@ BITMAP 50 20 20 -00 -00 -00 ENDCHAR STARTCHAR W ENCODING 87 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 88 88 88 @@ -1719,18 +1254,13 @@ A8 A8 D8 88 -00 -00 -00 ENDCHAR STARTCHAR X ENCODING 88 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 88 88 50 @@ -1738,18 +1268,13 @@ BITMAP 50 88 88 -00 -00 -00 ENDCHAR STARTCHAR Y ENCODING 89 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 88 88 50 @@ -1757,18 +1282,13 @@ BITMAP 20 20 20 -00 -00 -00 ENDCHAR STARTCHAR Z ENCODING 90 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 F8 08 10 @@ -1776,34 +1296,30 @@ F8 40 80 F8 -00 -00 -00 ENDCHAR STARTCHAR bracketleft ENCODING 91 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 3 11 2 -2 BITMAP -38 -20 -20 -20 -20 -20 -20 -20 -20 -20 -38 -00 +E0 +80 +80 +80 +80 +80 +80 +80 +80 +80 +E0 ENDCHAR STARTCHAR backslash ENCODING 92 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 10 0 -1 BITMAP 80 80 @@ -1815,111 +1331,70 @@ BITMAP 10 08 08 -00 -00 ENDCHAR STARTCHAR bracketright ENCODING 93 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 3 11 1 -2 BITMAP -70 -10 -10 -10 -10 -10 -10 -10 -10 -10 -70 -00 +E0 +20 +20 +20 +20 +20 +20 +20 +20 +20 +E0 ENDCHAR STARTCHAR asciicircum ENCODING 94 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 3 0 5 BITMAP -00 20 50 88 -00 -00 -00 -00 -00 -00 -00 -00 ENDCHAR STARTCHAR underscore ENCODING 95 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 6 1 0 -1 BITMAP -00 -00 -00 -00 -00 -00 -00 -00 -00 FC -00 -00 ENDCHAR STARTCHAR grave ENCODING 96 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 2 2 2 6 BITMAP -00 -20 -10 -00 -00 -00 -00 -00 -00 -00 -00 -00 +80 +40 ENDCHAR STARTCHAR a ENCODING 97 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 0 BITMAP -00 -00 -00 -00 78 88 88 98 68 -00 -00 -00 ENDCHAR STARTCHAR b ENCODING 98 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 0 BITMAP -00 80 80 80 @@ -1928,36 +1403,25 @@ F0 88 88 F0 -00 -00 -00 ENDCHAR STARTCHAR c ENCODING 99 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 0 BITMAP -00 -00 -00 -00 78 80 80 80 78 -00 -00 -00 ENDCHAR STARTCHAR d ENCODING 100 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 0 BITMAP -00 08 08 08 @@ -1966,36 +1430,25 @@ BITMAP 88 88 78 -00 -00 -00 ENDCHAR STARTCHAR e ENCODING 101 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 0 BITMAP -00 -00 -00 -00 70 88 F8 80 70 -00 -00 -00 ENDCHAR STARTCHAR f ENCODING 102 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 0 BITMAP -00 38 40 40 @@ -2004,20 +1457,13 @@ F0 40 40 40 -00 -00 -00 ENDCHAR STARTCHAR g ENCODING 103 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 -3 BITMAP -00 -00 -00 -00 78 88 88 @@ -2031,9 +1477,8 @@ STARTCHAR h ENCODING 104 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 0 BITMAP -00 80 80 80 @@ -2042,153 +1487,112 @@ F0 88 88 88 -00 -00 -00 ENDCHAR STARTCHAR i ENCODING 105 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 3 8 1 0 BITMAP +40 +40 00 -20 -20 -00 -60 -20 -20 -20 -70 -00 -00 -00 +C0 +40 +40 +40 +E0 ENDCHAR STARTCHAR j ENCODING 106 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 11 1 -3 BITMAP +10 +10 00 -08 -08 -00 -38 -08 -08 -08 -08 -08 -08 70 +10 +10 +10 +10 +10 +10 +E0 ENDCHAR STARTCHAR k ENCODING 107 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 8 1 0 BITMAP -00 -40 -40 -40 -48 -50 -60 -50 -48 -00 -00 -00 +80 +80 +80 +90 +A0 +C0 +A0 +90 ENDCHAR STARTCHAR l ENCODING 108 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 3 8 1 0 BITMAP -00 -60 -20 -20 -20 -20 -20 -20 -70 -00 -00 -00 +C0 +40 +40 +40 +40 +40 +40 +E0 ENDCHAR STARTCHAR m ENCODING 109 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 0 BITMAP -00 -00 -00 -00 D0 A8 A8 A8 88 -00 -00 -00 ENDCHAR STARTCHAR n ENCODING 110 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 0 BITMAP -00 -00 -00 -00 B0 C8 88 88 88 -00 -00 -00 ENDCHAR STARTCHAR o ENCODING 111 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 0 BITMAP -00 -00 -00 -00 70 88 88 88 70 -00 -00 -00 ENDCHAR STARTCHAR p ENCODING 112 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 -3 BITMAP -00 -00 -00 -00 F0 88 88 @@ -2202,12 +1606,8 @@ STARTCHAR q ENCODING 113 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 -3 BITMAP -00 -00 -00 -00 78 88 88 @@ -2221,145 +1621,95 @@ STARTCHAR r ENCODING 114 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 5 1 0 BITMAP -00 -00 -00 -00 -58 -60 -40 -40 -40 -00 -00 -00 +B0 +C0 +80 +80 +80 ENDCHAR STARTCHAR s ENCODING 115 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 0 BITMAP -00 -00 -00 -00 78 80 70 08 F0 -00 -00 -00 ENDCHAR STARTCHAR t ENCODING 116 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 8 1 0 BITMAP -00 -20 -20 -20 -70 -20 -20 -20 -18 -00 -00 -00 +40 +40 +40 +E0 +40 +40 +40 +30 ENDCHAR STARTCHAR u ENCODING 117 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 0 BITMAP -00 -00 -00 -00 88 88 88 98 68 -00 -00 -00 ENDCHAR STARTCHAR v ENCODING 118 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 0 BITMAP -00 -00 -00 -00 D8 50 50 20 20 -00 -00 -00 ENDCHAR STARTCHAR w ENCODING 119 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 0 BITMAP -00 -00 -00 -00 88 A8 A8 A8 50 -00 -00 -00 ENDCHAR STARTCHAR x ENCODING 120 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 0 BITMAP -00 -00 -00 -00 88 50 20 50 88 -00 -00 -00 ENDCHAR STARTCHAR y ENCODING 121 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 -3 BITMAP -00 -00 -00 -00 88 88 88 @@ -2373,161 +1723,111 @@ STARTCHAR z ENCODING 122 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 0 BITMAP -00 -00 -00 -00 F8 10 20 40 F8 -00 -00 -00 ENDCHAR STARTCHAR braceleft ENCODING 123 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 3 11 2 -2 BITMAP -08 -10 -10 -10 -10 20 -10 -10 -10 -10 -08 -00 +40 +40 +40 +40 +80 +40 +40 +40 +40 +20 ENDCHAR STARTCHAR bar ENCODING 124 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 1 11 2 -2 BITMAP -20 -20 -20 -20 -20 -20 -20 -20 -20 -20 -20 -00 +80 +80 +80 +80 +80 +80 +80 +80 +80 +80 +80 ENDCHAR STARTCHAR braceright ENCODING 125 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 3 11 1 -2 BITMAP +80 +40 +40 +40 40 20 -20 -20 -20 -10 -20 -20 -20 -20 40 -00 +40 +40 +40 +80 ENDCHAR STARTCHAR asciitilde ENCODING 126 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 3 0 2 BITMAP -00 -00 -00 -00 40 A8 10 -00 -00 -00 -00 -00 ENDCHAR -STARTCHAR space +STARTCHAR uni00A0 ENCODING 160 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 1 1 5 -3 BITMAP 00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 ENDCHAR STARTCHAR quoteleft ENCODING 161 -SWIDTH 480 0 +SWIDTH 1000 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 2 3 0 5 BITMAP -00 -10 -20 -30 -00 -00 -00 -00 -00 -00 -00 -00 +40 +40 +80 ENDCHAR STARTCHAR quoteright ENCODING 162 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 1 2 1 6 BITMAP -00 -30 -10 -20 -00 -00 -00 -00 -00 -00 -00 -00 +80 +80 ENDCHAR STARTCHAR sterling ENCODING 163 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 0 BITMAP -00 30 48 40 @@ -2536,112 +1836,82 @@ E0 40 48 B0 -00 -00 -00 ENDCHAR STARTCHAR Euro ENCODING 164 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 6 7 -1 0 BITMAP -00 -00 -30 -48 -E0 +38 +44 +F0 40 -E0 -48 -30 -00 -00 -00 +F0 +44 +38 ENDCHAR STARTCHAR uni20AF ENCODING 165 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -40 -E0 +88 50 -48 -48 -48 -E8 -D0 -00 -00 -00 +20 +70 +20 +70 +20 ENDCHAR STARTCHAR brokenbar ENCODING 166 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 1 7 2 0 BITMAP +80 +80 +80 00 -00 -20 -20 -20 -00 -20 -20 -20 -00 -00 -00 +80 +80 +80 ENDCHAR STARTCHAR section ENCODING 167 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 11 1 -2 BITMAP -30 -48 -40 -30 -48 -48 -48 -30 -08 -48 -30 -00 +60 +90 +80 +60 +90 +90 +90 +60 +10 +90 +60 ENDCHAR STARTCHAR dieresis ENCODING 168 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 3 2 1 6 BITMAP -00 -50 -50 -00 -00 -00 -00 -00 -00 -00 -00 -00 +A0 +A0 ENDCHAR STARTCHAR copyright ENCODING 169 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 6 8 0 0 BITMAP -00 78 84 B4 @@ -2650,132 +1920,90 @@ A4 B4 84 78 -00 -00 -00 ENDCHAR STARTCHAR uni037A ENCODING 170 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 7 1 2 BITMAP +60 +10 +70 +90 +70 00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -20 -30 +F0 ENDCHAR STARTCHAR guillemotleft ENCODING 171 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 1 BITMAP -00 -00 -00 28 50 A0 50 28 -00 -00 -00 -00 ENDCHAR STARTCHAR logicalnot ENCODING 172 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 2 1 2 BITMAP -00 -00 -00 -00 -00 -78 -08 -00 -00 -00 -00 -00 +F0 +10 ENDCHAR -STARTCHAR hyphen +STARTCHAR uni00AD ENCODING 173 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 1 1 3 BITMAP -00 -00 -00 -00 -00 -78 -00 -00 -00 -00 -00 -00 +F0 ENDCHAR -STARTCHAR afii00208 +STARTCHAR NameMe.174 +ENCODING 174 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 8 0 0 +BITMAP +78 +84 +B4 +AC +B4 +AC +84 +78 +ENDCHAR +STARTCHAR uni2015 ENCODING 175 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 1 0 6 BITMAP -00 -00 -00 -00 -00 -FC -00 -00 -00 -00 -00 -00 +F8 ENDCHAR STARTCHAR degree ENCODING 176 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 4 1 4 BITMAP -00 -30 -48 -48 -30 -00 -00 -00 -00 -00 -00 -00 +60 +90 +90 +60 ENDCHAR STARTCHAR plusminus ENCODING 177 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 20 20 F8 @@ -2783,94 +2011,57 @@ F8 20 00 F8 -00 -00 -00 ENDCHAR -STARTCHAR twosuperior +STARTCHAR uni00B2 ENCODING 178 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 3 5 1 4 BITMAP -60 -10 +C0 20 40 -70 -00 -00 -00 -00 -00 -00 -00 +80 +E0 ENDCHAR -STARTCHAR threesuperior +STARTCHAR uni00B3 ENCODING 179 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 3 5 1 4 BITMAP -60 -10 +C0 20 -10 -60 -00 -00 -00 -00 -00 -00 -00 +40 +20 +C0 ENDCHAR STARTCHAR tonos ENCODING 180 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 2 2 2 6 BITMAP -20 -20 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 +40 +80 ENDCHAR STARTCHAR dieresistonos ENCODING 181 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 3 3 0 6 BITMAP -20 -20 -50 -00 -00 -00 -00 -00 -00 -00 -00 +40 00 +A0 ENDCHAR STARTCHAR Alphatonos ENCODING 182 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 6 8 -1 0 BITMAP -00 -80 +40 90 28 44 @@ -2878,37 +2069,22 @@ BITMAP 7C 44 44 -00 -00 -00 ENDCHAR STARTCHAR periodcentered ENCODING 183 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 2 1 2 2 BITMAP -00 -00 -00 -00 -00 -00 -30 -00 -00 -00 -00 -00 +C0 ENDCHAR STARTCHAR Epsilontonos ENCODING 184 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 6 8 -1 0 BITMAP -00 -80 +40 BC 20 20 @@ -2916,170 +2092,132 @@ BC 20 20 3C -00 -00 -00 ENDCHAR STARTCHAR Etatonos ENCODING 185 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 7 8 -2 0 BITMAP -00 -80 -A4 -24 -24 -3C -24 -24 -24 -00 -00 -00 +40 +A2 +22 +22 +3E +22 +22 +22 ENDCHAR STARTCHAR Iotatonos ENCODING 186 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 8 -1 0 BITMAP -00 -80 -B8 +40 +90 +10 10 10 10 10 10 -38 -00 -00 -00 ENDCHAR STARTCHAR guillemotright ENCODING 187 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 1 BITMAP -00 -00 -00 A0 50 28 50 A0 -00 -00 -00 -00 ENDCHAR STARTCHAR Omicrontonos ENCODING 188 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 7 8 -2 0 BITMAP -00 -80 -98 -24 -24 -24 -24 -24 -18 -00 -00 -00 +40 +9C +22 +22 +22 +22 +22 +1C ENDCHAR STARTCHAR onehalf ENCODING 189 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 8 1 0 BITMAP -00 -40 -40 -40 -70 -08 +80 +80 +80 +E0 10 20 -38 -00 -00 -00 +40 +70 ENDCHAR STARTCHAR Upsilontonos ENCODING 190 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 0 BITMAP -00 -80 -A8 +C0 +40 +20 +C8 +10 28 -10 -10 -10 -10 -10 -00 -00 -00 +38 +08 ENDCHAR STARTCHAR Omegatonos ENCODING 191 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 6 9 -1 0 BITMAP -00 +40 80 -90 -28 +38 +44 44 44 44 28 6C -00 -00 -00 ENDCHAR STARTCHAR iotadieresistonos ENCODING 192 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 9 0 0 BITMAP -10 +40 20 00 -50 -00 -60 -20 -28 -10 -00 -00 -00 +70 +88 +88 +F8 +88 +88 ENDCHAR STARTCHAR Alpha ENCODING 193 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 20 50 88 @@ -3087,18 +2225,13 @@ BITMAP F8 88 88 -00 -00 -00 ENDCHAR STARTCHAR Beta ENCODING 194 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 F0 88 88 @@ -3106,56 +2239,41 @@ F0 88 88 F0 -00 -00 -00 ENDCHAR STARTCHAR Gamma ENCODING 195 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 -78 -40 -40 -40 -40 -40 -40 -00 -00 -00 +F8 +80 +80 +80 +80 +80 +80 ENDCHAR -STARTCHAR Delta +STARTCHAR uni0394 ENCODING 196 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -20 20 50 -50 -50 +88 +88 88 88 F8 -00 -00 -00 ENDCHAR STARTCHAR Epsilon ENCODING 197 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 F8 80 80 @@ -3163,18 +2281,13 @@ F0 80 80 F8 -00 -00 -00 ENDCHAR STARTCHAR Zeta ENCODING 198 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 F8 08 10 @@ -3182,18 +2295,13 @@ F8 40 80 F8 -00 -00 -00 ENDCHAR STARTCHAR Eta ENCODING 199 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 88 88 88 @@ -3201,56 +2309,41 @@ F8 88 88 88 -00 -00 -00 ENDCHAR STARTCHAR Theta ENCODING 200 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 70 88 88 -A8 +F8 88 88 70 -00 -00 -00 ENDCHAR STARTCHAR Iota ENCODING 201 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 1 7 2 0 BITMAP -00 -00 -F8 -20 -20 -20 -20 -20 -F8 -00 -00 -00 +80 +80 +80 +80 +80 +80 +80 ENDCHAR STARTCHAR Kappa ENCODING 202 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 88 90 A0 @@ -3258,37 +2351,27 @@ C0 A0 90 88 -00 -00 -00 ENDCHAR STARTCHAR Lambda ENCODING 203 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 -20 20 50 -50 88 88 88 -00 -00 -00 +88 +88 ENDCHAR STARTCHAR Mu ENCODING 204 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 88 D8 A8 @@ -3296,18 +2379,13 @@ A8 88 88 88 -00 -00 -00 ENDCHAR STARTCHAR Nu ENCODING 205 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 88 C8 C8 @@ -3315,18 +2393,13 @@ A8 98 98 88 -00 -00 -00 ENDCHAR STARTCHAR Xi ENCODING 206 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 F8 00 00 @@ -3334,18 +2407,13 @@ F8 00 00 F8 -00 -00 -00 ENDCHAR STARTCHAR Omicron ENCODING 207 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 70 88 88 @@ -3353,18 +2421,13 @@ BITMAP 88 88 70 -00 -00 -00 ENDCHAR STARTCHAR Pi ENCODING 208 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 F8 88 88 @@ -3372,18 +2435,13 @@ F8 88 88 88 -00 -00 -00 ENDCHAR STARTCHAR Rho ENCODING 209 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 F0 88 88 @@ -3391,37 +2449,35 @@ F0 80 80 80 -00 -00 +ENDCHAR +STARTCHAR NameMe.210 +ENCODING 210 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 1 1 4 0 +BITMAP 00 ENDCHAR STARTCHAR Sigma ENCODING 211 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 F8 +80 40 20 -10 -20 40 +80 F8 -00 -00 -00 ENDCHAR STARTCHAR Tau ENCODING 212 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 F8 20 20 @@ -3429,18 +2485,13 @@ F8 20 20 20 -00 -00 -00 ENDCHAR STARTCHAR Upsilon ENCODING 213 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 88 88 50 @@ -3448,37 +2499,27 @@ BITMAP 20 20 20 -00 -00 -00 ENDCHAR STARTCHAR Phi ENCODING 214 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -70 -20 70 A8 A8 +A8 +A8 70 20 -70 -00 -00 -00 ENDCHAR STARTCHAR Chi ENCODING 215 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 88 88 50 @@ -3486,37 +2527,27 @@ BITMAP 50 88 88 -00 -00 -00 ENDCHAR STARTCHAR Psi ENCODING 216 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 +A8 +A8 A8 A8 A8 70 20 -20 -20 -00 -00 -00 ENDCHAR -STARTCHAR Omega +STARTCHAR uni03A9 ENCODING 217 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 0 BITMAP -00 -00 70 88 88 @@ -3524,36 +2555,28 @@ BITMAP 88 50 D8 -00 -00 -00 ENDCHAR STARTCHAR Iotadieresis ENCODING 218 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 3 8 1 0 BITMAP +A0 00 -50 -00 -F8 -20 -20 -20 -20 -F8 -00 -00 -00 +E0 +40 +40 +40 +40 +E0 ENDCHAR STARTCHAR Upsilondieresis ENCODING 219 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 0 BITMAP -00 50 00 88 @@ -3562,424 +2585,321 @@ BITMAP 20 20 20 -00 -00 -00 ENDCHAR STARTCHAR alphatonos ENCODING 220 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 0 BITMAP -00 -20 +10 20 00 -68 -98 +78 +88 88 98 68 -00 -00 -00 ENDCHAR STARTCHAR epsilontonos ENCODING 221 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 8 0 0 BITMAP -00 -20 20 +40 00 70 -88 +80 60 -88 +80 70 -00 -00 -00 ENDCHAR STARTCHAR etatonos ENCODING 222 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 11 0 -3 BITMAP -00 -20 +10 20 00 -B0 -C8 -88 -88 -88 +F0 +48 +48 +48 +48 +08 08 08 -00 ENDCHAR STARTCHAR iotatonos ENCODING 223 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 3 8 1 0 BITMAP +40 +80 00 -20 -20 -00 +C0 +40 +40 +40 60 -20 -20 -28 -10 -00 -00 -00 ENDCHAR STARTCHAR upsilondieresistonos ENCODING 224 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 9 0 0 BITMAP 20 -20 -88 +40 +90 00 90 -88 -88 +90 +90 90 60 -00 -00 -00 ENDCHAR STARTCHAR alpha ENCODING 225 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 0 BITMAP -00 -00 -00 -00 -68 -98 +78 +88 88 98 68 -00 -00 -00 ENDCHAR STARTCHAR beta ENCODING 226 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 9 1 -1 BITMAP -00 -00 -70 -88 -88 -F0 -88 -88 -C8 -B0 +40 +A0 +A0 +E0 +90 +90 +90 +E0 80 -00 ENDCHAR STARTCHAR gamma ENCODING 227 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 -3 BITMAP -00 -00 -44 -A8 -28 -10 -10 -10 -10 -00 -00 -00 +88 +88 +50 +50 +20 +20 +20 +20 ENDCHAR STARTCHAR delta ENCODING 228 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 8 0 0 BITMAP -30 -48 -20 -10 -30 -48 -48 -48 -30 -00 -00 -00 +60 +80 +40 +60 +90 +90 +90 +60 ENDCHAR STARTCHAR epsilon ENCODING 229 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 5 0 0 BITMAP -00 -00 -00 -00 70 -88 +80 60 -88 +80 70 -00 -00 -00 ENDCHAR STARTCHAR zeta ENCODING 230 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 10 0 -2 BITMAP -00 -40 -38 +F0 20 40 -40 -40 -40 -38 -08 -30 -00 +80 +80 +80 +80 +60 +10 +60 ENDCHAR STARTCHAR eta ENCODING 231 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 -3 BITMAP -00 -00 -00 -00 -B0 -C8 -88 -88 -88 +F0 +48 +48 +48 +48 +08 08 08 -00 ENDCHAR STARTCHAR theta ENCODING 232 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 8 0 0 BITMAP -00 -00 -30 -48 -48 -78 -48 -48 -30 -00 -00 -00 +60 +90 +90 +F0 +90 +90 +90 +60 ENDCHAR STARTCHAR iota ENCODING 233 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 3 5 1 0 BITMAP -00 -00 -00 -00 +C0 +40 +40 +40 60 -20 -20 -28 -10 -00 -00 -00 ENDCHAR STARTCHAR kappa ENCODING 234 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 5 1 0 BITMAP -00 -00 -00 -00 -48 -50 -60 -50 -48 -00 -00 -00 +90 +A0 +E0 +90 +90 ENDCHAR STARTCHAR lambda ENCODING 235 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 0 BITMAP -00 40 -A0 +20 20 20 50 -50 +90 88 88 -00 -00 -00 ENDCHAR -STARTCHAR mu +STARTCHAR uni03BC ENCODING 236 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 7 0 -2 BITMAP -00 -00 -00 -00 -88 -88 -88 -98 +90 +90 +90 +90 E8 80 80 -00 ENDCHAR STARTCHAR nu ENCODING 237 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 0 BITMAP -00 -00 -00 -00 -D8 -50 -50 +C8 +48 +48 +30 20 -20 -00 -00 -00 ENDCHAR STARTCHAR xi ENCODING 238 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 11 0 -3 BITMAP -00 -80 70 80 80 -70 +60 80 80 -70 -08 -30 -00 +80 +60 +10 +60 +40 ENDCHAR STARTCHAR omicron ENCODING 239 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 0 BITMAP -00 -00 -00 -00 70 88 88 88 70 -00 -00 -00 ENDCHAR STARTCHAR pi ENCODING 240 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 5 0 0 BITMAP -00 -00 -00 -00 -F8 -88 -88 -88 -88 -00 -00 -00 +F0 +90 +90 +90 +90 ENDCHAR STARTCHAR rho ENCODING 241 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 -3 BITMAP -00 -00 -00 -00 70 88 88 88 -B0 +F0 80 80 80 @@ -3988,86 +2908,59 @@ STARTCHAR sigma1 ENCODING 242 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 8 0 -3 BITMAP -00 -00 -00 -00 -78 +70 80 -70 -08 -70 -00 -00 -00 +80 +80 +60 +10 +10 +60 ENDCHAR STARTCHAR sigma ENCODING 243 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 0 BITMAP -00 -00 -00 -00 78 90 -90 -90 -60 -00 -00 -00 +88 +88 +70 ENDCHAR STARTCHAR tau ENCODING 244 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 5 1 0 BITMAP -00 -00 -00 -00 -78 -20 -20 -28 -10 -00 -00 -00 +F0 +40 +40 +40 +30 ENDCHAR STARTCHAR upsilon ENCODING 245 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 5 0 0 BITMAP -00 -00 -00 90 -88 -88 -88 +90 +90 90 60 -00 -00 -00 ENDCHAR STARTCHAR phi ENCODING 246 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 -3 BITMAP -00 -00 30 A8 A8 @@ -4075,113 +2968,85 @@ A8 70 20 20 -00 -00 -00 +20 ENDCHAR STARTCHAR chi ENCODING 247 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 -3 BITMAP -00 -00 -00 -00 88 +48 50 20 +20 50 +90 88 -00 -00 -00 ENDCHAR STARTCHAR psi ENCODING 248 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 -3 BITMAP -00 -00 -00 -00 +20 +A8 A8 A8 70 20 20 -00 -00 -00 +20 ENDCHAR STARTCHAR omega ENCODING 249 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 5 0 0 BITMAP -00 -00 -00 -00 50 88 A8 A8 50 -00 -00 -00 ENDCHAR STARTCHAR iotadieresis ENCODING 250 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 3 7 1 0 BITMAP +A0 00 -00 -50 -00 +40 +40 +40 +40 60 -20 -20 -28 -10 -00 -00 -00 ENDCHAR STARTCHAR upsilondieresis ENCODING 251 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 7 0 0 BITMAP -00 -50 +A0 00 90 -88 -88 -88 +90 +90 90 60 -00 -00 -00 ENDCHAR STARTCHAR omicrontonos ENCODING 252 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 0 BITMAP -00 -20 +10 20 00 70 @@ -4189,37 +3054,29 @@ BITMAP 88 88 70 -00 -00 -00 ENDCHAR STARTCHAR upsilontonos ENCODING 253 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 4 8 0 0 BITMAP 20 -20 +40 00 90 -88 -88 -88 +90 +90 90 60 -00 -00 -00 ENDCHAR STARTCHAR omegatonos ENCODING 254 SWIDTH 480 0 DWIDTH 6 0 -BBX 6 12 0 -3 +BBX 5 8 0 0 BITMAP -00 -20 +10 20 00 50 @@ -4227,8 +3084,13 @@ BITMAP A8 A8 50 -00 -00 +ENDCHAR +STARTCHAR NameMe.255 +ENCODING 255 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 1 1 4 0 +BITMAP 00 ENDCHAR ENDFONT diff --git a/gui/themes/fonts/fixed5x8-iso-8859-7.bdf b/gui/themes/fonts/fixed5x8-iso-8859-7.bdf index da1374a465c..997efc25d63 100644 --- a/gui/themes/fonts/fixed5x8-iso-8859-7.bdf +++ b/gui/themes/fonts/fixed5x8-iso-8859-7.bdf @@ -1,15 +1,15 @@ STARTFONT 2.1 -COMMENT AUTOMATICALLY GENERATED FILE. DO NOT EDIT! -COMMENT Generated with 'ucs2any fixed5x8.bdf /usr/share/fonts/X11/util/map-ISO8859-7 ISO8859-7' -COMMENT from an ISO10646-1 encoded source BDF font. -COMMENT ucs2any by Ben Collver , 2003, based on -COMMENT ucs2any.pl by Markus Kuhn , 2000. -COMMENT Derived from 5x8.bdf,v 1.32 2006-01-05 20:03:17+00 mgk25 Rel - -COMMENT Send bug reports to Markus Kuhn FONT -Misc-Fixed-Medium-R-Normal--8-80-75-75-C-50-ISO8859-7 SIZE 11 75 75 FONTBOUNDINGBOX 5 8 0 -1 +COMMENT "Generated by fontforge, http://fontforge.sourceforge.net" +COMMENT "AUTOMATICALLY GENERATED FILE. DO NOT EDIT!" +COMMENT "Generated with 'ucs2any fixed5x8.bdf /usr/share/fonts/X11/util/map-ISO8859-7 ISO8859-7'" +COMMENT "from an ISO10646-1 encoded source BDF font." +COMMENT "ucs2any by Ben Collver , 2003, based on" +COMMENT "ucs2any.pl by Markus Kuhn , 2000." +COMMENT "Derived from 5x8.bdf,v 1.32 2006-01-05 20:03:17+00 mgk25 Rel" +COMMENT "Send bug reports to Markus Kuhn " STARTPROPERTIES 21 FONTNAME_REGISTRY "" FOUNDRY "Misc" @@ -38,31 +38,26 @@ STARTCHAR defaultchar ENCODING 0 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 A0 10 80 10 80 50 -00 ENDCHAR STARTCHAR uni25C6 ENCODING 1 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 5 0 0 BITMAP -00 -00 20 70 F8 70 20 -00 ENDCHAR STARTCHAR shade ENCODING 2 @@ -83,7 +78,7 @@ STARTCHAR uni2409 ENCODING 3 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 8 0 -1 BITMAP A0 A0 @@ -143,31 +138,23 @@ STARTCHAR degree ENCODING 7 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 3 1 3 BITMAP -00 -20 -50 -20 -00 -00 -00 -00 +40 +A0 +40 ENDCHAR STARTCHAR plusminus ENCODING 8 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 5 1 0 BITMAP +40 +E0 +40 00 -00 -20 -70 -20 -00 -70 -00 +E0 ENDCHAR STARTCHAR uni2424 ENCODING 9 @@ -203,26 +190,19 @@ STARTCHAR SF040000 ENCODING 11 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 4 0 3 BITMAP 20 20 20 E0 -00 -00 -00 -00 ENDCHAR STARTCHAR SF030000 ENCODING 12 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 5 0 -1 BITMAP -00 -00 -00 E0 20 20 @@ -233,31 +213,24 @@ STARTCHAR SF010000 ENCODING 13 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 5 2 -1 BITMAP -00 -00 -00 -38 -20 -20 -20 -20 +E0 +80 +80 +80 +80 ENDCHAR STARTCHAR SF020000 ENCODING 14 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 4 2 3 BITMAP -20 -20 -20 -38 -00 -00 -00 -00 +80 +80 +80 +E0 ENDCHAR STARTCHAR SF050000 ENCODING 15 @@ -278,97 +251,62 @@ STARTCHAR uni23BA ENCODING 16 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 1 0 6 BITMAP F8 -00 -00 -00 -00 -00 -00 -00 ENDCHAR STARTCHAR uni23BB ENCODING 17 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 1 0 5 BITMAP -00 F8 -00 -00 -00 -00 -00 -00 ENDCHAR STARTCHAR SF100000 ENCODING 18 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 1 0 3 BITMAP -00 -00 -00 F8 -00 -00 -00 -00 ENDCHAR STARTCHAR uni23BC ENCODING 19 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 1 0 0 BITMAP -00 -00 -00 -00 -00 -00 F8 -00 ENDCHAR STARTCHAR uni23BD ENCODING 20 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 1 0 -1 BITMAP -00 -00 -00 -00 -00 -00 -00 F8 ENDCHAR STARTCHAR SF080000 ENCODING 21 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 8 2 -1 BITMAP -20 -20 -20 -38 -20 -20 -20 -20 +80 +80 +80 +E0 +80 +80 +80 +80 ENDCHAR STARTCHAR SF090000 ENCODING 22 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 8 0 -1 BITMAP 20 20 @@ -383,26 +321,19 @@ STARTCHAR SF070000 ENCODING 23 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 4 0 3 BITMAP 20 20 20 F8 -00 -00 -00 -00 ENDCHAR STARTCHAR SF060000 ENCODING 24 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 5 0 -1 BITMAP -00 -00 -00 F8 20 20 @@ -413,157 +344,123 @@ STARTCHAR SF110000 ENCODING 25 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 1 8 2 -1 BITMAP -20 -20 -20 -20 -20 -20 -20 -20 +80 +80 +80 +80 +80 +80 +80 +80 ENDCHAR STARTCHAR lessequal ENCODING 26 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 6 1 0 BITMAP -00 -10 20 40 +80 +40 20 -10 -70 -00 +E0 ENDCHAR STARTCHAR greaterequal ENCODING 27 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 6 1 0 BITMAP -00 +80 40 20 -10 -20 40 -70 -00 +80 +E0 ENDCHAR STARTCHAR pi ENCODING 28 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 4 0 0 BITMAP -00 -00 -00 F8 50 50 50 -00 ENDCHAR STARTCHAR notequal ENCODING 29 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 5 0 0 BITMAP -00 -00 20 F0 60 F0 40 -00 ENDCHAR STARTCHAR sterling ENCODING 30 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 20 50 E0 40 50 A0 -00 ENDCHAR STARTCHAR periodcentered ENCODING 31 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 1 1 2 2 BITMAP -00 -00 -00 -00 -20 -00 -00 -00 +80 ENDCHAR STARTCHAR space ENCODING 32 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 1 1 4 -1 BITMAP 00 -00 -00 -00 -00 -00 -00 -00 ENDCHAR STARTCHAR exclam ENCODING 33 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 1 6 2 0 BITMAP +80 +80 +80 +80 00 -20 -20 -20 -20 -00 -20 -00 +80 ENDCHAR STARTCHAR quotedbl ENCODING 34 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 3 1 3 BITMAP -00 -50 -50 -50 -00 -00 -00 -00 +A0 +A0 +A0 ENDCHAR STARTCHAR numbersign ENCODING 35 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 7 0 0 BITMAP 50 50 @@ -572,13 +469,12 @@ F8 F8 50 50 -00 ENDCHAR STARTCHAR dollar ENCODING 36 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 7 0 0 BITMAP 20 70 @@ -587,28 +483,24 @@ A0 28 70 20 -00 ENDCHAR STARTCHAR percent ENCODING 37 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 5 1 1 BITMAP -00 +80 +A0 40 -50 +A0 20 -50 -10 -00 -00 ENDCHAR STARTCHAR ampersand ENCODING 38 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 7 0 0 BITMAP 40 A0 @@ -617,382 +509,311 @@ A0 A0 A0 50 -00 ENDCHAR STARTCHAR quotesingle ENCODING 39 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 1 3 2 3 BITMAP -00 -20 -20 -20 -00 -00 -00 -00 +80 +80 +80 ENDCHAR STARTCHAR parenleft ENCODING 40 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 2 6 1 0 BITMAP -00 -20 40 +80 +80 +80 +80 40 -40 -40 -20 -00 ENDCHAR STARTCHAR parenright ENCODING 41 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 2 6 1 0 BITMAP -00 +80 40 -20 -20 -20 -20 40 -00 +40 +40 +80 ENDCHAR STARTCHAR asterisk ENCODING 42 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 5 0 0 BITMAP -00 -00 90 60 F0 60 90 -00 ENDCHAR STARTCHAR plus ENCODING 43 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 5 0 0 BITMAP -00 -00 20 20 F8 20 20 -00 ENDCHAR STARTCHAR comma ENCODING 44 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 3 1 -1 BITMAP -00 -00 -00 -00 -00 -30 -20 +60 40 +80 ENDCHAR STARTCHAR hyphen ENCODING 45 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 1 0 2 BITMAP -00 -00 -00 -00 F0 -00 -00 -00 ENDCHAR STARTCHAR period ENCODING 46 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 3 1 -1 BITMAP -00 -00 -00 -00 -00 -20 -70 -20 +40 +E0 +40 ENDCHAR STARTCHAR slash ENCODING 47 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 10 10 20 40 80 80 -00 ENDCHAR STARTCHAR zero ENCODING 48 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 6 1 0 BITMAP -00 -20 -50 -50 -50 -50 -20 -00 +40 +A0 +A0 +A0 +A0 +40 ENDCHAR STARTCHAR one ENCODING 49 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 6 1 0 BITMAP -00 -20 -60 -20 -20 -20 -70 -00 +40 +C0 +40 +40 +40 +E0 ENDCHAR STARTCHAR two ENCODING 50 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 60 90 10 60 80 F0 -00 ENDCHAR STARTCHAR three ENCODING 51 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 F0 20 60 10 90 60 -00 ENDCHAR STARTCHAR four ENCODING 52 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 20 60 A0 F0 20 20 -00 ENDCHAR STARTCHAR five ENCODING 53 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 F0 80 E0 10 90 60 -00 ENDCHAR STARTCHAR six ENCODING 54 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 60 80 E0 90 90 60 -00 ENDCHAR STARTCHAR seven ENCODING 55 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 F0 10 20 20 40 40 -00 ENDCHAR STARTCHAR eight ENCODING 56 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 60 90 60 90 90 60 -00 ENDCHAR STARTCHAR nine ENCODING 57 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 60 90 90 70 10 60 -00 ENDCHAR STARTCHAR colon ENCODING 58 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 2 5 1 0 BITMAP +C0 +C0 00 -00 -60 -60 -00 -60 -60 -00 +C0 +C0 ENDCHAR STARTCHAR semicolon ENCODING 59 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 6 1 -1 BITMAP +60 +60 00 -00 -30 -30 -00 -30 -20 +60 40 +80 ENDCHAR STARTCHAR less ENCODING 60 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 6 1 0 BITMAP -00 -10 20 40 +80 +80 40 20 -10 -00 ENDCHAR STARTCHAR equal ENCODING 61 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 3 0 1 BITMAP -00 -00 -00 F0 00 F0 -00 -00 ENDCHAR STARTCHAR greater ENCODING 62 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 6 1 0 BITMAP -00 +80 40 20 -10 -10 20 40 -00 +80 ENDCHAR STARTCHAR question ENCODING 63 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 6 1 0 BITMAP -00 -20 -50 -10 -20 -00 +40 +A0 20 +40 00 +40 ENDCHAR STARTCHAR at ENCODING 64 @@ -1013,249 +834,216 @@ STARTCHAR A ENCODING 65 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 60 90 90 F0 90 90 -00 ENDCHAR STARTCHAR B ENCODING 66 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 E0 90 E0 90 90 E0 -00 ENDCHAR STARTCHAR C ENCODING 67 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 60 90 80 80 90 60 -00 ENDCHAR STARTCHAR D ENCODING 68 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 E0 90 90 90 90 E0 -00 ENDCHAR STARTCHAR E ENCODING 69 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 F0 80 E0 80 80 F0 -00 ENDCHAR STARTCHAR F ENCODING 70 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 F0 80 E0 80 80 80 -00 ENDCHAR STARTCHAR G ENCODING 71 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 60 90 80 B0 90 60 -00 ENDCHAR STARTCHAR H ENCODING 72 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 90 90 F0 90 90 90 -00 ENDCHAR STARTCHAR I ENCODING 73 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 6 1 0 BITMAP -00 -70 -20 -20 -20 -20 -70 -00 +E0 +40 +40 +40 +40 +E0 ENDCHAR STARTCHAR J ENCODING 74 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 70 20 20 20 A0 40 -00 ENDCHAR STARTCHAR K ENCODING 75 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 90 A0 C0 A0 A0 90 -00 ENDCHAR STARTCHAR L ENCODING 76 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 80 80 80 80 80 F0 -00 ENDCHAR STARTCHAR M ENCODING 77 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 90 F0 F0 90 90 90 -00 ENDCHAR STARTCHAR N ENCODING 78 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 90 D0 F0 B0 B0 90 -00 ENDCHAR STARTCHAR O ENCODING 79 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 60 90 90 90 90 60 -00 ENDCHAR STARTCHAR P ENCODING 80 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 E0 90 90 E0 80 80 -00 ENDCHAR STARTCHAR Q ENCODING 81 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 7 0 -1 BITMAP -00 60 90 90 @@ -1268,326 +1056,262 @@ STARTCHAR R ENCODING 82 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 E0 90 90 E0 90 90 -00 ENDCHAR STARTCHAR S ENCODING 83 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 60 90 40 20 90 60 -00 ENDCHAR STARTCHAR T ENCODING 84 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 6 1 0 BITMAP -00 -70 -20 -20 -20 -20 -20 -00 +E0 +40 +40 +40 +40 +40 ENDCHAR STARTCHAR U ENCODING 85 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 90 90 90 90 90 60 -00 ENDCHAR STARTCHAR V ENCODING 86 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 90 90 90 90 60 60 -00 ENDCHAR STARTCHAR W ENCODING 87 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 90 90 90 F0 F0 90 -00 ENDCHAR STARTCHAR X ENCODING 88 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 90 90 60 60 90 90 -00 ENDCHAR STARTCHAR Y ENCODING 89 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 6 0 0 BITMAP -00 88 88 50 20 20 20 -00 ENDCHAR STARTCHAR Z ENCODING 90 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 F0 10 20 40 80 F0 -00 ENDCHAR STARTCHAR bracketleft ENCODING 91 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 6 1 0 BITMAP -00 -70 -40 -40 -40 -40 -70 -00 +E0 +80 +80 +80 +80 +E0 ENDCHAR STARTCHAR backslash ENCODING 92 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 80 80 40 20 10 10 -00 ENDCHAR STARTCHAR bracketright ENCODING 93 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 6 1 0 BITMAP -00 -70 -10 -10 -10 -10 -70 -00 +E0 +20 +20 +20 +20 +E0 ENDCHAR STARTCHAR asciicircum ENCODING 94 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 2 1 4 BITMAP -00 -20 -50 -00 -00 -00 -00 -00 +40 +A0 ENDCHAR STARTCHAR underscore ENCODING 95 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 1 0 -1 BITMAP -00 -00 -00 -00 -00 -00 -00 F0 ENDCHAR STARTCHAR grave ENCODING 96 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 2 2 1 4 BITMAP -00 +80 40 -20 -00 -00 -00 -00 -00 ENDCHAR STARTCHAR a ENCODING 97 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 4 0 0 BITMAP -00 -00 -00 70 90 90 70 -00 ENDCHAR STARTCHAR b ENCODING 98 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 80 80 E0 90 90 E0 -00 ENDCHAR STARTCHAR c ENCODING 99 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 4 1 0 BITMAP -00 -00 -00 -30 -40 -40 -30 -00 +60 +80 +80 +60 ENDCHAR STARTCHAR d ENCODING 100 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 10 10 70 90 90 70 -00 ENDCHAR STARTCHAR e ENCODING 101 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 4 0 0 BITMAP -00 -00 -00 60 B0 C0 60 -00 ENDCHAR STARTCHAR f ENCODING 102 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 20 50 40 E0 40 40 -00 ENDCHAR STARTCHAR g ENCODING 103 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 5 0 -1 BITMAP -00 -00 -00 60 90 70 @@ -1598,131 +1322,107 @@ STARTCHAR h ENCODING 104 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 80 80 E0 90 90 90 -00 ENDCHAR STARTCHAR i ENCODING 105 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 6 1 0 BITMAP +40 00 -20 -00 -60 -20 -20 -70 -00 +C0 +40 +40 +E0 ENDCHAR STARTCHAR j ENCODING 106 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 7 1 -1 BITMAP -00 -10 -00 -10 -10 -10 -50 20 +00 +20 +20 +20 +A0 +40 ENDCHAR STARTCHAR k ENCODING 107 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 80 80 90 E0 90 90 -00 ENDCHAR STARTCHAR l ENCODING 108 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 6 1 0 BITMAP -00 -60 -20 -20 -20 -20 -70 -00 +C0 +40 +40 +40 +40 +E0 ENDCHAR STARTCHAR m ENCODING 109 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 4 0 0 BITMAP -00 -00 -00 D0 A8 A8 A8 -00 ENDCHAR STARTCHAR n ENCODING 110 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 4 0 0 BITMAP -00 -00 -00 E0 90 90 90 -00 ENDCHAR STARTCHAR o ENCODING 111 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 4 0 0 BITMAP -00 -00 -00 60 90 90 60 -00 ENDCHAR STARTCHAR p ENCODING 112 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 5 0 -1 BITMAP -00 -00 -00 E0 90 E0 @@ -1733,11 +1433,8 @@ STARTCHAR q ENCODING 113 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 5 0 -1 BITMAP -00 -00 -00 70 90 70 @@ -1748,116 +1445,87 @@ STARTCHAR r ENCODING 114 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 4 0 0 BITMAP -00 -00 -00 A0 D0 80 80 -00 ENDCHAR STARTCHAR s ENCODING 115 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 4 1 0 BITMAP -00 -00 -00 -30 60 -10 -60 -00 +C0 +20 +C0 ENDCHAR STARTCHAR t ENCODING 116 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 40 40 E0 40 50 20 -00 ENDCHAR STARTCHAR u ENCODING 117 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 4 0 0 BITMAP -00 -00 -00 90 90 90 70 -00 ENDCHAR STARTCHAR v ENCODING 118 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 4 1 0 BITMAP -00 -00 -00 -50 -50 -50 -20 -00 +A0 +A0 +A0 +40 ENDCHAR STARTCHAR w ENCODING 119 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 4 0 0 BITMAP -00 -00 -00 88 A8 A8 50 -00 ENDCHAR STARTCHAR x ENCODING 120 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 4 0 0 BITMAP -00 -00 -00 90 60 60 90 -00 ENDCHAR STARTCHAR y ENCODING 121 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 5 0 -1 BITMAP -00 -00 -00 90 90 70 @@ -1868,22 +1536,18 @@ STARTCHAR z ENCODING 122 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 4 0 0 BITMAP -00 -00 -00 F0 20 40 F0 -00 ENDCHAR STARTCHAR braceleft ENCODING 123 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 7 0 0 BITMAP 30 40 @@ -1892,28 +1556,25 @@ C0 20 40 30 -00 ENDCHAR STARTCHAR bar ENCODING 124 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 1 6 2 0 BITMAP -00 -20 -20 -20 -20 -20 -20 -00 +80 +80 +80 +80 +80 +80 ENDCHAR STARTCHAR braceright ENCODING 125 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 7 0 0 BITMAP C0 20 @@ -1922,88 +1583,62 @@ C0 40 20 C0 -00 ENDCHAR STARTCHAR asciitilde ENCODING 126 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 2 0 4 BITMAP -00 50 A0 -00 -00 -00 -00 -00 ENDCHAR STARTCHAR space ENCODING 160 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 1 1 4 -1 BITMAP 00 -00 -00 -00 -00 -00 -00 -00 ENDCHAR STARTCHAR quoteleft ENCODING 161 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 2 3 1 4 BITMAP -20 40 -60 -00 -00 -00 -00 -00 +80 +C0 ENDCHAR STARTCHAR quoteright ENCODING 162 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 2 3 1 4 BITMAP -60 -20 +C0 40 -00 -00 -00 -00 -00 +80 ENDCHAR STARTCHAR sterling ENCODING 163 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 20 50 E0 40 50 A0 -00 ENDCHAR STARTCHAR Euro ENCODING 164 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 7 0 0 BITMAP 30 40 @@ -2012,13 +1647,12 @@ E0 E0 40 30 -00 ENDCHAR STARTCHAR uni20AF ENCODING 165 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 7 0 0 BITMAP 40 E0 @@ -2027,28 +1661,26 @@ E0 50 D0 E0 -00 ENDCHAR STARTCHAR brokenbar ENCODING 166 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 1 7 2 0 BITMAP -20 -20 -20 -00 -20 -20 -20 +80 +80 +80 00 +80 +80 +80 ENDCHAR STARTCHAR section ENCODING 167 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 7 0 0 BITMAP 70 80 @@ -2057,208 +1689,143 @@ E0 70 10 E0 -00 ENDCHAR STARTCHAR dieresis ENCODING 168 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 1 1 5 BITMAP -00 -50 -00 -00 -00 -00 -00 -00 +A0 ENDCHAR STARTCHAR copyright ENCODING 169 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 6 0 0 BITMAP -00 70 A8 C8 C8 A8 70 -00 ENDCHAR STARTCHAR uni037A ENCODING 170 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 2 2 1 -1 BITMAP -00 -00 -00 -00 -00 -00 -40 -60 +80 +C0 ENDCHAR STARTCHAR guillemotleft ENCODING 171 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 3 0 1 BITMAP -00 -00 -00 50 A0 50 -00 -00 ENDCHAR STARTCHAR logicalnot ENCODING 172 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 3 1 0 BITMAP -00 -00 -00 -00 -70 -10 -10 -00 +E0 +20 +20 ENDCHAR STARTCHAR hyphen ENCODING 173 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 1 1 2 BITMAP -00 -00 -00 -00 -70 -00 -00 -00 +E0 ENDCHAR STARTCHAR afii00208 ENCODING 175 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 1 0 2 BITMAP -00 -00 -00 -00 F8 -00 -00 -00 ENDCHAR STARTCHAR degree ENCODING 176 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 3 1 3 BITMAP -00 -20 -50 -20 -00 -00 -00 -00 +40 +A0 +40 ENDCHAR STARTCHAR plusminus ENCODING 177 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 5 1 0 BITMAP +40 +E0 +40 00 -00 -20 -70 -20 -00 -70 -00 +E0 ENDCHAR STARTCHAR twosuperior ENCODING 178 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 5 1 2 BITMAP +40 +A0 20 -50 -10 -20 -70 -00 -00 -00 +40 +E0 ENDCHAR STARTCHAR threesuperior ENCODING 179 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 5 1 2 BITMAP -60 -10 -60 -10 -60 -00 -00 -00 +C0 +20 +C0 +20 +C0 ENDCHAR STARTCHAR tonos ENCODING 180 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 2 2 1 5 BITMAP -20 40 -00 -00 -00 -00 -00 -00 +80 ENDCHAR STARTCHAR dieresistonos ENCODING 181 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 3 1 4 BITMAP -10 20 -50 -00 -00 -00 -00 -00 +40 +A0 ENDCHAR STARTCHAR Alphatonos ENCODING 182 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 7 0 0 BITMAP 20 40 @@ -2267,28 +1834,20 @@ BITMAP F0 90 90 -00 ENDCHAR STARTCHAR periodcentered ENCODING 183 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 1 1 2 2 BITMAP -00 -00 -00 -00 -20 -00 -00 -00 +80 ENDCHAR STARTCHAR Epsilontonos ENCODING 184 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 7 0 0 BITMAP 20 40 @@ -2297,13 +1856,12 @@ F0 E0 80 F0 -00 ENDCHAR STARTCHAR Etatonos ENCODING 185 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 7 0 0 BITMAP 20 40 @@ -2312,43 +1870,36 @@ BITMAP F0 90 90 -00 ENDCHAR STARTCHAR Iotatonos ENCODING 186 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 7 1 0 BITMAP -10 20 -70 -20 -20 -20 -70 -00 +40 +E0 +40 +40 +40 +E0 ENDCHAR STARTCHAR guillemotright ENCODING 187 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 3 0 1 BITMAP -00 -00 -00 A0 50 A0 -00 -00 ENDCHAR STARTCHAR Omicrontonos ENCODING 188 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 7 0 0 BITMAP 20 40 @@ -2357,13 +1908,12 @@ BITMAP 90 90 60 -00 ENDCHAR STARTCHAR onehalf ENCODING 189 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 7 0 0 BITMAP 80 80 @@ -2372,13 +1922,12 @@ D0 10 20 70 -00 ENDCHAR STARTCHAR Upsilontonos ENCODING 190 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 7 0 0 BITMAP 10 20 @@ -2387,13 +1936,12 @@ BITMAP 20 20 20 -00 ENDCHAR STARTCHAR Omegatonos ENCODING 191 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 7 0 0 BITMAP 10 20 @@ -2402,13 +1950,12 @@ BITMAP 88 50 D8 -00 ENDCHAR STARTCHAR iotadieresistonos ENCODING 192 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 7 0 0 BITMAP 20 40 @@ -2417,403 +1964,352 @@ A0 40 50 20 -00 ENDCHAR STARTCHAR Alpha ENCODING 193 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 60 90 90 F0 90 90 -00 ENDCHAR STARTCHAR Beta ENCODING 194 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 E0 90 E0 90 90 E0 -00 ENDCHAR STARTCHAR Gamma ENCODING 195 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 F0 80 80 80 80 80 -00 ENDCHAR STARTCHAR Delta ENCODING 196 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 6 0 0 BITMAP -00 20 20 50 50 88 F8 -00 ENDCHAR STARTCHAR Epsilon ENCODING 197 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 F0 80 E0 80 80 F0 -00 ENDCHAR STARTCHAR Zeta ENCODING 198 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 F0 10 20 40 80 F0 -00 ENDCHAR STARTCHAR Eta ENCODING 199 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 90 90 F0 90 90 90 -00 ENDCHAR STARTCHAR Theta ENCODING 200 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 60 90 F0 90 90 60 -00 ENDCHAR STARTCHAR Iota ENCODING 201 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 6 1 0 BITMAP -00 -70 -20 -20 -20 -20 -70 -00 +E0 +40 +40 +40 +40 +E0 ENDCHAR STARTCHAR Kappa ENCODING 202 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 90 A0 C0 A0 A0 90 -00 ENDCHAR STARTCHAR Lambda ENCODING 203 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 60 60 90 90 90 90 -00 ENDCHAR STARTCHAR Mu ENCODING 204 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 90 F0 F0 90 90 90 -00 ENDCHAR STARTCHAR Nu ENCODING 205 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 90 D0 F0 B0 B0 90 -00 ENDCHAR STARTCHAR Xi ENCODING 206 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 F0 00 60 00 00 F0 -00 ENDCHAR STARTCHAR Omicron ENCODING 207 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 60 90 90 90 90 60 -00 ENDCHAR STARTCHAR Pi ENCODING 208 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 F0 90 90 90 90 90 -00 ENDCHAR STARTCHAR Rho ENCODING 209 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 E0 90 90 E0 80 80 -00 ENDCHAR STARTCHAR Sigma ENCODING 211 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 F0 80 40 40 80 F0 -00 ENDCHAR STARTCHAR Tau ENCODING 212 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 6 1 0 BITMAP -00 -70 -20 -20 -20 -20 -20 -00 +E0 +40 +40 +40 +40 +40 ENDCHAR STARTCHAR Upsilon ENCODING 213 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 6 0 0 BITMAP -00 88 88 50 20 20 20 -00 ENDCHAR STARTCHAR Phi ENCODING 214 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 6 0 0 BITMAP -00 20 70 A8 A8 70 20 -00 ENDCHAR STARTCHAR Chi ENCODING 215 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 90 90 60 60 90 90 -00 ENDCHAR STARTCHAR Psi ENCODING 216 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 6 0 0 BITMAP -00 A8 A8 70 20 20 20 -00 ENDCHAR STARTCHAR Omega ENCODING 217 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 6 0 0 BITMAP -00 70 88 88 88 50 D8 -00 ENDCHAR STARTCHAR Iotadieresis ENCODING 218 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 7 1 0 BITMAP -50 -00 -70 -20 -20 -20 -70 +A0 00 +E0 +40 +40 +40 +E0 ENDCHAR STARTCHAR Upsilondieresis ENCODING 219 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 7 1 0 BITMAP -50 -00 -50 -50 -20 -20 -20 +A0 00 +A0 +A0 +40 +40 +40 ENDCHAR STARTCHAR alphatonos ENCODING 220 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 7 0 0 BITMAP 20 40 @@ -2822,13 +2318,12 @@ BITMAP 90 90 70 -00 ENDCHAR STARTCHAR epsilontonos ENCODING 221 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 7 0 0 BITMAP 20 40 @@ -2837,13 +2332,12 @@ BITMAP E0 80 70 -00 ENDCHAR STARTCHAR etatonos ENCODING 222 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 8 0 -1 BITMAP 20 40 @@ -2858,22 +2352,21 @@ STARTCHAR iotatonos ENCODING 223 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 7 1 0 BITMAP -20 40 +80 00 +80 +80 +A0 40 -40 -50 -20 -00 ENDCHAR STARTCHAR upsilondieresistonos ENCODING 224 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 7 0 0 BITMAP 20 D0 @@ -2882,30 +2375,24 @@ D0 90 90 60 -00 ENDCHAR STARTCHAR alpha ENCODING 225 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 4 0 0 BITMAP -00 -00 -00 70 90 90 70 -00 ENDCHAR STARTCHAR beta ENCODING 226 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 7 0 -1 BITMAP -00 60 90 E0 @@ -2918,55 +2405,44 @@ STARTCHAR gamma ENCODING 227 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 5 1 -1 BITMAP -00 -00 -00 -50 -50 -50 -20 -20 +A0 +A0 +A0 +40 +40 ENDCHAR STARTCHAR delta ENCODING 228 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 60 80 60 90 90 60 -00 ENDCHAR STARTCHAR epsilon ENCODING 229 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 4 0 0 BITMAP -00 -00 -00 70 E0 80 70 -00 ENDCHAR STARTCHAR zeta ENCODING 230 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 -1 BITMAP -00 -00 F0 40 80 @@ -2978,11 +2454,8 @@ STARTCHAR eta ENCODING 231 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 5 0 -1 BITMAP -00 -00 -00 A0 D0 90 @@ -2993,71 +2466,56 @@ STARTCHAR theta ENCODING 232 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 60 90 F0 90 90 60 -00 ENDCHAR STARTCHAR iota ENCODING 233 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 4 1 0 BITMAP -00 -00 -00 +80 +80 +A0 40 -40 -50 -20 -00 ENDCHAR STARTCHAR kappa ENCODING 234 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 4 0 0 BITMAP -00 -00 -00 90 E0 A0 90 -00 ENDCHAR STARTCHAR lambda ENCODING 235 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 E0 10 70 90 90 90 -00 ENDCHAR STARTCHAR mu ENCODING 236 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 5 0 -1 BITMAP -00 -00 -00 90 90 90 @@ -3068,24 +2526,19 @@ STARTCHAR nu ENCODING 237 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 4 1 0 BITMAP -00 -00 -00 -50 -50 -20 -20 -00 +A0 +A0 +40 +40 ENDCHAR STARTCHAR xi ENCODING 238 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 7 0 -1 BITMAP -00 F0 40 60 @@ -3098,41 +2551,30 @@ STARTCHAR omicron ENCODING 239 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 4 0 0 BITMAP -00 -00 -00 60 90 90 60 -00 ENDCHAR STARTCHAR pi ENCODING 240 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 4 0 0 BITMAP -00 -00 -00 F8 50 50 50 -00 ENDCHAR STARTCHAR rho ENCODING 241 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 5 0 -1 BITMAP -00 -00 -00 60 90 90 @@ -3143,11 +2585,8 @@ STARTCHAR sigma1 ENCODING 242 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 5 0 -1 BITMAP -00 -00 -00 60 80 60 @@ -3158,56 +2597,41 @@ STARTCHAR sigma ENCODING 243 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 4 0 0 BITMAP -00 -00 -00 70 90 90 60 -00 ENDCHAR STARTCHAR tau ENCODING 244 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 4 0 0 BITMAP -00 -00 -00 F0 40 50 20 -00 ENDCHAR STARTCHAR upsilon ENCODING 245 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 4 0 0 BITMAP -00 -00 -00 90 90 90 60 -00 ENDCHAR STARTCHAR phi ENCODING 246 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 5 0 -1 BITMAP -00 -00 -00 B0 A8 A8 @@ -3218,26 +2642,20 @@ STARTCHAR chi ENCODING 247 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 3 5 1 -1 BITMAP -00 -00 -00 -50 -50 -20 -50 -50 +A0 +A0 +40 +A0 +A0 ENDCHAR STARTCHAR psi ENCODING 248 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 5 0 -1 BITMAP -00 -00 -00 A8 A8 70 @@ -3248,52 +2666,44 @@ STARTCHAR omega ENCODING 249 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 4 0 0 BITMAP -00 -00 -00 88 A8 A8 50 -00 ENDCHAR STARTCHAR iotadieresis ENCODING 250 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 A0 00 40 40 50 20 -00 ENDCHAR STARTCHAR upsilondieresis ENCODING 251 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 6 0 0 BITMAP -00 90 00 90 90 90 60 -00 ENDCHAR STARTCHAR omicrontonos ENCODING 252 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 7 0 0 BITMAP 20 40 @@ -3302,13 +2712,12 @@ BITMAP 90 90 60 -00 ENDCHAR STARTCHAR upsilontonos ENCODING 253 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 4 7 0 0 BITMAP 20 40 @@ -3317,13 +2726,12 @@ BITMAP 90 90 60 -00 ENDCHAR STARTCHAR omegatonos ENCODING 254 SWIDTH 436 0 DWIDTH 5 0 -BBX 5 8 0 -1 +BBX 5 7 0 0 BITMAP 10 20 @@ -3332,6 +2740,5 @@ BITMAP A8 A8 50 -00 ENDCHAR ENDFONT diff --git a/gui/themes/modern.zip b/gui/themes/modern.zip index 1737598757e..808917702dd 100644 Binary files a/gui/themes/modern.zip and b/gui/themes/modern.zip differ diff --git a/gui/themes/modern/THEMERC b/gui/themes/modern/THEMERC index fa43a0da9a1..48048d3d00a 100644 --- a/gui/themes/modern/THEMERC +++ b/gui/themes/modern/THEMERC @@ -1 +1 @@ -[SCUMMVM_STX0.8.27:ResidualVM Modern Theme:No Author] +[SCUMMVM_STX0.8.28:ResidualVM Modern Theme:No Author] diff --git a/gui/themes/modern/modern_gfx.stx b/gui/themes/modern/modern_gfx.stx index 1aa9feeb377..821222d0438 100644 --- a/gui/themes/modern/modern_gfx.stx +++ b/gui/themes/modern/modern_gfx.stx @@ -86,6 +86,9 @@ + @@ -212,7 +215,7 @@ /> @@ -860,6 +863,361 @@ /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1729,4 +1734,6 @@ + + diff --git a/gui/themes/modern/modern_layout_lowres.stx b/gui/themes/modern/modern_layout_lowres.stx index 6ec4b585381..125eeed4ec0 100644 --- a/gui/themes/modern/modern_layout_lowres.stx +++ b/gui/themes/modern/modern_layout_lowres.stx @@ -43,6 +43,8 @@ + + @@ -1707,4 +1709,6 @@ + + diff --git a/gui/unknown-game-dialog.cpp b/gui/unknown-game-dialog.cpp index 54f6bcab124..999d860b8b1 100644 --- a/gui/unknown-game-dialog.cpp +++ b/gui/unknown-game-dialog.cpp @@ -198,13 +198,13 @@ Common::String UnknownGameDialog::generateBugtrackerURL() { Common::String report = generateUnknownGameReport(_detectedGame, false, false); report = encodeUrlString(report); - Common::String engineName = encodeUrlString(_detectedGame.engineName); + Common::String engineId = encodeUrlString(_detectedGame.engineId); return Common::String::format( "https://www.scummvm.org/unknowngame?" "engine=%s" "&description=%s", - engineName.c_str(), + engineId.c_str(), report.c_str()); } diff --git a/gui/widget.cpp b/gui/widget.cpp index 2ac73dd4ca8..aa99b2f66ae 100644 --- a/gui/widget.cpp +++ b/gui/widget.cpp @@ -32,6 +32,7 @@ #include "gui/ThemeEval.h" #include "gui/dialog.h" +#include "gui/widgets/popup.h" namespace GUI { @@ -308,7 +309,7 @@ void StaticTextWidget::drawWidget() { ButtonWidget::ButtonWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &label, const char *tooltip, uint32 cmd, uint8 hotkey) : StaticTextWidget(boss, x, y, w, h, cleanupHotkey(label), Graphics::kTextAlignCenter, tooltip), CommandSender(boss), - _cmd(cmd), _hotkey(hotkey), _lastTime(0), _duringPress(false) { + _cmd(cmd), _hotkey(hotkey), _duringPress(false) { if (hotkey == 0) _hotkey = parseHotkey(label); @@ -319,7 +320,7 @@ ButtonWidget::ButtonWidget(GuiObject *boss, int x, int y, int w, int h, const Co ButtonWidget::ButtonWidget(GuiObject *boss, const Common::String &name, const Common::String &label, const char *tooltip, uint32 cmd, uint8 hotkey) : StaticTextWidget(boss, name, cleanupHotkey(label), tooltip), CommandSender(boss), - _cmd(cmd), _hotkey(hotkey), _lastTime(0), _duringPress(false) { + _cmd(cmd), _hotkey(hotkey), _duringPress(false) { if (hotkey == 0) _hotkey = parseHotkey(label); setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG); @@ -386,6 +387,104 @@ void ButtonWidget::setUnpressedState() { #pragma mark - +DropdownButtonWidget::DropdownButtonWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &label, const char *tooltip, uint32 cmd, uint8 hotkey) : + ButtonWidget(boss, x, y, w, h, label, tooltip, cmd, hotkey) { + setFlags(getFlags() | WIDGET_TRACK_MOUSE); + + reset(); +} + +DropdownButtonWidget::DropdownButtonWidget(GuiObject *boss, const Common::String &name, const Common::String &label, const char *tooltip, uint32 cmd, uint8 hotkey) : + ButtonWidget(boss, name, label, tooltip, cmd, hotkey) { + setFlags(getFlags() | WIDGET_TRACK_MOUSE); + + reset(); +} + +void DropdownButtonWidget::reset() { + _inDropdown = false; + _inButton = false; + _dropdownWidth = g_gui.xmlEval()->getVar("Globals.DropdownButton.Width", 13); +} + +bool DropdownButtonWidget::isInDropDown(int x, int y) const { + Common::Rect dropdownRect(_w - _dropdownWidth, 0, _w, _h); + return dropdownRect.contains(x, y); +} + +void DropdownButtonWidget::handleMouseMoved(int x, int y, int button) { + if (_entries.empty()) { + return; + } + + // Detect which part of the button the cursor is over + bool inDropdown = isInDropDown(x, y); + bool inButton = Common::Rect(_w, _h).contains(x, y) && !inDropdown; + + if (inDropdown != _inDropdown) { + _inDropdown = inDropdown; + markAsDirty(); + } + + if (inButton != _inButton) { + _inButton = inButton; + markAsDirty(); + } +} + +void DropdownButtonWidget::handleMouseUp(int x, int y, int button, int clickCount) { + if (isEnabled() && !_entries.empty() && _duringPress && isInDropDown(x, y)) { + + PopUpDialog popupDialog(this, "DropdownDialog", x + getAbsX(), y + getAbsY()); + popupDialog.setPosition(getAbsX(), getAbsY() + _h); + popupDialog.setLineHeight(_h); + popupDialog.setPadding(_dropdownWidth, _dropdownWidth); + + for (uint i = 0; i < _entries.size(); i++) { + popupDialog.appendEntry(_entries[i].label); + } + + int newSel = popupDialog.runModal(); + if (newSel != -1) { + sendCommand(_entries[newSel].cmd, 0); + } + + setUnpressedState(); + _duringPress = false; + } else { + ButtonWidget::handleMouseUp(x, y, button, clickCount); + } +} + +void DropdownButtonWidget::reflowLayout() { + ButtonWidget::reflowLayout(); + + reset(); +} + +void DropdownButtonWidget::appendEntry(const Common::String &label, uint32 cmd) { + Entry e; + e.label = label; + e.cmd = cmd; + _entries.push_back(e); +} + +void DropdownButtonWidget::clearEntries() { + _entries.clear(); +} + +void DropdownButtonWidget::drawWidget() { + if (_entries.empty()) { + // Degrade to a regular button + g_gui.theme()->drawButton(Common::Rect(_x, _y, _x + _w, _y + _h), _label, _state); + } else { + g_gui.theme()->drawDropDownButton(Common::Rect(_x, _y, _x + _w, _y + _h), _dropdownWidth, _label, + _state, _inButton, _inDropdown); + } +} + +#pragma mark - + PicButtonWidget::PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip, uint32 cmd, uint8 hotkey) : ButtonWidget(boss, x, y, w, h, "", tooltip, cmd, hotkey), _alpha(255), _transparency(false), _showButton(true) { @@ -468,7 +567,7 @@ void PicButtonWidget::drawWidget() { const int x = _x + (_w - gfx->w) / 2; const int y = _y + (_h - gfx->h) / 2; - g_gui.theme()->drawSurface(Common::Rect(x, y, x + gfx->w, y + gfx->h), *gfx, _transparency); + g_gui.theme()->drawSurface(Common::Point(x, y), *gfx, _transparency); } } @@ -719,7 +818,7 @@ void GraphicsWidget::drawWidget() { const int x = _x + (_w - _gfx.w) / 2; const int y = _y + (_h - _gfx.h) / 2; - g_gui.theme()->drawSurface(Common::Rect(x, y, x + _gfx.w, y + _gfx.h), _gfx, _transparency); + g_gui.theme()->drawSurface(Common::Point(x, y), _gfx, _transparency); } } diff --git a/gui/widget.h b/gui/widget.h index f87816b2e3a..5ae1891a126 100644 --- a/gui/widget.h +++ b/gui/widget.h @@ -227,8 +227,39 @@ public: protected: void drawWidget(); bool _duringPress; -private: - uint32 _lastTime; +}; + +/* DropdownButtonWidget */ +class DropdownButtonWidget : public ButtonWidget { +public: + DropdownButtonWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &label, const char *tooltip = nullptr, uint32 cmd = 0, uint8 hotkey = 0); + DropdownButtonWidget(GuiObject *boss, const Common::String &name, const Common::String &label, const char *tooltip = nullptr, uint32 cmd = 0, uint8 hotkey = 0); + + void handleMouseMoved(int x, int y, int button) override; + void handleMouseUp(int x, int y, int button, int clickCount) override; + void reflowLayout() override; + + void appendEntry(const Common::String &label, uint32 cmd); + void clearEntries(); + +protected: + struct Entry { + Common::String label; + uint32 cmd; + }; + typedef Common::Array EntryList; + + // Widget API + void drawWidget() override; + + void reset(); + bool isInDropDown(int x, int y) const; + + EntryList _entries; + + uint32 _dropdownWidth; + bool _inDropdown; + bool _inButton; }; /* PicButtonWidget */ diff --git a/gui/widgets/editable.cpp b/gui/widgets/editable.cpp index 2af078f9f62..048a0b0fcd5 100644 --- a/gui/widgets/editable.cpp +++ b/gui/widgets/editable.cpp @@ -186,7 +186,7 @@ bool EditableWidget::handleKeyDown(Common::KeyState state) { break; case Common::KEYCODE_v: - if (g_system->hasFeature(OSystem::kFeatureClipboardSupport) && state.flags & Common::KBD_CTRL) { + if (state.flags & Common::KBD_CTRL) { if (g_system->hasTextInClipboard()) { String text = g_system->getTextFromClipboard(); for (uint32 i = 0; i < text.size(); ++i) { @@ -201,7 +201,7 @@ bool EditableWidget::handleKeyDown(Common::KeyState state) { break; case Common::KEYCODE_c: - if (g_system->hasFeature(OSystem::kFeatureClipboardSupport) && state.flags & Common::KBD_CTRL) { + if (state.flags & Common::KBD_CTRL) { if (!getEditString().empty()) g_system->setTextInClipboard(getEditString()); } else { diff --git a/gui/widgets/edittext.cpp b/gui/widgets/edittext.cpp index ba9ef616ba5..e2dcd2be3e0 100644 --- a/gui/widgets/edittext.cpp +++ b/gui/widgets/edittext.cpp @@ -28,26 +28,26 @@ namespace GUI { -EditTextWidget::EditTextWidget(GuiObject *boss, int x, int y, int w, int h, const String &text, const char *tooltip, uint32 cmd, uint32 finishCmd) +EditTextWidget::EditTextWidget(GuiObject *boss, int x, int y, int w, int h, const String &text, const char *tooltip, uint32 cmd, uint32 finishCmd, ThemeEngine::FontStyle font) : EditableWidget(boss, x, y - 1, w, h + 2, tooltip, cmd) { setFlags(WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS | WIDGET_WANT_TICKLE); _type = kEditTextWidget; _finishCmd = finishCmd; setEditString(text); - setFontStyle(ThemeEngine::kFontStyleNormal); + setFontStyle(font); _leftPadding = _rightPadding = 0; } -EditTextWidget::EditTextWidget(GuiObject *boss, const String &name, const String &text, const char *tooltip, uint32 cmd, uint32 finishCmd) +EditTextWidget::EditTextWidget(GuiObject *boss, const String &name, const String &text, const char *tooltip, uint32 cmd, uint32 finishCmd, ThemeEngine::FontStyle font) : EditableWidget(boss, name, tooltip, cmd) { setFlags(WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS | WIDGET_WANT_TICKLE); _type = kEditTextWidget; _finishCmd = finishCmd; setEditString(text); - setFontStyle(ThemeEngine::kFontStyleNormal); + setFontStyle(font); _leftPadding = _rightPadding = 0; } @@ -100,7 +100,7 @@ void EditTextWidget::drawWidget() { setTextDrawableArea(r); g_gui.theme()->drawText( - Common::Rect(_x + 2 + _leftPadding, _y + 2, _x + _leftPadding + getEditRect().width() + 2, _y + _h), + Common::Rect(_x + 2 + _leftPadding, _y + 1, _x + _leftPadding + getEditRect().width() + 2, _y + _h), _editString, _state, Graphics::kTextAlignLeft, ThemeEngine::kTextInversionNone, -_editScrollOffset, false, _font, ThemeEngine::kFontColorNormal, true, _textDrawableArea); } diff --git a/gui/widgets/edittext.h b/gui/widgets/edittext.h index 9a1b698606a..a20d40eb331 100644 --- a/gui/widgets/edittext.h +++ b/gui/widgets/edittext.h @@ -40,8 +40,8 @@ protected: int _rightPadding; public: - EditTextWidget(GuiObject *boss, int x, int y, int w, int h, const String &text, const char *tooltip = 0, uint32 cmd = 0, uint32 finishCmd = 0); - EditTextWidget(GuiObject *boss, const String &name, const String &text, const char *tooltp = 0, uint32 cmd = 0, uint32 finishCmd = 0); + EditTextWidget(GuiObject *boss, int x, int y, int w, int h, const String &text, const char *tooltip = 0, uint32 cmd = 0, uint32 finishCmd = 0, ThemeEngine::FontStyle font = ThemeEngine::kFontStyleNormal); + EditTextWidget(GuiObject *boss, const String &name, const String &text, const char *tooltp = 0, uint32 cmd = 0, uint32 finishCmd = 0, ThemeEngine::FontStyle font = ThemeEngine::kFontStyleNormal); void setEditString(const String &str); diff --git a/gui/widgets/list.cpp b/gui/widgets/list.cpp index 6dd4ab4dd58..74239f889dc 100644 --- a/gui/widgets/list.cpp +++ b/gui/widgets/list.cpp @@ -41,7 +41,7 @@ ListWidget::ListWidget(Dialog *boss, const String &name, const char *tooltip, ui // This ensures that _entriesPerPage is properly initialized. reflowLayout(); - _scrollBar = new ScrollBarWidget(this, _w - _scrollBarWidth + 1, 0, _scrollBarWidth, _h); + _scrollBar = new ScrollBarWidget(this, _w - _scrollBarWidth, 0, _scrollBarWidth, _h); _scrollBar->setTarget(this); setFlags(WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS | WIDGET_WANT_TICKLE); @@ -72,7 +72,7 @@ ListWidget::ListWidget(Dialog *boss, int x, int y, int w, int h, const char *too // This ensures that _entriesPerPage is properly initialized. reflowLayout(); - _scrollBar = new ScrollBarWidget(this, _w - _scrollBarWidth + 1, 0, _scrollBarWidth, _h); + _scrollBar = new ScrollBarWidget(this, _w - _scrollBarWidth, 0, _scrollBarWidth, _h); _scrollBar->setTarget(this); setFlags(WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS | WIDGET_WANT_TICKLE); @@ -658,7 +658,7 @@ void ListWidget::reflowLayout() { assert(_entriesPerPage > 0); if (_scrollBar) { - _scrollBar->resize(_w - _scrollBarWidth + 1, 0, _scrollBarWidth, _h); + _scrollBar->resize(_w - _scrollBarWidth, 0, _scrollBarWidth, _h); scrollBarRecalc(); scrollToCurrent(); } diff --git a/gui/widgets/popup.cpp b/gui/widgets/popup.cpp index a36a652e5b7..a3d718602af 100644 --- a/gui/widgets/popup.cpp +++ b/gui/widgets/popup.cpp @@ -21,7 +21,6 @@ */ #include "common/system.h" -#include "gui/dialog.h" #include "gui/gui-manager.h" #include "gui/widgets/popup.h" @@ -33,58 +32,34 @@ namespace GUI { // PopUpDialog // -class PopUpDialog : public Dialog { -protected: - PopUpWidget *_popUpBoss; - int _clickX, _clickY; - int _selection; - uint32 _openTime; - bool _twoColumns; - int _entriesPerColumn; - - int _leftPadding; - int _rightPadding; - -public: - PopUpDialog(PopUpWidget *boss, int clickX, int clickY); - - void drawDialog(DrawLayer layerToDraw) override; - - void handleMouseUp(int x, int y, int button, int clickCount) override; - void handleMouseWheel(int x, int y, int direction) override; // Scroll through entries with scroll wheel - void handleMouseMoved(int x, int y, int button) override; // Redraw selections depending on mouse position - void handleKeyDown(Common::KeyState state) override; // Scroll through entries with arrow keys etc. - -protected: - void drawMenuEntry(int entry, bool hilite); - - int findItem(int x, int y) const; - void setSelection(int item); - bool isMouseDown(); - - void moveUp(); - void moveDown(); -}; - -PopUpDialog::PopUpDialog(PopUpWidget *boss, int clickX, int clickY) - : Dialog(0, 0, 16, 16), - _popUpBoss(boss) { +PopUpDialog::PopUpDialog(Widget *boss, const Common::String &name, int clickX, int clickY): + Dialog(name), + _boss(boss), + // Remember original mouse position + _clickX(clickX), + _clickY(clickY), + _selection(-1), + _initialSelection(-1), + _openTime(0), + _twoColumns(false), + _entriesPerColumn(1), + _leftPadding(0), + _rightPadding(0), + _lineHeight(kLineHeight) { _backgroundType = ThemeEngine::kDialogBackgroundNone; + _w = _boss->getWidth(); +} - _openTime = 0; - _entriesPerColumn = 1; +void PopUpDialog::open() { + // Time the popup was opened + _openTime = g_system->getMillis(); - // Copy the selection index - _selection = _popUpBoss->_selectedItem; + _initialSelection = _selection; // Calculate real popup dimensions - _x = _popUpBoss->getAbsX(); - _y = _popUpBoss->getAbsY() - _popUpBoss->_selectedItem * kLineHeight; - _h = _popUpBoss->_entries.size() * kLineHeight + 2; - _w = _popUpBoss->_w - kLineHeight + 2; + _h = _entries.size() * _lineHeight + 2; - _leftPadding = _popUpBoss->_leftPadding; - _rightPadding = _popUpBoss->_rightPadding; + _entriesPerColumn = 1; // Perform clipping / switch to scrolling mode if we don't fit on the screen // FIXME - OSystem should send out notification messages when the screen @@ -99,16 +74,16 @@ PopUpDialog::PopUpDialog(PopUpWidget *boss, int clickX, int clickY) const int screenW = g_system->getOverlayWidth(); _twoColumns = true; - _entriesPerColumn = _popUpBoss->_entries.size() / 2; + _entriesPerColumn = _entries.size() / 2; - if (_popUpBoss->_entries.size() & 1) + if (_entries.size() & 1) _entriesPerColumn++; - _h = _entriesPerColumn * kLineHeight + 2; + _h = _entriesPerColumn * _lineHeight + 2; _w = 0; - for (uint i = 0; i < _popUpBoss->_entries.size(); i++) { - int width = g_gui.getStringWidth(_popUpBoss->_entries[i].name); + for (uint i = 0; i < _entries.size(); i++) { + int width = g_gui.getStringWidth(_entries[i]); if (width > _w) _w = width; @@ -119,9 +94,9 @@ PopUpDialog::PopUpDialog(PopUpWidget *boss, int clickX, int clickY) if (!(_w & 1)) _w++; - if (_popUpBoss->_selectedItem >= _entriesPerColumn) { + if (_selection >= _entriesPerColumn) { _x -= _w / 2; - _y = _popUpBoss->getAbsY() - (_popUpBoss->_selectedItem - _entriesPerColumn) * kLineHeight; + _y = _boss->getAbsY() - (_selection - _entriesPerColumn) * _lineHeight; } if (_w >= screenW) @@ -142,9 +117,10 @@ PopUpDialog::PopUpDialog(PopUpWidget *boss, int clickX, int clickY) // TODO - implement scrolling if we had to move the menu, or if there are too many entries - // Remember original mouse position - _clickX = clickX - _x; - _clickY = clickY - _y; + Dialog::open(); +} + +void PopUpDialog::reflowLayout() { } void PopUpDialog::drawDialog(DrawLayer layerToDraw) { @@ -157,7 +133,7 @@ void PopUpDialog::drawDialog(DrawLayer layerToDraw) { g_gui.vLine(_x + _w / 2, _y, _y + _h - 2, g_gui._color);*/ // Draw the entries - int count = _popUpBoss->_entries.size(); + int count = _entries.size(); for (int i = 0; i < count; i++) { drawMenuEntry(i, i == _selection); } @@ -166,19 +142,18 @@ void PopUpDialog::drawDialog(DrawLayer layerToDraw) { /*if (_twoColumns && (count & 1)) { g_gui.fillRect(_x + 1 + _w / 2, _y + 1 + kLineHeight * (_entriesPerColumn - 1), _w / 2 - 1, kLineHeight, g_gui._bgcolor); }*/ - - if (_openTime == 0) { - // Time the popup was opened - _openTime = g_system->getMillis(); - } } void PopUpDialog::handleMouseUp(int x, int y, int button, int clickCount) { + int absX = x + getAbsX(); + int absY = y + getAbsY(); + // Mouse was released. If it wasn't moved much since the original mouse down, // let the popup stay open. If it did move, assume the user made his selection. - int dist = (_clickX - x) * (_clickX - x) + (_clickY - y) * (_clickY - y); + int dist = (_clickX - absX) * (_clickX - absX) + (_clickY - absY) * (_clickY - absY); if (dist > 3 * 3 || g_system->getMillis() - _openTime > 300) { - setResult(_selection); + int item = findItem(x, y); + setResult(item); close(); } _clickX = -1; @@ -197,11 +172,11 @@ void PopUpDialog::handleMouseMoved(int x, int y, int button) { // Compute over which item the mouse is... int item = findItem(x, y); - if (item >= 0 && _popUpBoss->_entries[item].name.size() == 0) + if (item >= 0 && _entries[item].size() == 0) item = -1; if (item == -1 && !isMouseDown()) { - setSelection(_popUpBoss->_selectedItem); + setSelection(_initialSelection); return; } @@ -237,7 +212,7 @@ void PopUpDialog::handleKeyDown(Common::KeyState state) { break; // fall through case Common::KEYCODE_END: - setSelection(_popUpBoss->_entries.size()-1); + setSelection(_entries.size()-1); break; case Common::KEYCODE_KP2: @@ -269,19 +244,45 @@ void PopUpDialog::handleKeyDown(Common::KeyState state) { } } +void PopUpDialog::setPosition(int x, int y) { + _x = x; + _y = y; +} + +void PopUpDialog::setPadding(int left, int right) { + _leftPadding = left; + _rightPadding = right; +} + +void PopUpDialog::setLineHeight(int lineHeight) { + _lineHeight = lineHeight; +} + +void PopUpDialog::setWidth(uint16 width) { + _w = width; +} + +void PopUpDialog::appendEntry(const Common::String &entry) { + _entries.push_back(entry); +} + +void PopUpDialog::clearEntries() { + _entries.clear(); +} + int PopUpDialog::findItem(int x, int y) const { if (x >= 0 && x < _w && y >= 0 && y < _h) { if (_twoColumns) { - uint entry = (y - 2) / kLineHeight; + uint entry = (y - 2) / _lineHeight; if (x > _w / 2) { entry += _entriesPerColumn; - if (entry >= _popUpBoss->_entries.size()) + if (entry >= _entries.size()) return -1; } return entry; } - return (y - 2) / kLineHeight; + return (y - 2) / _lineHeight; } return -1; } @@ -311,19 +312,19 @@ bool PopUpDialog::isMouseDown() { void PopUpDialog::moveUp() { if (_selection < 0) { - setSelection(_popUpBoss->_entries.size() - 1); + setSelection(_entries.size() - 1); } else if (_selection > 0) { int item = _selection; do { item--; - } while (item >= 0 && _popUpBoss->_entries[item].name.size() == 0); + } while (item >= 0 && _entries[item].size() == 0); if (item >= 0) setSelection(item); } } void PopUpDialog::moveDown() { - int lastItem = _popUpBoss->_entries.size() - 1; + int lastItem = _entries.size() - 1; if (_selection < 0) { setSelection(0); @@ -331,7 +332,7 @@ void PopUpDialog::moveDown() { int item = _selection; do { item++; - } while (item <= lastItem && _popUpBoss->_entries[item].name.size() == 0); + } while (item <= lastItem && _entries[item].size() == 0); if (item <= lastItem) setSelection(item); } @@ -343,34 +344,34 @@ void PopUpDialog::drawMenuEntry(int entry, bool hilite) { int x, y, w; if (_twoColumns) { - int n = _popUpBoss->_entries.size() / 2; + int n = _entries.size() / 2; - if (_popUpBoss->_entries.size() & 1) + if (_entries.size() & 1) n++; if (entry >= n) { x = _x + 1 + _w / 2; - y = _y + 1 + kLineHeight * (entry - n); + y = _y + 1 + _lineHeight * (entry - n); } else { x = _x + 1; - y = _y + 1 + kLineHeight * entry; + y = _y + 1 + _lineHeight * entry; } w = _w / 2 - 1; } else { x = _x + 1; - y = _y + 1 + kLineHeight * entry; + y = _y + 1 + _lineHeight * entry; w = _w - 2; } - Common::String &name(_popUpBoss->_entries[entry].name); + Common::String &name(_entries[entry]); if (name.size() == 0) { // Draw a separator - g_gui.theme()->drawLineSeparator(Common::Rect(x, y, x + w, y + kLineHeight)); + g_gui.theme()->drawLineSeparator(Common::Rect(x, y, x + w, y + _lineHeight)); } else { g_gui.theme()->drawText( - Common::Rect(x + 1, y + 2, x + w, y + 2 + kLineHeight), + Common::Rect(x + 1, y + 2, x + w, y + 2 + _lineHeight), name, hilite ? ThemeEngine::kStateHighlight : ThemeEngine::kStateEnabled, Graphics::kTextAlignLeft, ThemeEngine::kTextInversionNone, _leftPadding ); @@ -405,7 +406,17 @@ PopUpWidget::PopUpWidget(GuiObject *boss, int x, int y, int w, int h, const char void PopUpWidget::handleMouseDown(int x, int y, int button, int clickCount) { if (isEnabled()) { - PopUpDialog popupDialog(this, x + getAbsX(), y + getAbsY()); + PopUpDialog popupDialog(this, "", x + getAbsX(), y + getAbsY()); + popupDialog.setPosition(getAbsX(), getAbsY() - _selectedItem * kLineHeight); + popupDialog.setPadding(_leftPadding, _rightPadding); + popupDialog.setWidth(getWidth() - kLineHeight + 2); + + + for (uint i = 0; i < _entries.size(); i++) { + popupDialog.appendEntry(_entries[i].name); + } + popupDialog.setSelection(_selectedItem); + int newSel = popupDialog.runModal(); if (newSel != -1 && _selectedItem != newSel) { _selectedItem = newSel; diff --git a/gui/widgets/popup.h b/gui/widgets/popup.h index d2b1f1cb925..6174388d6c4 100644 --- a/gui/widgets/popup.h +++ b/gui/widgets/popup.h @@ -23,6 +23,7 @@ #ifndef GUI_WIDGETS_POPUP_H #define GUI_WIDGETS_POPUP_H +#include "gui/dialog.h" #include "gui/widget.h" #include "common/str.h" #include "common/array.h" @@ -41,7 +42,6 @@ enum { * is broadcast, with data being equal to the tag value of the selected entry. */ class PopUpWidget : public Widget, public CommandSender { - friend class PopUpDialog; typedef Common::String String; struct Entry { @@ -85,6 +85,62 @@ protected: void drawWidget(); }; +/** + * A small dialog showing a list of items and allowing the user to chose one of them + * + * Used by PopUpWidget and DropdownButtonWidget. + */ +class PopUpDialog : public Dialog { +protected: + Widget *_boss; + int _clickX, _clickY; + int _selection; + int _initialSelection; + uint32 _openTime; + bool _twoColumns; + int _entriesPerColumn; + + int _leftPadding; + int _rightPadding; + int _lineHeight; + + int _lastRead; + + typedef Common::Array EntryList; + EntryList _entries; + +public: + PopUpDialog(Widget *boss, const Common::String &name, int clickX, int clickY); + + void open() override; + void reflowLayout() override; + void drawDialog(DrawLayer layerToDraw) override; + + void handleMouseUp(int x, int y, int button, int clickCount) override; + void handleMouseWheel(int x, int y, int direction) override; // Scroll through entries with scroll wheel + void handleMouseMoved(int x, int y, int button) override; // Redraw selections depending on mouse position + void handleKeyDown(Common::KeyState state) override; // Scroll through entries with arrow keys etc. + + void setPosition(int x, int y); + void setPadding(int left, int right); + void setLineHeight(int lineHeight); + void setWidth(uint16 width); + + void appendEntry(const Common::String &entry); + void clearEntries(); + void setSelection(int item); + +protected: + void drawMenuEntry(int entry, bool hilite); + + int findItem(int x, int y) const; + bool isMouseDown(); + + void moveUp(); + void moveDown(); + void read(Common::String); +}; + } // End of namespace GUI #endif diff --git a/gui/widgets/scrollcontainer.cpp b/gui/widgets/scrollcontainer.cpp index 7e3f50d3bb4..389eed05c3e 100644 --- a/gui/widgets/scrollcontainer.cpp +++ b/gui/widgets/scrollcontainer.cpp @@ -74,13 +74,14 @@ void ScrollContainerWidget::recalc() { h = max - min; if (h <= _limitH) _scrolledY = 0; + if (_scrolledY > h - _limitH) _scrolledY = 0; _verticalScroll->_numEntries = h; _verticalScroll->_currentPos = _scrolledY; _verticalScroll->_entriesPerPage = _limitH; _verticalScroll->_singleStep = kLineHeight; - _verticalScroll->setPos(_w - scrollbarWidth, _scrolledY+1); - _verticalScroll->setSize(scrollbarWidth, _limitH -2); + _verticalScroll->setPos(_w - scrollbarWidth, _scrolledY); + _verticalScroll->setSize(scrollbarWidth, _limitH-1); } @@ -146,7 +147,7 @@ void ScrollContainerWidget::reflowLayout() { } void ScrollContainerWidget::drawWidget() { - g_gui.theme()->drawDialogBackground(Common::Rect(_x, _y, _x + _w, _y + getHeight() - 1), _backgroundType); + g_gui.theme()->drawDialogBackground(Common::Rect(_x, _y, _x + _w, _y + getHeight()), _backgroundType); } bool ScrollContainerWidget::containsWidget(Widget *w) const { @@ -166,7 +167,7 @@ Widget *ScrollContainerWidget::findWidget(int x, int y) { Common::Rect ScrollContainerWidget::getClipRect() const { // Make sure the clipping rect contains the scrollbar so it is properly redrawn - return Common::Rect(getAbsX(), getAbsY(), getAbsX() + _w, getAbsY() + getHeight()); + return Common::Rect(getAbsX(), getAbsY(), getAbsX() + _w, getAbsY() + getHeight() - 1); // this -1 is because of container border, which might not be present actually } void ScrollContainerWidget::setBackgroundType(ThemeEngine::DialogBackground backgroundType) { diff --git a/gui/widgets/tab.cpp b/gui/widgets/tab.cpp index 977aaaf021f..d34214b0ead 100644 --- a/gui/widgets/tab.cpp +++ b/gui/widgets/tab.cpp @@ -62,7 +62,7 @@ void TabWidget::init() { _bodyLP = g_gui.xmlEval()->getVar("Globals.TabWidget.Body.Padding.Left"); _bodyRP = g_gui.xmlEval()->getVar("Globals.TabWidget.Body.Padding.Right"); - _butRP = g_gui.xmlEval()->getVar("Globals.TabWidget.NavButtonPadding.Right", 0); + _butRP = g_gui.xmlEval()->getVar("Globals.TabWidget.NavButton.Padding.Right", 0); _butTP = g_gui.xmlEval()->getVar("Globals.TabWidget.NavButton.Padding.Top", 0); _butW = g_gui.xmlEval()->getVar("Globals.TabWidget.NavButton.Width", 10); _butH = g_gui.xmlEval()->getVar("Globals.TabWidget.NavButton.Height", 10); @@ -258,9 +258,9 @@ void TabWidget::reflowLayout() { _minTabWidth = g_gui.xmlEval()->getVar("Globals.TabWidget.Tab.Width"); _titleVPad = g_gui.xmlEval()->getVar("Globals.TabWidget.Tab.Padding.Top"); - _butRP = g_gui.xmlEval()->getVar("Globals.TabWidget.NavButton.PaddingRight", 0); + _butRP = g_gui.xmlEval()->getVar("Globals.TabWidget.NavButton.Padding.Right", 0); _butTP = g_gui.xmlEval()->getVar("Globals.TabWidget.NavButton.Padding.Top", 0); - _butW = g_gui.xmlEval()->getVar("GlobalsTabWidget.NavButton.Width", 10); + _butW = g_gui.xmlEval()->getVar("Globals.TabWidget.NavButton.Width", 10); _butH = g_gui.xmlEval()->getVar("Globals.TabWidget.NavButton.Height", 10); // If widgets were added or removed in the current tab, without tabs @@ -375,7 +375,7 @@ Widget *TabWidget::findWidget(int x, int y) { void TabWidget::computeLastVisibleTab(bool adjustFirstIfRoom) { int availableWidth = _w; if (_navButtonsVisible) - availableWidth -= 2 + _butW * 2; + availableWidth -= 2 + _butW * 2 + _butRP; _lastVisibleTab = _tabs.size() - 1; for (int i = _firstVisibleTab; i < (int)_tabs.size(); ++i) { diff --git a/image/png.cpp b/image/png.cpp index d8351711d90..9532840f2fa 100644 --- a/image/png.cpp +++ b/image/png.cpp @@ -43,7 +43,9 @@ PNGDecoder::PNGDecoder() : _outputSurface(0), _palette(0), _paletteColorCount(0), - _skipSignature(false) { + _skipSignature(false), + _keepTransparencyPaletted(false), + _transparentColor(-1) { } PNGDecoder::~PNGDecoder() { @@ -159,7 +161,7 @@ bool PNGDecoder::loadStream(Common::SeekableReadStream &stream) { // Images of all color formats except PNG_COLOR_TYPE_PALETTE // will be transformed into ARGB images - if (colorType == PNG_COLOR_TYPE_PALETTE && !png_get_valid(pngPtr, infoPtr, PNG_INFO_tRNS)) { + if (colorType == PNG_COLOR_TYPE_PALETTE && (_keepTransparencyPaletted || !png_get_valid(pngPtr, infoPtr, PNG_INFO_tRNS))) { int numPalette = 0; png_colorp palette = NULL; uint32 success = png_get_PLTE(pngPtr, infoPtr, &palette, &numPalette); @@ -175,6 +177,16 @@ bool PNGDecoder::loadStream(Common::SeekableReadStream &stream) { _palette[(i * 3) + 2] = palette[i].blue; } + + if (png_get_valid(pngPtr, infoPtr, PNG_INFO_tRNS)) { + png_bytep trans; + int numTrans; + png_color_16p transColor; + png_get_tRNS(pngPtr, infoPtr, &trans, &numTrans, &transColor); + assert(numTrans == 1); + _transparentColor = *trans; + } + _outputSurface->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); png_set_packing(pngPtr); } else { @@ -253,16 +265,6 @@ bool writePNG(Common::WriteStream &out, const Graphics::Surface &input, const bo const Graphics::PixelFormat requiredFormat_4byte(4, 8, 8, 8, 8, 24, 16, 8, 0); #endif - if (input.format.bytesPerPixel == 3) { - if (input.format != requiredFormat_3byte) { - warning("Cannot currently write PNG with 3-byte pixel format other than %s", requiredFormat_3byte.toString().c_str()); - return false; - } - } else if (input.format.bytesPerPixel != 4) { - warning("Cannot currently write PNG with pixel format of bpp other than 3, 4"); - return false; - } - int colorType; Graphics::Surface *tmp = NULL; const Graphics::Surface *surface; diff --git a/image/png.h b/image/png.h index adbc6d7a689..f983da467ee 100644 --- a/image/png.h +++ b/image/png.h @@ -57,8 +57,9 @@ public: const Graphics::Surface *getSurface() const { return _outputSurface; } const byte *getPalette() const { return _palette; } uint16 getPaletteColorCount() const { return _paletteColorCount; } + int getTransparentColor() const { return _transparentColor; } void setSkipSignature(bool skip) { _skipSignature = skip; } - + void setKeepTransparencyPaletted(bool keep) { _keepTransparencyPaletted = keep; } private: Graphics::PixelFormat getByteOrderRgbaPixelFormat() const; @@ -68,6 +69,10 @@ private: // flag to skip the png signature check for headless png files bool _skipSignature; + // Flag to keep paletted images paletted, even when the image has transparency + bool _keepTransparencyPaletted; + int _transparentColor; + Graphics::Surface *_outputSurface; }; diff --git a/po/de_DE.po b/po/de_DE.po index 5db97970f3f..5e493a70c22 100644 --- a/po/de_DE.po +++ b/po/de_DE.po @@ -1,5981 +1,5614 @@ -# LANGUAGE translation for ResidualVM. -# Copyright (C) 2015 ResidualVM Team -# This file is distributed under the same license as the ResidualVM package. -# Lothar Serra Mari , 2015. -# -msgid "" -msgstr "" -"Project-Id-Version: ResidualVM 0.4.0git\n" -"Report-Msgid-Bugs-To: https://github.com/residualvm/residualvm/issues\n" -"POT-Creation-Date: 2019-09-29 15:54+0200\n" -"PO-Revision-Date: 2019-09-29 15:56+0200\n" -"Last-Translator: Lothar Serra Mari \n" -"Language-Team: Lothar Serra Mari \n" -"Language: de\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=ISO-8859-1\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 2.2.3\n" - -#: gui/downloaddialog.cpp:136 gui/launcher.cpp:554 -msgid "ResidualVM couldn't open the specified directory!" -msgstr "ResidualVM kann das gewählte Verzeichnis nicht öffnen!" - -#: gui/launcher.cpp:142 backends/platform/sdl/macosx/appmenu_osx.mm:209 -msgid "Quit ResidualVM" -msgstr "ResidualVM beenden" - -#: gui/launcher.cpp:143 backends/platform/sdl/macosx/appmenu_osx.mm:203 -msgid "About ResidualVM" -msgstr "Über ResidualVM" - -#: gui/launcher.cpp:144 -msgid "Change global ResidualVM options" -msgstr "Globale ResidualVM-Optionen ändern" - -#: gui/launcher.cpp:508 -msgid "" -"ResidualVM could not find any engine capable of running the selected game!" -msgstr "ResidualVM kann keine für diese Spiel geeignete Engine finden!" - -#: gui/launcher.cpp:573 -msgid "ResidualVM could not find any game in the specified directory!" -msgstr "ResidualVM kann kein Spiel im gewählten Verzeichnis finden!" - -#: gui/options.cpp:1154 -msgid "Preserve aspect ratio" -msgstr "Seitenverhältnis beibehalten" - -#: gui/options.cpp:1154 -msgid "Preserve the aspect ratio in fullscreen mode" -msgstr "Seitenverhältnis im Vollbildmodus beibehalten" - -#: gui/options.cpp:1157 -msgid "V-Sync" -msgstr "V-Sync" - -#: gui/options.cpp:1157 -msgid "Wait for the vertical sync to refresh the screen" -msgstr "Beim Bildaufbau auf vertikale Synchronisation warten" - -#: gui/options.cpp:1159 -msgid "Game Renderer:" -msgstr "Spiele-Renderer:" - -#: gui/options.cpp:1168 -msgid "Anti-aliasing:" -msgstr "Kantenglättung:" - -#: gui/options.cpp:1770 -msgid "Language of ResidualVM GUI" -msgstr "Sprache der ResidualVM-Oberfläche" - -#: gui/options.cpp:1797 -msgid "" -"When starting a game, change the GUI language to the game language.That way, " -"if a game uses the ResidualVM save and load dialogs, they are in the same " -"language as the game." -msgstr "" -"Die Sprache der Menüführung wird beim Starten des Spiels auf die Sprache des " -"Spiels gestellt. Damit ist sichergestellt, dass bei der Verwendung der " -"ResidualVM-eigenen \"Speichern und Laden\"-Funktionalität gleiche Sprachen " -"verwendet werden." - -#: gui/options.cpp:1811 -msgid "" -"Use the native system file browser instead of the ResidualVM one to select a " -"file or directory." -msgstr "" -"Verwende zur Auswahl einer Datei oder eines Verzeichnisses den " -"betriebssystemeigenen Dateimanager anstelle des ResidualVM-eigenen " -"Auswahlmenüs." - -#: gui/options.cpp:1818 -msgid "How often to check ResidualVM updates" -msgstr "Wie oft ResidualVM nach Updates suchen soll" - -#: gui/updates-dialog.cpp:49 -msgid "" -"ResidualVM now supports automatic check for updates\n" -"which requires access to the Internet. Would you\n" -"like to enable this feature?" -msgstr "" -"ResidualVM kann automatisch nach Aktualisierungen suchen\n" -"was einen Zugang zum Internet erfordert.\n" -"Möchten Sie diese Funktion aktivieren?" - -#: engines/engine.cpp:544 -msgid "" -"WARNING: The game you are about to start is not yet fully supported by " -"ResidualVM. As such, it is likely to be unstable, and any saved game you " -"make might not work in future versions of ResidualVM." -msgstr "" -"WARNUNG: Das Spiel, welches Sie starten wollen, wird noch nicht vollständig " -"von ResidualVM unterstützt. Somit ist es wahrscheinlich, dass es instabil " -"ist und jegliche Spielstände, die Sie erstellen, könnten in zukünftigen " -"Versionen von ResidualVM nicht mehr funktionieren." - -#: engines/game.cpp:166 -#, c-format -msgid "" -"The game in '%s' seems to be an unknown game variant.\n" -"\n" -"Please report the following data to the ResidualVM team at %s along with the " -"name of the game you tried to add and its version, language, etc.:" -msgstr "" -"Das Spiel in '%s' scheint eine unbekannte Version zu sein.\n" -"\n" -"Bitte teilen Sie dem ResidualVM-Team unter %s die folgenden Informationen " -"zusammen mit dem Namen, der Version und der Sprache des Spiels, welches Sie " -"hinzufügen möchten, mit:" - -#: backends/platform/sdl/macosx/appmenu_osx.mm:205 -msgid "Hide ResidualVM" -msgstr "ResidualVM verstecken" - -#: backends/platform/sdl/macosx/appmenu_osx.mm:218 -msgid "What's New in ResidualVM" -msgstr "Neues in ResidualVM" - -#: engines/grim/detection.cpp:57 -msgid "Load user patch (unsupported)" -msgstr "Benutzer-Patch laden (nicht unterstützt)" - -#: engines/grim/detection.cpp:58 -msgid "" -"Load an user patch. Please note that the ResidualVM-team doesn't provide " -"support for using such patches." -msgstr "" -"Lade einen benutzerdefinierten Patch. Bitte beachten Sie, dass das " -"ResidualVM-Team keine Unterstützung für solche Patches anbietet." - -#: engines/grim/detection.cpp:66 -msgid "Show FPS" -msgstr "Bildwiederholrate anzeigen" - -#: engines/grim/detection.cpp:67 -msgid "Show the current FPS-rate, while you play." -msgstr "Zeigt die aktuelle Bildwiederholrate an, während Sie spielen." - -#: engines/grim/grim.cpp:314 -#, c-format -msgid "" -"ResidualVM found some problems with your game data files.\n" -"Running ResidualVM nevertheless may cause game bugs or even crashes.\n" -"Do you still want to run %s?" -msgstr "" -"ResidualVM hat Probleme mit Ihren Spiel-Dateien gefunden.\n" -"Wenn Sie ResidualVM trotzdem starten, kann dies Fehler im Spiel oder " -"Abstürze verursachen.\n" -"Möchten Sie %s trotzdem ausführen?" - -#: engines/grim/grim.cpp:317 -msgid "Escape From Monkey Island" -msgstr "Escape From Monkey Island" - -#: engines/grim/grim.cpp:317 -msgid "Grim Fandango" -msgstr "Grim Fandango" - -#: engines/grim/md5check.cpp:546 -#, c-format -msgid "'%s' may be corrupted. MD5: '%s'" -msgstr "'%s' ist möglicherweise defekt. MD5: '%s'" - -#: engines/grim/md5check.cpp:547 -#, c-format -msgid "" -"The game data file %s may be corrupted.\n" -"If you are sure it is not please provide the ResidualVM team the following " -"code, along with the file name, the language and a description of your game " -"version (i.e. dvd-box or jewelcase):\n" -"%s" -msgstr "" -"Die Spiel-Datei %s ist möglicherweise defekt.\n" -"Wenn Sie sicher sind, dass dies nicht der Fall ist, schicken Sie den " -"folgenden Code an das ResidualVM-Team, zusammen mit Dateinamen, der Sprache " -"und einer Beschreibung Ihrer Spiele-Version (z.B. DVD-Box oder Jewelcase):\n" -"%s" - -#: engines/grim/md5check.cpp:553 -#, c-format -msgid "Could not open %s for checking" -msgstr "Kann %s nicht zur Überprüfung öffnen" - -#: engines/grim/md5check.cpp:554 -#, c-format -msgid "" -"Could not open the file %s for checking.\n" -"It may be missing or you may not have the rights to open it.\n" -"Go to http://wiki.residualvm.org/index.php/Datafiles to see a list of the " -"needed files." -msgstr "" -"Die Datei %s kann nicht zur Überprüfung geöffnet werden.\n" -"Entweder fehlt die Datei, oder Sie haben nicht die nötigen Rechte, um sie zu " -"öffnen.\n" -"Auf http://wiki.residualvm.org/index.php/Datafiles finden Sie eine Liste der " -"benötigten Dateien." - -#: engines/grim/md5checkdialog.cpp:42 -msgid "" -"ResidualVM will now verify the game data files, to make sure you have the " -"best gaming experience.\n" -"This may take a while, please wait.\n" -"Successive runs will not check them again." -msgstr "" -"ResidualVM wird jetzt die Spiel-Dateien überprüfen, um ein optimales " -"Spielerlebnis sicherzustellen.\n" -"Dies wird eine Weile dauern - bitte warten.\n" -"Zukünftig werden sie nicht mehr überprüft." - -#: engines/grim/resource.cpp:96 -msgid "" -"The original patch of Grim Fandango\n" -"is missing. Please download it from\n" -"http://www.residualvm.org/downloads/\n" -"and put it in the game data files directory" -msgstr "" -"Der originale Patch von Grim Fandango\n" -"ist nicht vorhanden. Bitte laden Sie ihn von\n" -"http://www.residualvm.org/downloads/\n" -"herunter und kopieren Sie ihn in das Verzeichnis\n" -"mit den Spiel-Dateien" - -#: engines/grim/resource.cpp:101 -msgid "" -"The original patch of Escape from Monkey Island is missing. \n" -"Please download it from http://www.residualvm.org/downloads/\n" -"and put it in the game data files directory.\n" -"Pay attention to download the correct version according to the game's " -"language" -msgstr "" -"Der originale Patch von Escape from Monkey Island ist nicht vorhanden. \n" -"Bitte Laden Sie ihn von http://www.residualvm.org/downloads/ herunter \n" -"und kopieren Sie ihn in das Verzeichnis mit den Spiel-Dateien.\n" -"Achten Sie darauf, dass Sie die zur Spiel-Sprache passende Version " -"herunterladen" - -#: engines/grim/resource.cpp:121 -msgid "residualvm-grim-patch.lab not found" -msgstr "residualvm-grim-patch.lab nicht gefunden" - -#: engines/grim/resource.cpp:143 -msgid "" -"Loading datausr.lab. Please note that the ResidualVM-team doesn't provide " -"support for using such patches" -msgstr "" -"Lade datausr.lab. Bitte beachten Sie, dass das ResidualVM-Team keine " -"Unterstützung für solche Patches anbietet" - -#: engines/grim/resource.cpp:150 -#, c-format -msgid "%s not found" -msgstr "%s nicht gefunden" - -#: engines/grim/resource.cpp:181 -msgid "" -"Loading datausr.m4b. Please note that the ResidualVM-team doesn't provide " -"support for using such patches" -msgstr "" -"Lade datausr.m4b. Bitte beachten Sie, dass das ResidualVM-Team keine " -"Unterstützung für solche Patches anbietet" - -#: engines/grim/resource.cpp:188 -msgid "Cannot find game data - check configuration file" -msgstr "Spiel-Daten nicht gefunden - Konfigurationsdatei überprüfen" - -#: engines/myst3/detection.cpp:193 -msgid "Widescreen mod" -msgstr "Breitbild-Modus" - -#: engines/myst3/detection.cpp:194 -msgid "Enable enable widescreen rendering in fullscreen mode." -msgstr "Aktiviere Breitbild-Darstellung im Vollbildmodus." - -#: engines/myst3/myst3.cpp:360 -msgid "" -"This version of Myst III has not been updated with the latest official " -"patch.\n" -"Please install the official update corresponding to your game's language.\n" -"The updates can be downloaded from:\n" -"http://www.residualvm.org/downloads/" -msgstr "" -"Diese Version von Myst III wurde nicht auf die aktuellste Version " -"aktualisiert.\n" -"Bitte installieren Sie das zu Ihrer Sprache passende Update.\n" -"Die Updates können unter folgender Website heruntergeladen werden:\n" -"http://www.residualvm.org/downloads/" - -#: engines/stark/detection.cpp:346 -msgid "Load modded assets" -msgstr "Modifizierte Assets laden" - -#: engines/stark/detection.cpp:347 -msgid "Enable loading of external replacement assets." -msgstr "Erlaubt das Laden externer Ersatz-Assets." - -#: engines/stark/detection.cpp:355 -msgid "Enable linear filtering of the backgrounds images" -msgstr "Aktiviere Bilineare Filterung von Hintergrundbildern" - -#: engines/stark/detection.cpp:356 -msgid "" -"When linear filtering is enabled the background graphics are smoother in " -"full screen mode, at the cost of some details." -msgstr "" -"Wenn Bilineare Filterung für Hintergrundbilder aktiviert ist, wird die " -"Grafik auf Kosten der Detailgenauigkeit im Vollbildmodus verbessert." - -#: engines/stark/detection.cpp:364 -msgid "Enable font anti-aliasing" -msgstr "Kantenglättung für Schriftarten aktivieren" - -#: engines/stark/detection.cpp:365 -msgid "When font anti-aliasing is enabled, the text is smoother." -msgstr "" -"Wenn die Kantenglättung für Schriftarten aktiviert ist, wird Text sauberer " -"dargestellt." - -#: engines/stark/stark.cpp:302 -msgid "You are missing recommended data files:" -msgstr "Ihnen fehlen folgende empfohlene Datendateien:" - -#: engines/stark/stark.cpp:316 -msgid "" -"The 'fonts' folder is required to experience the text style as it was " -"designed. The Steam release is known to be missing it. You can get the fonts " -"from the demo version of the game." -msgstr "" -"Der Ordner 'fonts' wird benötigt, um die Texte wie ursprünglich gedacht " -"darzustellen. Das Steam-Release ist dafür bekannt, dass dieser Ordner fehlt. " -"Sie können die Schriftarten von der Demo-Version dieses Spiels beziehen." - -#: engines/stark/stark.cpp:323 -msgid "" -"'gui.ini' is recommended to get proper font settings for the game " -"localization." -msgstr "" -"'gui.ini' wird empfohlen, um die korrekten Schriftarten-Einstellungen für " -"diese Übersetzung zu erhalten." - -#: engines/stark/stark.cpp:329 -msgid "'language.ini' is recommended to get localized confirmation dialogs." -msgstr "" -"'language.ini' wird empfohlen, um die korrekten übersetzten Bestätigungs-" -"Dialoge zu erhalten." - -#: engines/stark/stark.cpp:335 -msgid "'game.exe' is recommended to get styled confirmation dialogs." -msgstr "" -"'game.exe' wird empfohlen, um korrekt dargestellte Bestätigungs-Dialoge zu " -"erhalten." - -#: gui/about.cpp:94 -#, c-format -msgid "(built on %s)" -msgstr "(erstellt am %s)" - -#: gui/about.cpp:101 -msgid "Features compiled in:" -msgstr "Verfügbare Funktionen:" - -#: gui/about.cpp:110 -msgid "Available engines:" -msgstr "Verfügbare Spiele-Engines:" - -#: gui/browser.cpp:75 backends/dialogs/macosx/macosx-dialogs.mm:87 -msgid "Show hidden files" -msgstr "Versteckte Dateien anzeigen" - -#: gui/browser.cpp:75 -msgid "Show files marked with the hidden attribute" -msgstr "" -"Dateien anzeigen, die mit dem Attribut \"versteckt\" gekennzeichnet sind" - -#: gui/browser.cpp:79 gui/remotebrowser.cpp:57 -msgid "Go up" -msgstr "Pfad hoch" - -#: gui/browser.cpp:79 gui/browser.cpp:81 gui/remotebrowser.cpp:57 -#: gui/remotebrowser.cpp:59 -msgid "Go to previous directory level" -msgstr "Zu höherer Pfadebene wechseln" - -#: gui/browser.cpp:81 gui/remotebrowser.cpp:59 -msgctxt "lowres" -msgid "Go up" -msgstr "Pfad hoch" - -#: gui/browser.cpp:82 gui/chooser.cpp:46 gui/editgamedialog.cpp:299 -#: gui/editrecorddialog.cpp:67 gui/filebrowser-dialog.cpp:65 -#: gui/fluidsynth-dialog.cpp:153 gui/KeysDialog.cpp:43 gui/massadd.cpp:92 -#: gui/options.cpp:1799 gui/predictivedialog.cpp:73 gui/recorderdialog.cpp:69 -#: gui/recorderdialog.cpp:155 gui/remotebrowser.cpp:60 -#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:451 -#: gui/saveload-dialog.cpp:746 gui/saveload-dialog.cpp:1140 -#: gui/storagewizarddialog.cpp:68 gui/themebrowser.cpp:55 -#: gui/unknown-game-dialog.cpp:49 engines/engine.cpp:546 -#: backends/events/default/default-events.cpp:190 -#: backends/events/default/default-events.cpp:212 -#: backends/platform/wii/options.cpp:48 engines/drascula/saveload.cpp:49 -#: engines/mohawk/myst_stacks/menu.cpp:284 -#: engines/mohawk/myst_stacks/menu.cpp:301 -#: engines/mohawk/myst_stacks/menu.cpp:319 -#: engines/mohawk/riven_stacks/aspit.cpp:350 -#: engines/mohawk/riven_stacks/aspit.cpp:372 -#: engines/mohawk/riven_stacks/aspit.cpp:456 -#: engines/parallaction/saveload.cpp:271 engines/scumm/dialogs.cpp:187 -#: engines/sword1/control.cpp:887 engines/wintermute/wintermute.cpp:166 -msgid "Cancel" -msgstr "Abbrechen" - -#: gui/browser.cpp:83 gui/chooser.cpp:47 gui/filebrowser-dialog.cpp:66 -#: gui/remotebrowser.cpp:61 gui/themebrowser.cpp:56 -#: backends/dialogs/macosx/macosx-dialogs.mm:148 -#: backends/dialogs/win32/win32-dialogs.cpp:145 -msgid "Choose" -msgstr "Auswählen" - -#: gui/downloaddialog.cpp:48 -msgid "Select directory where to download game data" -msgstr "" -"Wählen Sie das Verzeichnis, in welches die Spieldaten heruntergeladen werden " -"sollen" - -#: gui/downloaddialog.cpp:49 gui/editgamedialog.cpp:482 gui/launcher.cpp:198 -msgid "Select directory with game data" -msgstr "Verzeichnis mit Spieldateien auswählen" - -#: gui/downloaddialog.cpp:51 gui/downloaddialog.cpp:263 -msgid "From: " -msgstr "Von: " - -#: gui/downloaddialog.cpp:52 gui/downloaddialog.cpp:264 -msgid "To: " -msgstr "Nach: " - -#: gui/downloaddialog.cpp:63 -msgid "Cancel download" -msgstr "Download abbrechen" - -#: gui/downloaddialog.cpp:65 -msgctxt "lowres" -msgid "Cancel download" -msgstr "Download abbr." - -#: gui/downloaddialog.cpp:67 -msgid "Hide" -msgstr "Verstecken" - -#: gui/downloaddialog.cpp:117 -msgid "" -"It looks like your connection is limited. Do you really want to download " -"files with it?" -msgstr "" -"Ihre Internetverbindung ist anscheinend getaktet. Möchten Sie die Dateien " -"wirklich über diese Verbindung herunterladen?" - -#: gui/downloaddialog.cpp:118 gui/downloaddialog.cpp:152 -#: gui/filebrowser-dialog.cpp:133 gui/fluidsynth-dialog.cpp:218 -#: gui/launcher.cpp:326 gui/launcher.cpp:395 gui/launcher.cpp:455 -#: gui/storagewizarddialog.cpp:112 -#: backends/events/symbiansdl/symbiansdl-events.cpp:191 -#: backends/platform/wince/CEActionsPocket.cpp:326 -#: backends/platform/wince/CEActionsSmartphone.cpp:287 -#: backends/platform/wince/CELauncherDialog.cpp:83 -#: engines/kyra/gui/saveload_eob.cpp:569 engines/kyra/gui/saveload_eob.cpp:602 -#: engines/sci/graphics/controls32.cpp:820 -msgid "Yes" -msgstr "Ja" - -#: gui/downloaddialog.cpp:118 gui/downloaddialog.cpp:153 -#: gui/filebrowser-dialog.cpp:133 gui/fluidsynth-dialog.cpp:218 -#: gui/launcher.cpp:326 gui/launcher.cpp:395 gui/launcher.cpp:455 -#: gui/storagewizarddialog.cpp:112 -#: backends/events/symbiansdl/symbiansdl-events.cpp:191 -#: backends/platform/wince/CEActionsPocket.cpp:326 -#: backends/platform/wince/CEActionsSmartphone.cpp:287 -#: backends/platform/wince/CELauncherDialog.cpp:83 -#: engines/kyra/gui/saveload_eob.cpp:569 engines/kyra/gui/saveload_eob.cpp:602 -#: engines/sci/graphics/controls32.cpp:820 -msgid "No" -msgstr "Nein" - -#: gui/downloaddialog.cpp:136 gui/launcher.cpp:554 -msgid "ScummVM couldn't open the specified directory!" -msgstr "ScummVM konnte das gewählte Verzeichnis nicht öffnen!" - -#: gui/downloaddialog.cpp:146 -msgid "" -"Cannot create a directory to download - the specified directory has a file " -"with the same name." -msgstr "" -"Kann kein Verzeichnis zum Herunterladen erstellen - das gewählte Verzeichnis " -"beinhaltet eine Datei mit dem gleichen Namen." - -#: gui/downloaddialog.cpp:146 gui/editgamedialog.cpp:300 -#: gui/fluidsynth-dialog.cpp:154 gui/KeysDialog.cpp:42 gui/launcher.cpp:504 -#: gui/launcher.cpp:508 gui/massadd.cpp:89 gui/options.cpp:1801 -#: gui/saveload-dialog.cpp:1141 engines/engine.cpp:465 engines/engine.cpp:476 -#: backends/platform/wii/options.cpp:47 -#: backends/platform/wince/CELauncherDialog.cpp:54 -#: engines/agos/animation.cpp:559 engines/drascula/saveload.cpp:49 -#: engines/groovie/script.cpp:430 engines/parallaction/saveload.cpp:271 -#: engines/sci/engine/kgraphics.cpp:74 engines/sci/graphics/controls32.cpp:817 -#: engines/scumm/dialogs.cpp:189 engines/scumm/scumm.cpp:1885 -#: engines/scumm/players/player_v3m.cpp:130 -#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:141 -#: engines/sword1/animation.cpp:524 engines/sword1/animation.cpp:545 -#: engines/sword1/animation.cpp:561 engines/sword1/animation.cpp:569 -#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633 -#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445 -#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471 -#: engines/zvision/file/save_manager.cpp:230 -msgid "OK" -msgstr "OK" - -#: gui/downloaddialog.cpp:151 -#, c-format -msgid "" -"The \"%s\" already exists in the specified directory.\n" -"Do you really want to download files into that directory?" -msgstr "" -"\"%s\" existiert im gewählten Verzeichnis bereits.\n" -"Möchten Sie wirklich die Dateien in das gewählte Verzeichnis herunterladen?" - -#: gui/downloaddialog.cpp:251 -#, c-format -msgid "Downloaded %s %s / %s %s" -msgstr "%s %s / %s %s heruntergeladen" - -#: gui/downloaddialog.cpp:258 -#, c-format -msgid "Download speed: %s %s" -msgstr "Download-Geschwindigkeit: %s %s" - -#: gui/editgamedialog.cpp:136 -msgid "Game" -msgstr "Spiel" - -#: gui/editgamedialog.cpp:140 -msgid "ID:" -msgstr "ID:" - -#: gui/editgamedialog.cpp:140 gui/editgamedialog.cpp:142 -#: gui/editgamedialog.cpp:143 -msgid "" -"Short game identifier used for referring to saved games and running the game " -"from the command line" -msgstr "" -"Kurzer Spielname, um Spielstände zuzuordnen und das Spiel von der " -"Kommandozeile aus starten zu können" - -#: gui/editgamedialog.cpp:142 -msgctxt "lowres" -msgid "ID:" -msgstr "ID:" - -#: gui/editgamedialog.cpp:147 gui/editrecorddialog.cpp:59 -msgid "Name:" -msgstr "Name:" - -#: gui/editgamedialog.cpp:147 gui/editgamedialog.cpp:149 -#: gui/editgamedialog.cpp:150 -msgid "Full title of the game" -msgstr "Vollständiger Name des Spiels" - -#: gui/editgamedialog.cpp:149 -msgctxt "lowres" -msgid "Name:" -msgstr "Name:" - -#: gui/editgamedialog.cpp:153 -msgid "Language:" -msgstr "Sprache:" - -#: gui/editgamedialog.cpp:153 gui/editgamedialog.cpp:154 -msgid "" -"Language of the game. This will not turn your Spanish game version into " -"English" -msgstr "" -"Sprache des Spiels. Diese Funktion wird eine spanische Version des Spiels " -"nicht in eine deutsche verwandeln" - -#: gui/editgamedialog.cpp:155 gui/editgamedialog.cpp:169 gui/options.cpp:1055 -#: gui/options.cpp:1068 gui/options.cpp:1082 gui/options.cpp:1673 -#: audio/null.cpp:41 -msgid "" -msgstr "" - -#: gui/editgamedialog.cpp:165 -msgid "Platform:" -msgstr "Plattform:" - -#: gui/editgamedialog.cpp:165 gui/editgamedialog.cpp:167 -#: gui/editgamedialog.cpp:168 -msgid "Platform the game was originally designed for" -msgstr "Plattform, für die das Spiel ursprünglich erstellt wurde" - -#: gui/editgamedialog.cpp:167 -msgctxt "lowres" -msgid "Platform:" -msgstr "Plattform:" - -#: gui/editgamedialog.cpp:180 -msgid "Engine" -msgstr "Engine" - -#: gui/editgamedialog.cpp:188 gui/options.cpp:1415 gui/options.cpp:1525 -msgid "Graphics" -msgstr "Grafik" - -#: gui/editgamedialog.cpp:188 gui/options.cpp:1415 gui/options.cpp:1525 -msgid "GFX" -msgstr "GFX" - -#: gui/editgamedialog.cpp:194 -msgid "Override global graphic settings" -msgstr "Globale Grafik-Einstellungen übergehen" - -#: gui/editgamedialog.cpp:196 -msgctxt "lowres" -msgid "Override global graphic settings" -msgstr "Globale Grafik-Einstellungen übergehen" - -#: gui/editgamedialog.cpp:203 gui/options.cpp:1555 -msgid "Audio" -msgstr "Audio" - -#: gui/editgamedialog.cpp:206 -msgid "Override global audio settings" -msgstr "Globale Audio-Einstellungen übergehen" - -#: gui/editgamedialog.cpp:208 -msgctxt "lowres" -msgid "Override global audio settings" -msgstr "Globale Audio-Einstellungen übergehen" - -#: gui/editgamedialog.cpp:217 gui/options.cpp:1560 -msgid "Volume" -msgstr "Lautstärke" - -#: gui/editgamedialog.cpp:219 gui/options.cpp:1562 -msgctxt "lowres" -msgid "Volume" -msgstr "Lautst." - -#: gui/editgamedialog.cpp:222 -msgid "Override global volume settings" -msgstr "Globale Lautstärke-Einstellungen übergehen" - -#: gui/editgamedialog.cpp:224 -msgctxt "lowres" -msgid "Override global volume settings" -msgstr "Globale Lautstärke-Einstellungen übergehen" - -#: gui/editgamedialog.cpp:233 gui/options.cpp:1570 -msgid "MIDI" -msgstr "MIDI" - -#: gui/editgamedialog.cpp:236 -msgid "Override global MIDI settings" -msgstr "Globale MIDI-Einstellungen übergehen" - -#: gui/editgamedialog.cpp:238 -msgctxt "lowres" -msgid "Override global MIDI settings" -msgstr "Globale MIDI-Einstellungen übergehen" - -#: gui/editgamedialog.cpp:248 gui/options.cpp:1580 -msgid "MT-32" -msgstr "MT-32" - -#: gui/editgamedialog.cpp:251 -msgid "Override global MT-32 settings" -msgstr "Globale MT-32-Einstellungen übergehen" - -#: gui/editgamedialog.cpp:253 -msgctxt "lowres" -msgid "Override global MT-32 settings" -msgstr "Globale MT-32-Einstellungen übergehen" - -#: gui/editgamedialog.cpp:262 gui/options.cpp:1587 -msgid "Paths" -msgstr "Pfade" - -#: gui/editgamedialog.cpp:264 gui/options.cpp:1589 -msgctxt "lowres" -msgid "Paths" -msgstr "Pfade" - -#: gui/editgamedialog.cpp:271 -msgid "Game Path:" -msgstr "Spielpfad:" - -#: gui/editgamedialog.cpp:273 -msgctxt "lowres" -msgid "Game Path:" -msgstr "Spielpfad:" - -#: gui/editgamedialog.cpp:278 gui/options.cpp:1613 -msgid "Extra Path:" -msgstr "Extras:" - -#: gui/editgamedialog.cpp:278 gui/editgamedialog.cpp:280 -#: gui/editgamedialog.cpp:281 -msgid "Specifies path to additional data used by the game" -msgstr "Legt das Verzeichnis für zusätzliche Spieldateien fest" - -#: gui/editgamedialog.cpp:280 gui/options.cpp:1615 -msgctxt "lowres" -msgid "Extra Path:" -msgstr "Extras:" - -#: gui/editgamedialog.cpp:287 gui/options.cpp:1597 -msgid "Save Path:" -msgstr "Spielstände:" - -#: gui/editgamedialog.cpp:287 gui/editgamedialog.cpp:289 -#: gui/editgamedialog.cpp:290 gui/options.cpp:1597 gui/options.cpp:1599 -#: gui/options.cpp:1600 -msgid "Specifies where your saved games are put" -msgstr "Legt fest, wo die Spielstände gespeichert werden" - -#: gui/editgamedialog.cpp:289 gui/options.cpp:1599 -msgctxt "lowres" -msgid "Save Path:" -msgstr "Spielstände:" - -#: gui/editgamedialog.cpp:313 gui/editgamedialog.cpp:410 -#: gui/editgamedialog.cpp:469 gui/editgamedialog.cpp:530 gui/options.cpp:1608 -#: gui/options.cpp:1616 gui/options.cpp:1625 gui/options.cpp:1826 -#: gui/options.cpp:1832 gui/options.cpp:1840 gui/options.cpp:1863 -#: gui/options.cpp:1896 gui/options.cpp:1902 gui/options.cpp:1909 -#: gui/options.cpp:1917 gui/options.cpp:2119 gui/options.cpp:2122 -#: gui/options.cpp:2129 gui/options.cpp:2139 -msgctxt "path" -msgid "None" -msgstr "Keiner" - -#: gui/editgamedialog.cpp:318 gui/editgamedialog.cpp:416 -#: gui/editgamedialog.cpp:534 gui/options.cpp:1820 gui/options.cpp:1890 -#: gui/options.cpp:2125 backends/platform/wii/options.cpp:56 -msgid "Default" -msgstr "Standard" - -#: gui/editgamedialog.cpp:462 gui/options.cpp:2133 -msgid "Select SoundFont" -msgstr "SoundFont auswählen" - -#: gui/editgamedialog.cpp:501 -msgid "Select additional game directory" -msgstr "Verzeichnis mit zusätzlichen Dateien auswählen" - -#: gui/editgamedialog.cpp:514 gui/options.cpp:2056 -msgid "Select directory for saved games" -msgstr "Verzeichnis für Spielstände auswählen" - -#: gui/editgamedialog.cpp:520 -msgid "" -"Saved games sync feature doesn't work with non-default directories. If you " -"want your saved games to sync, use default directory." -msgstr "" -"Spielstand-Synchronisierung funktioniert nicht mit anderen Verzeichnissen. " -"Wenn Sie Ihre Spielstände synchronisieren möchten, verwenden Sie das " -"Standard-Verzeichnis." - -#: gui/editgamedialog.cpp:546 -msgid "This game ID is already taken. Please choose another one." -msgstr "Diese Spiel-ID ist bereits vergeben. Bitte eine andere wählen." - -#: gui/editrecorddialog.cpp:58 -msgid "Author:" -msgstr "Autor:" - -#: gui/editrecorddialog.cpp:60 -msgid "Notes:" -msgstr "Notizen:" - -#: gui/editrecorddialog.cpp:68 gui/predictivedialog.cpp:74 -msgid "Ok" -msgstr "OK" - -#: gui/filebrowser-dialog.cpp:50 -msgid "Choose file for loading" -msgstr "Zu ladende Datei auswählen" - -#: gui/filebrowser-dialog.cpp:50 -msgid "Enter filename for saving" -msgstr "Dateiname zum Speichern eingeben" - -#: gui/filebrowser-dialog.cpp:133 -msgid "Do you really want to overwrite the file?" -msgstr "Möchten Sie diese Datei wirklich überschreiben?" - -#: gui/fluidsynth-dialog.cpp:69 -msgid "Reverb" -msgstr "Hall" - -#: gui/fluidsynth-dialog.cpp:71 gui/fluidsynth-dialog.cpp:103 -msgid "Active" -msgstr "Aktiv" - -#: gui/fluidsynth-dialog.cpp:73 -msgid "Room:" -msgstr "Raum:" - -#: gui/fluidsynth-dialog.cpp:80 -msgid "Damp:" -msgstr "Dämpfung:" - -#: gui/fluidsynth-dialog.cpp:87 -msgid "Width:" -msgstr "Radius:" - -#: gui/fluidsynth-dialog.cpp:94 gui/fluidsynth-dialog.cpp:112 -msgid "Level:" -msgstr "Intensität:" - -#: gui/fluidsynth-dialog.cpp:101 -msgid "Chorus" -msgstr "Chorus" - -#: gui/fluidsynth-dialog.cpp:105 -msgid "N:" -msgstr "Stimmen:" - -#: gui/fluidsynth-dialog.cpp:119 -msgid "Speed:" -msgstr "Rate:" - -#: gui/fluidsynth-dialog.cpp:126 -msgid "Depth:" -msgstr "Trennzeit:" - -#: gui/fluidsynth-dialog.cpp:133 -msgid "Type:" -msgstr "Typ:" - -#: gui/fluidsynth-dialog.cpp:136 -msgid "Sine" -msgstr "Sinus" - -#: gui/fluidsynth-dialog.cpp:137 -msgid "Triangle" -msgstr "Dreieck" - -#: gui/fluidsynth-dialog.cpp:139 gui/options.cpp:1633 -msgid "Misc" -msgstr "Sonstiges" - -#: gui/fluidsynth-dialog.cpp:141 -msgid "Interpolation:" -msgstr "Interpolation:" - -#: gui/fluidsynth-dialog.cpp:144 -msgid "None (fastest)" -msgstr "Keine (am schnellsten)" - -#: gui/fluidsynth-dialog.cpp:145 -msgid "Linear" -msgstr "Linear" - -#: gui/fluidsynth-dialog.cpp:146 -msgid "Fourth-order" -msgstr "Vierstufig" - -#: gui/fluidsynth-dialog.cpp:147 -msgid "Seventh-order" -msgstr "Siebenstufig" - -#: gui/fluidsynth-dialog.cpp:151 -msgid "Reset" -msgstr "Zurücksetzen" - -#: gui/fluidsynth-dialog.cpp:151 -msgid "Reset all FluidSynth settings to their default values." -msgstr "Setzt alle FluidSynth-Einstellungen auf ihre Standard-Werte zurück." - -#: gui/fluidsynth-dialog.cpp:218 -msgid "" -"Do you really want to reset all FluidSynth settings to their default values?" -msgstr "" -"Möchten Sie wirklich alle FluidSynth-Einstellungen auf ihre Standard-Werte " -"zurücksetzen?" - -#: gui/gui-manager.cpp:119 gui/unknown-game-dialog.cpp:49 -#: backends/keymapper/remap-dialog.cpp:53 engines/scumm/help.cpp:126 -#: engines/scumm/help.cpp:141 engines/scumm/help.cpp:166 -#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:210 -msgid "Close" -msgstr "Schließen" - -#: gui/gui-manager.cpp:122 -msgid "Mouse click" -msgstr "Mausklick" - -#: gui/gui-manager.cpp:126 base/main.cpp:356 -msgid "Display keyboard" -msgstr "Tastatur anzeigen" - -#: gui/gui-manager.cpp:130 base/main.cpp:360 -msgid "Remap keys" -msgstr "Tasten neu zuweisen" - -#: gui/gui-manager.cpp:133 base/main.cpp:363 engines/scumm/help.cpp:87 -msgid "Toggle fullscreen" -msgstr "Vollbild umschalten" - -#: gui/KeysDialog.cpp:41 -msgid "Map" -msgstr "Zuweisen" - -#: gui/KeysDialog.cpp:49 -msgid "Select an action and click 'Map'" -msgstr "Aktion auswählen und \"Zuweisen\" klicken" - -#: gui/KeysDialog.cpp:80 gui/KeysDialog.cpp:102 gui/KeysDialog.cpp:141 -#, c-format -msgid "Associated key : %s" -msgstr "Zugewiesene Taste: %s" - -#: gui/KeysDialog.cpp:82 gui/KeysDialog.cpp:104 gui/KeysDialog.cpp:143 -msgid "Associated key : none" -msgstr "Zugewiesene Taste: keine" - -#: gui/KeysDialog.cpp:90 -msgid "Please select an action" -msgstr "Bitte eine Aktion auswählen" - -#: gui/KeysDialog.cpp:106 -msgid "Press the key to associate" -msgstr "Taste drücken, um sie zuzuweisen" - -#: gui/KeysDialog.cpp:145 gui/KeysDialog.h:36 -msgid "Choose an action to map" -msgstr "Eine Aktion zum Zuweisen auswählen" - -#: gui/launcher.cpp:142 engines/dialogs.cpp:111 engines/mohawk/dialogs.cpp:142 -msgid "~Q~uit" -msgstr "~B~eenden" - -#: gui/launcher.cpp:142 backends/platform/sdl/macosx/appmenu_osx.mm:209 -msgid "Quit ScummVM" -msgstr "ScummVM beenden" - -#: gui/launcher.cpp:143 -msgid "A~b~out..." -msgstr "Übe~r~..." - -#: gui/launcher.cpp:143 backends/platform/sdl/macosx/appmenu_osx.mm:203 -msgid "About ScummVM" -msgstr "Über ScummVM" - -#: gui/launcher.cpp:144 -msgid "~O~ptions..." -msgstr "~O~ptionen..." - -#: gui/launcher.cpp:144 -msgid "Change global ScummVM options" -msgstr "Globale ScummVM-Einstellungen ändern" - -#: gui/launcher.cpp:146 -msgid "~S~tart" -msgstr "~S~tarten" - -#: gui/launcher.cpp:146 -msgid "Start selected game" -msgstr "Ausgewähltes Spiel starten" - -#: gui/launcher.cpp:149 -msgid "~L~oad..." -msgstr "~L~aden..." - -#: gui/launcher.cpp:149 -msgid "Load saved game for selected game" -msgstr "Spielstand für ausgewähltes Spiel laden" - -#: gui/launcher.cpp:154 -msgid "~A~dd Game..." -msgstr "Spiel ~h~inzufügen..." - -#: gui/launcher.cpp:154 gui/launcher.cpp:161 -msgid "Hold Shift for Mass Add" -msgstr "" -"Umschalttaste (Shift) gedrückt halten, um Verzeichnisse nach Spielen zu " -"durchsuchen" - -#: gui/launcher.cpp:156 -msgid "~E~dit Game..." -msgstr "Spielo~p~tionen..." - -#: gui/launcher.cpp:156 gui/launcher.cpp:163 -msgid "Change game options" -msgstr "Spieloptionen ändern" - -#: gui/launcher.cpp:158 -msgid "~R~emove Game" -msgstr "Spiel ~e~ntfernen" - -#: gui/launcher.cpp:158 gui/launcher.cpp:165 -msgid "Remove game from the list. The game data files stay intact" -msgstr "Spiel aus der Liste entfernen. Die Spieldateien bleiben erhalten" - -#: gui/launcher.cpp:161 -msgctxt "lowres" -msgid "~A~dd Game..." -msgstr "~H~inzufügen..." - -#: gui/launcher.cpp:163 -msgctxt "lowres" -msgid "~E~dit Game..." -msgstr "Spielo~p~tion" - -#: gui/launcher.cpp:165 -msgctxt "lowres" -msgid "~R~emove Game" -msgstr "~E~ntfernen" - -#: gui/launcher.cpp:173 -msgid "Search in game list" -msgstr "In Spieleliste suchen" - -#: gui/launcher.cpp:177 gui/launcher.cpp:785 -msgid "Search:" -msgstr "Suchen:" - -#: gui/launcher.cpp:201 engines/dialogs.cpp:115 engines/cruise/menu.cpp:214 -#: engines/mohawk/dialogs.cpp:162 engines/mohawk/myst.cpp:942 -#: engines/mohawk/riven.cpp:673 engines/pegasus/pegasus.cpp:355 -#: engines/tsage/scenes.cpp:601 engines/wage/saveload.cpp:748 -msgid "Load game:" -msgstr "Spiel laden:" - -#: gui/launcher.cpp:201 engines/dialogs.cpp:115 -#: backends/platform/wince/CEActionsPocket.cpp:267 -#: backends/platform/wince/CEActionsSmartphone.cpp:231 -#: engines/cruise/menu.cpp:214 engines/mohawk/dialogs.cpp:162 -#: engines/mohawk/myst.cpp:942 engines/mohawk/riven.cpp:673 -#: engines/parallaction/saveload.cpp:194 engines/pegasus/pegasus.cpp:355 -#: engines/scumm/dialogs.cpp:185 engines/tsage/scenes.cpp:601 -#: engines/wage/saveload.cpp:748 -msgid "Load" -msgstr "Laden" - -#: gui/launcher.cpp:325 -msgid "" -"Do you really want to run the mass game detector? This could potentially add " -"a huge number of games." -msgstr "" -"Möchten Sie wirklich den PC nach Spielen durchsuchen? Möglicherweise wird " -"dabei eine größere Menge an Spielen hinzugefügt." - -#: gui/launcher.cpp:384 -msgid "This directory cannot be used yet, it is being downloaded into!" -msgstr "" -"Dieses Verzeichnis kann noch nicht verwendet werden, da noch Dateien " -"heruntergeladen werden!" - -#: gui/launcher.cpp:395 -msgid "Do you really want to remove this game configuration?" -msgstr "Möchten Sie diese Spielkonfiguration wirklich entfernen?" - -#: gui/launcher.cpp:454 -msgid "Do you want to load saved game?" -msgstr "Möchten Sie einen Spielstand laden?" - -#: gui/launcher.cpp:504 -msgid "This game does not support loading games from the launcher." -msgstr "" -"Für dieses Spiel wird das Laden aus der Spieleliste heraus nicht unterstützt." - -#: gui/launcher.cpp:508 -msgid "ScummVM could not find any engine capable of running the selected game!" -msgstr "ScummVM konnte keine passende Engine für dieses Spiel finden!" - -#: gui/launcher.cpp:573 -msgid "ScummVM could not find any game in the specified directory!" -msgstr "ScummVM konnte im gewählten Verzeichnis kein Spiel finden!" - -#: gui/launcher.cpp:588 -msgid "Unknown variant" -msgstr "Unbekannte Spiele-Variante" - -#: gui/launcher.cpp:594 -msgid "Pick the game:" -msgstr "Spiel auswählen:" - -#: gui/launcher.cpp:722 -msgid "Mass Add..." -msgstr "Durchsuchen..." - -#: gui/launcher.cpp:724 -msgid "Record..." -msgstr "Aufzeichnen..." - -#: gui/massadd.cpp:76 gui/massadd.cpp:79 -msgid "... progress ..." -msgstr "... läuft ..." - -#: gui/massadd.cpp:265 -msgid "Scan complete!" -msgstr "Suchlauf abgeschlossen!" - -#: gui/massadd.cpp:268 -#, c-format -msgid "Discovered %d new games, ignored %d previously added games." -msgstr "%d neue Spiele gefunden, %d bereits hinzugefügte Spiele ignoriert." - -#: gui/massadd.cpp:272 -#, c-format -msgid "Scanned %d directories ..." -msgstr "%d Ordner durchsucht..." - -#: gui/massadd.cpp:275 -#, c-format -msgid "Discovered %d new games, ignored %d previously added games ..." -msgstr "%d neue Spiele gefunden, %d bereits hinzugefügte Spiele ignoriert..." - -#: gui/onscreendialog.cpp:101 gui/onscreendialog.cpp:103 -msgid "Stop" -msgstr "Anhalten" - -#: gui/onscreendialog.cpp:106 -msgid "Edit record description" -msgstr "Aufnahme-Beschreibung ändern" - -#: gui/onscreendialog.cpp:108 -msgid "Switch to Game" -msgstr "Wechsle" - -#: gui/onscreendialog.cpp:110 -msgid "Fast replay" -msgstr "Schneller Modus" - -#: gui/options.cpp:122 common/updates.cpp:56 -msgid "Never" -msgstr "nie" - -#: gui/options.cpp:122 -msgid "Every 5 mins" -msgstr "Alle 5 Minuten" - -#: gui/options.cpp:122 -msgid "Every 10 mins" -msgstr "Alle 10 Minuten" - -#: gui/options.cpp:122 -msgid "Every 15 mins" -msgstr "Alle 15 Minuten" - -#: gui/options.cpp:122 -msgid "Every 30 mins" -msgstr "Alle 30 Minuten" - -#: gui/options.cpp:361 gui/options.cpp:691 gui/options.cpp:829 -#: gui/options.cpp:911 gui/options.cpp:1184 -msgctxt "soundfont" -msgid "None" -msgstr "Kein SoundFont" - -#: gui/options.cpp:552 -msgid "Failed to apply some of the graphic options changes:" -msgstr "Folgende Grafikoptionen konnten nicht geändert werden:" - -#: gui/options.cpp:564 -msgid "the video mode could not be changed" -msgstr "der Videomodus konnte nicht geändert werden" - -#: gui/options.cpp:577 -msgid "the stretch mode could not be changed" -msgstr "der Skaliermodus konnte nicht geändert werden" - -#: gui/options.cpp:583 -msgid "the aspect ratio setting could not be changed" -msgstr "Die Einstellung für das Seitenverhältnis konnte nicht geändert werden" - -#: gui/options.cpp:589 -msgid "the fullscreen setting could not be changed" -msgstr "Vollbildeinstellung konnte nicht geändert werden" - -#: gui/options.cpp:595 -msgid "the filtering setting could not be changed" -msgstr "Die Filtereinstellung konnte nicht geändert werden" - -#: gui/options.cpp:990 -msgid "Show On-screen control" -msgstr "Virtuelle Bedienelemente anzeigen" - -#: gui/options.cpp:994 -msgid "Touchpad mouse mode" -msgstr "Touchpad-Mausmodus" - -#: gui/options.cpp:998 -msgid "Swap Menu and Back buttons" -msgstr "Menü- und Zurück-Tasten vertauschen" - -#: gui/options.cpp:1003 -msgid "Pointer Speed:" -msgstr "Zeiger-Geschw.:" - -#: gui/options.cpp:1003 gui/options.cpp:1005 gui/options.cpp:1006 -msgid "Speed for keyboard/joystick mouse pointer control" -msgstr "Zeiger-Geschwindigkeit der Tastatur- bzw. Joystick-Maus" - -#: gui/options.cpp:1005 -msgctxt "lowres" -msgid "Pointer Speed:" -msgstr "Zeiger-Geschw.:" - -#: gui/options.cpp:1016 -msgid "Joy Deadzone:" -msgstr "Joystick-Totzone:" - -#: gui/options.cpp:1016 gui/options.cpp:1018 gui/options.cpp:1019 -msgid "Analog joystick Deadzone" -msgstr "Totzone des analogen Joysticks" - -#: gui/options.cpp:1018 -msgctxt "lowres" -msgid "Joy Deadzone:" -msgstr "Joystick-Totzone:" - -#: gui/options.cpp:1032 -msgid "HW Shader:" -msgstr "HW-Shader:" - -#: gui/options.cpp:1032 gui/options.cpp:1034 -msgid "Different hardware shaders give different visual effects" -msgstr "" -"Verschiedene Hardware-Shader erzeugen unterschiedliche visuelle Effekte" - -#: gui/options.cpp:1034 -msgctxt "lowres" -msgid "HW Shader:" -msgstr "HW-Shader:" - -#: gui/options.cpp:1035 -msgid "Different shaders give different visual effects" -msgstr "Verschiedene Shader erzeugen verschiedene Grafikeffekte" - -#: gui/options.cpp:1052 -msgid "Graphics mode:" -msgstr "Grafikmodus:" - -#: gui/options.cpp:1066 -msgid "Render mode:" -msgstr "Render-Modus:" - -#: gui/options.cpp:1066 gui/options.cpp:1067 -msgid "Special dithering modes supported by some games" -msgstr "Spezielle Dithering-Methoden unterstützt von manchen Spielen" - -#: gui/options.cpp:1079 -msgid "Stretch mode:" -msgstr "Skaliermodus:" - -#: gui/options.cpp:1090 -msgid "Fullscreen mode" -msgstr "Vollbildmodus" - -#: gui/options.cpp:1093 -msgid "Filter graphics" -msgstr "Bilineare Filterung" - -#: gui/options.cpp:1093 -msgid "Use linear filtering when scaling graphics" -msgstr "Verwende bilineare Filterung zur Grafik-Skalierung" - -#: gui/options.cpp:1096 -msgid "Aspect ratio correction" -msgstr "Seitenverhältnis korrigieren" - -#: gui/options.cpp:1096 -msgid "Correct aspect ratio for 320x200 games" -msgstr "Seitenverhältnis für Spiele mit der Auflösung 320x200 korrigieren" - -#: gui/options.cpp:1104 -msgid "Preferred device:" -msgstr "Bevorzugtes Gerät:" - -#: gui/options.cpp:1104 -msgid "Music device:" -msgstr "Musikgerät:" - -#: gui/options.cpp:1104 gui/options.cpp:1106 -msgid "Specifies preferred sound device or sound card emulator" -msgstr "" -"Legt das bevorzugte Audio-Wiedergabegerät oder den Soundkarten-Emulator fest" - -#: gui/options.cpp:1104 gui/options.cpp:1106 gui/options.cpp:1107 -msgid "Specifies output sound device or sound card emulator" -msgstr "Legt das Musikwiedergabe-Gerät oder den Soundkarten-Emulator fest" - -#: gui/options.cpp:1106 -msgctxt "lowres" -msgid "Preferred dev.:" -msgstr "Standard-Gerät:" - -#: gui/options.cpp:1106 -msgctxt "lowres" -msgid "Music device:" -msgstr "Musikgerät:" - -#: gui/options.cpp:1133 -msgid "AdLib emulator:" -msgstr "AdLib-Emulator:" - -#: gui/options.cpp:1133 gui/options.cpp:1134 -msgid "AdLib is used for music in many games" -msgstr "AdLib wird für die Musik in vielen Spielen verwendet" - -#: gui/options.cpp:1147 -msgid "GM device:" -msgstr "GM-Gerät:" - -#: gui/options.cpp:1147 -msgid "Specifies default sound device for General MIDI output" -msgstr "" -"Legt das standardmäßige Musikwiedergabe-Gerät für General-MIDI-Ausgabe fest" - -#: gui/options.cpp:1158 -msgid "Don't use General MIDI music" -msgstr "Keine General-MIDI-Musik" - -#: gui/options.cpp:1169 gui/options.cpp:1231 -msgid "Use first available device" -msgstr "Erstes verfügbares Gerät" - -#: gui/options.cpp:1181 -msgid "SoundFont:" -msgstr "SoundFont:" - -#: gui/options.cpp:1181 gui/options.cpp:1183 gui/options.cpp:1184 -msgid "SoundFont is supported by some audio cards, FluidSynth and Timidity" -msgstr "" -"SoundFont wird von einigen Soundkarten, FluidSynth und Timidity unterstützt" - -#: gui/options.cpp:1183 -msgctxt "lowres" -msgid "SoundFont:" -msgstr "SoundFont:" - -#: gui/options.cpp:1189 -msgid "Mixed AdLib/MIDI mode" -msgstr "Gemischter AdLib/MIDI-Modus" - -#: gui/options.cpp:1189 -msgid "Use both MIDI and AdLib sound generation" -msgstr "Kombiniert MIDI-Musik mit AdLib-Soundeffekten" - -#: gui/options.cpp:1192 -msgid "MIDI gain:" -msgstr "MIDI-Lautstärke:" - -#: gui/options.cpp:1202 -msgid "MT-32 Device:" -msgstr "MT-32-Gerät:" - -#: gui/options.cpp:1202 -msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output" -msgstr "" -"Legt das standardmäßige Audio-Wiedergabegerät für die Ausgabe von Roland " -"MT-32/LAPC1/CM32l/CM64 fest" - -#: gui/options.cpp:1207 -msgid "True Roland MT-32 (disable GM emulation)" -msgstr "Echte Roland MT-32 (GM-Emulation deaktiviert)" - -#: gui/options.cpp:1207 gui/options.cpp:1209 -msgid "" -"Check if you want to use your real hardware Roland-compatible sound device " -"connected to your computer" -msgstr "" -"Wählen Sie dies aus, wenn Sie ein echtes Roland-kompatibles Soundgerät " -"verwenden" - -#: gui/options.cpp:1209 -msgctxt "lowres" -msgid "True Roland MT-32 (no GM emulation)" -msgstr "Echte Roland MT-32 (keine GM-Emulation)" - -#: gui/options.cpp:1212 -msgid "Roland GS device (enable MT-32 mappings)" -msgstr "Roland-GS-Gerät (MT-32-Zuweisungen aktivieren)" - -#: gui/options.cpp:1212 -msgid "" -"Check if you want to enable patch mappings to emulate an MT-32 on a Roland " -"GS device" -msgstr "" -"Auswählen, wenn Sie ausbessernde Instrumentzuweisungen aktivieren möchten, " -"um MT-32 auf einem Roland-GS-Gerät zu emulieren" - -#: gui/options.cpp:1221 -msgid "Don't use Roland MT-32 music" -msgstr "Keine Roland-MT-32-Musik" - -#: gui/options.cpp:1248 -msgid "Text and speech:" -msgstr "Text und Sprache:" - -#: gui/options.cpp:1252 gui/options.cpp:1262 -msgid "Speech" -msgstr "Sprache" - -#: gui/options.cpp:1253 gui/options.cpp:1263 -msgid "Subtitles" -msgstr "Untertitel" - -#: gui/options.cpp:1254 -msgid "Both" -msgstr "Beides" - -#: gui/options.cpp:1256 -msgid "Subtitle speed:" -msgstr "Untertitel-Tempo:" - -#: gui/options.cpp:1258 -msgctxt "lowres" -msgid "Text and speech:" -msgstr "Text und Sprache:" - -#: gui/options.cpp:1262 -msgid "Spch" -msgstr "Spr." - -#: gui/options.cpp:1263 -msgid "Subs" -msgstr "Text" - -#: gui/options.cpp:1264 -msgctxt "lowres" -msgid "Both" -msgstr "S+T" - -#: gui/options.cpp:1264 -msgid "Show subtitles and play speech" -msgstr "Untertitel anzeigen und Sprachausgabe aktivieren" - -#: gui/options.cpp:1266 -msgctxt "lowres" -msgid "Subtitle speed:" -msgstr "Text-Tempo:" - -#: gui/options.cpp:1282 -msgid "Music volume:" -msgstr "Musiklautstärke:" - -#: gui/options.cpp:1284 -msgctxt "lowres" -msgid "Music volume:" -msgstr "Musiklautstärke:" - -#: gui/options.cpp:1291 -msgid "Mute all" -msgstr "Stumm" - -#: gui/options.cpp:1294 -msgid "SFX volume:" -msgstr "Effektlautstärke:" - -#: gui/options.cpp:1294 gui/options.cpp:1296 gui/options.cpp:1297 -msgid "Special sound effects volume" -msgstr "Lautstärke spezieller Geräusch-Effekte" - -#: gui/options.cpp:1296 -msgctxt "lowres" -msgid "SFX volume:" -msgstr "Effektlautst.:" - -#: gui/options.cpp:1304 -msgid "Speech volume:" -msgstr "Sprachlautstärke:" - -#: gui/options.cpp:1306 -msgctxt "lowres" -msgid "Speech volume:" -msgstr "Sprachlautst.:" - -#: gui/options.cpp:1536 -msgid "Shader" -msgstr "Shader" - -#: gui/options.cpp:1548 -msgid "Control" -msgstr "Steuerung" - -#: gui/options.cpp:1574 -msgid "FluidSynth Settings" -msgstr "FluidSynth-Einstellungen" - -#: gui/options.cpp:1605 -msgid "Theme Path:" -msgstr "Themes:" - -#: gui/options.cpp:1607 -msgctxt "lowres" -msgid "Theme Path:" -msgstr "Themes:" - -#: gui/options.cpp:1613 gui/options.cpp:1615 gui/options.cpp:1616 -msgid "Specifies path to additional data used by all games or ScummVM" -msgstr "" -"Legt das Verzeichnis für zusätzliche Spieldateien für alle Spiele in ScummVM " -"fest" - -#: gui/options.cpp:1622 -msgid "Plugins Path:" -msgstr "Plugins:" - -#: gui/options.cpp:1624 -msgctxt "lowres" -msgid "Plugins Path:" -msgstr "Plugins:" - -#: gui/options.cpp:1635 -msgctxt "lowres" -msgid "Misc" -msgstr "Andere" - -#: gui/options.cpp:1637 -msgid "Theme:" -msgstr "Theme:" - -#: gui/options.cpp:1641 -msgid "GUI renderer:" -msgstr "GUI-Renderer:" - -#: gui/options.cpp:1653 -msgid "Autosave:" -msgstr "Autom. Speichern:" - -#: gui/options.cpp:1655 -msgctxt "lowres" -msgid "Autosave:" -msgstr "Autospeichern:" - -#: gui/options.cpp:1663 -msgid "Keys" -msgstr "Tasten" - -#: gui/options.cpp:1670 -msgid "GUI language:" -msgstr "Sprache:" - -#: gui/options.cpp:1670 -msgid "Language of ScummVM GUI" -msgstr "Sprache der ScummVM-Oberfläche" - -#: gui/options.cpp:1696 -msgid "Switch the GUI language to the game language" -msgstr "Menüsprache auf Spielsprache einstellen" - -#: gui/options.cpp:1697 -msgid "" -"When starting a game, change the GUI language to the game language.That way, " -"if a game uses the ScummVM save and load dialogs, they are in the same " -"language as the game." -msgstr "" -"Die Sprache der Menüführung wird beim Starten des Spiels auf die Sprache des " -"Spiels gestellt. Damit ist sichergestellt, dass bei der Verwendung der " -"ScummVM-eigenen \"Speichern und Laden\"-Funktionalität gleiche Sprachen " -"verwendet werden." - -#: gui/options.cpp:1710 -msgid "Use native system file browser" -msgstr "Verwende betriebssystemeigenen Dateimanager" - -#: gui/options.cpp:1711 -msgid "" -"Use the native system file browser instead of the ScummVM one to select a " -"file or directory." -msgstr "" -"Verwende zur Auswahl einer Datei oder eines Verzeichnisses den " -"betriebssystemeigenen Dateimanager anstelle des ScummVM-eigenen Auswahlmenüs." - -#: gui/options.cpp:1718 gui/updates-dialog.cpp:86 -msgid "Update check:" -msgstr "Updates suchen:" - -#: gui/options.cpp:1718 -msgid "How often to check ScummVM updates" -msgstr "Wie oft nach Aktualisierungen von ScummVM suchen?" - -#: gui/options.cpp:1730 -msgid "Check now" -msgstr "Jetzt prüfen" - -#: gui/options.cpp:1738 -msgid "Cloud" -msgstr "Cloud" - -#: gui/options.cpp:1740 -msgctxt "lowres" -msgid "Cloud" -msgstr "Cloud" - -#: gui/options.cpp:1746 -msgid "Storage:" -msgstr "Cloud-Speicher:" - -#: gui/options.cpp:1746 -msgid "Active cloud storage" -msgstr "Aktiver Cloud-Speicher" - -#: gui/options.cpp:1753 gui/options.cpp:2336 -msgid "" -msgstr "" - -#: gui/options.cpp:1757 backends/platform/wii/options.cpp:114 -msgid "Username:" -msgstr "Benutzername:" - -#: gui/options.cpp:1757 -msgid "Username used by this storage" -msgstr "Benutzername, der von diesem Cloud-Speicher verwendet wird" - -#: gui/options.cpp:1760 -msgid "Used space:" -msgstr "Belegter Speicher:" - -#: gui/options.cpp:1760 -msgid "Space used by ScummVM's saved games on this storage" -msgstr "" -"Von ScummVM-Spielständen belegter Speicherplatz auf diesem Cloud-Speicher" - -#: gui/options.cpp:1763 -msgid "Last sync time:" -msgstr "Letzte Sync.:" - -#: gui/options.cpp:1763 -msgid "When the last saved games sync for this storage occured" -msgstr "Zeitpunkt der letzten Spielstand-Synchronisierung" - -#: gui/options.cpp:1766 gui/storagewizarddialog.cpp:71 -msgid "Connect" -msgstr "Verbinden" - -#: gui/options.cpp:1766 -msgid "Open wizard dialog to connect your cloud storage account" -msgstr "" -"Öffnet den Assistenten, der Sie durch die Einrichtung Ihres Cloud-Speichers " -"führt" - -#: gui/options.cpp:1767 -msgid "Refresh" -msgstr "Aktualisieren" - -#: gui/options.cpp:1767 -msgid "Refresh current cloud storage information (username and usage)" -msgstr "" -"Aktualisiert die Informationen über diesen Cloud-Speicher (Benutzername und " -"Belegung)" - -#: gui/options.cpp:1768 -msgid "Download" -msgstr "Herunterladen" - -#: gui/options.cpp:1768 -msgid "Open downloads manager dialog" -msgstr "Öffnet den Download-Manager" - -#: gui/options.cpp:1770 -msgid "Run server" -msgstr "Server starten" - -#: gui/options.cpp:1770 -msgid "Run local webserver" -msgstr "Startet den lokalen Webserver" - -#: gui/options.cpp:1771 gui/options.cpp:2446 -msgid "Not running" -msgstr "Nicht gestartet" - -#: gui/options.cpp:1775 -msgid "/root/ Path:" -msgstr "/root/-Pfad:" - -#: gui/options.cpp:1775 gui/options.cpp:1777 gui/options.cpp:1778 -msgid "Specifies which directory the Files Manager can access" -msgstr "Legt fest, auf welches Verzeichnis der Dateimanager zugreifen darf" - -#: gui/options.cpp:1777 -msgctxt "lowres" -msgid "/root/ Path:" -msgstr "/root/-Pfad:" - -#: gui/options.cpp:1787 -msgid "Server's port:" -msgstr "Server-Port:" - -#: gui/options.cpp:1787 -msgid "" -"Which port is used by the server\n" -"Auth with server is not available with non-default port" -msgstr "" -"Legt den Port für den Server fest.\n" -"Authentifizierung mit dem Server ist nicht verfügbar, wenn ein anderer Port " -"verwendet wird" - -#: gui/options.cpp:1800 -msgid "Apply" -msgstr "Übernehmen" - -#: gui/options.cpp:1943 -msgid "Failed to change cloud storage!" -msgstr "Konnte den Cloud-Speicher nicht ändern!" - -#: gui/options.cpp:1946 -msgid "Another cloud storage is already active." -msgstr "Ein anderer Cloud-Speicher arbeitet gerade." - -#: gui/options.cpp:2021 -msgid "Theme does not support selected language!" -msgstr "Das Theme unterstützt die gewählte Sprache nicht!" - -#: gui/options.cpp:2024 -msgid "Theme cannot be loaded!" -msgstr "Theme konnte nicht geladen werden!" - -#: gui/options.cpp:2027 -msgid "" -"\n" -"Misc settings will be restored." -msgstr "" -"\n" -"Verschiedene Einstellungen werden wiederhergestellt." - -#: gui/options.cpp:2063 -msgid "The chosen directory cannot be written to. Please select another one." -msgstr "" -"In das gewählte Verzeichnis kann nicht geschrieben werden. Bitte ein anderes " -"auswählen." - -#: gui/options.cpp:2072 -msgid "Select directory for GUI themes" -msgstr "Verzeichnis für Oberflächen-Themes" - -#: gui/options.cpp:2082 -msgid "Select directory for extra files" -msgstr "Verzeichnis für zusätzliche Dateien auswählen" - -#: gui/options.cpp:2093 -msgid "Select directory for plugins" -msgstr "Verzeichnis für Plugins auswählen" - -#: gui/options.cpp:2105 -msgid "Select directory for Files Manager /root/" -msgstr "" -"Wählen Sie das Verzeichnis aus, welches als Stammverzeichnis ('root') dient" - -#: gui/options.cpp:2343 -#, c-format -msgid "%llu bytes" -msgstr "%llu Bytes" - -#: gui/options.cpp:2351 -msgid "" -msgstr "" - -#: gui/options.cpp:2353 -msgid "" -msgstr "" - -#: gui/options.cpp:2437 -msgid "Stop server" -msgstr "Server anhalten" - -#: gui/options.cpp:2438 -msgid "Stop local webserver" -msgstr "Lokalen Webserver anhalten" - -#: gui/options.cpp:2529 -msgid "" -"Request failed.\n" -"Check your Internet connection." -msgstr "" -"Anfrage fehlgeschlagen.\n" -"Bitte überprüfen Sie Ihre Internetverbindung." - -#. I18N: You must leave "#" as is, only word 'next' is translatable -#: gui/predictivedialog.cpp:86 -msgid "# next" -msgstr "# nächste" - -#: gui/predictivedialog.cpp:87 -msgid "add" -msgstr "hinzufügen" - -#: gui/predictivedialog.cpp:92 gui/predictivedialog.cpp:167 -msgid "Delete char" -msgstr "Löschen" - -#: gui/predictivedialog.cpp:97 gui/predictivedialog.cpp:171 -msgid "<" -msgstr "<" - -#. I18N: Pre means 'Predictive', leave '*' as is -#: gui/predictivedialog.cpp:99 gui/predictivedialog.cpp:575 -msgid "* Pre" -msgstr "* Vorschau" - -#. I18N: 'Num' means Numbers -#: gui/predictivedialog.cpp:578 -msgid "* Num" -msgstr "* Zahlen" - -#. I18N: 'Abc' means Latin alphabet input -#: gui/predictivedialog.cpp:581 -msgid "* Abc" -msgstr "* ABC" - -#: gui/recorderdialog.cpp:63 -msgid "Recorder or Playback Gameplay" -msgstr "Spiel aufzeichnen/wiedergeben" - -#: gui/recorderdialog.cpp:68 gui/recorderdialog.cpp:155 -#: gui/saveload-dialog.cpp:393 gui/saveload-dialog.cpp:451 -msgid "Delete" -msgstr "Löschen" - -#: gui/recorderdialog.cpp:70 -msgid "Record" -msgstr "Aufnahme" - -#: gui/recorderdialog.cpp:71 -msgid "Playback" -msgstr "Wiedergabe" - -#: gui/recorderdialog.cpp:73 -msgid "Edit" -msgstr "Bearbeiten" - -#: gui/recorderdialog.cpp:85 gui/recorderdialog.cpp:241 -#: gui/recorderdialog.cpp:251 -msgid "Author: " -msgstr "Autor: " - -#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:242 -#: gui/recorderdialog.cpp:252 -msgid "Notes: " -msgstr "Notizen: " - -#: gui/recorderdialog.cpp:154 -msgid "Do you really want to delete this record?" -msgstr "Möchten Sie diese Aufnahme wirklich löschen?" - -#: gui/recorderdialog.cpp:172 -msgid "Unknown Author" -msgstr "Unbekannter Autor" - -#: gui/remotebrowser.cpp:129 -msgid "ScummVM could not access the directory!" -msgstr "ScummVM konnte auf das gewählte Verzeichnis nicht zugreifen!" - -#: gui/saveload-dialog.cpp:340 -msgid "List view" -msgstr "Listenansicht" - -#: gui/saveload-dialog.cpp:341 -msgid "Grid view" -msgstr "Rasteransicht" - -#: gui/saveload-dialog.cpp:384 gui/saveload-dialog.cpp:551 -msgid "No date saved" -msgstr "Kein Datum gespeichert" - -#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:552 -msgid "No time saved" -msgstr "Keine Zeit gespeichert" - -#: gui/saveload-dialog.cpp:386 gui/saveload-dialog.cpp:553 -msgid "No playtime saved" -msgstr "Keine Spielzeit gespeichert" - -#: gui/saveload-dialog.cpp:450 -msgid "Do you really want to delete this saved game?" -msgstr "Diesen Spielstand wirklich löschen?" - -#: gui/saveload-dialog.cpp:577 gui/saveload-dialog.cpp:1089 -msgid "Date: " -msgstr "Datum: " - -#: gui/saveload-dialog.cpp:581 gui/saveload-dialog.cpp:1095 -msgid "Time: " -msgstr "Zeit: " - -#: gui/saveload-dialog.cpp:587 gui/saveload-dialog.cpp:1103 -msgid "Playtime: " -msgstr "Spieldauer: " - -#: gui/saveload-dialog.cpp:600 gui/saveload-dialog.cpp:688 -msgid "Untitled saved game" -msgstr "Unbenannter Spielstand" - -#: gui/saveload-dialog.cpp:747 -msgid "Next" -msgstr "Vor" - -#: gui/saveload-dialog.cpp:750 -msgid "Prev" -msgstr "Zurück" - -#: gui/saveload-dialog.cpp:953 -msgid "New Save" -msgstr "Neuer Spielstand" - -#: gui/saveload-dialog.cpp:953 -msgid "Create a new saved game" -msgstr "Neuen Spielstand erstellen" - -#: gui/saveload-dialog.cpp:1082 -msgid "Name: " -msgstr "Name: " - -#: gui/saveload-dialog.cpp:1160 -#, c-format -msgid "Enter a description for slot %d:" -msgstr "Geben Sie eine Beschreibung für Speicherplatz %d ein:" - -#: gui/storagewizarddialog.cpp:55 -#, c-format -msgid "%s Storage Connection Wizard" -msgstr "Verbindungs-Assistent für %s" - -#: gui/storagewizarddialog.cpp:58 -msgid "Navigate to the following URL:" -msgstr "Rufen Sie folgende URL auf:" - -#: gui/storagewizarddialog.cpp:61 -msgid "Obtain the code from the storage, enter it" -msgstr "Geben Sie den Code Ihres Cloud-Speichers in das" - -#: gui/storagewizarddialog.cpp:62 -msgid "in the following field and press 'Connect':" -msgstr "folgende Feld ein und klicken Sie auf 'Verbinden':" - -#: gui/storagewizarddialog.cpp:69 -msgid "Open URL" -msgstr "URL öffnen" - -#: gui/storagewizarddialog.cpp:70 -msgid "Paste" -msgstr "Einfügen" - -#: gui/storagewizarddialog.cpp:70 -msgid "Pastes clipboard contents into fields" -msgstr "Fügt den Inhalt der Zwischenablage in die Felder ein" - -#: gui/storagewizarddialog.cpp:78 -msgid "You will be directed to ScummVM's page where" -msgstr "Sie werden zur Webseite von ScummVM weitergeleitet," - -#: gui/storagewizarddialog.cpp:79 -msgid "you should allow it to access your storage." -msgstr "wo Sie den Zugriff auf die Cloud erlauben sollten." - -#: gui/storagewizarddialog.cpp:112 -msgid "Another Storage is active. Do you want to interrupt it?" -msgstr "" -"Ein anderer Cloud-Speicher arbeitet gerade. Möchten Sie ihn unterbrechen?" - -#: gui/storagewizarddialog.cpp:121 -msgid "Wait until current Storage finishes up and try again." -msgstr "" -"Warten Sie, bis der Cloud-Speicher fertig ist und versuchen Sie es erneut." - -#: gui/storagewizarddialog.cpp:182 -#, c-format -msgid "Field %s has a mistake in it." -msgstr "Fehler in Feld %s." - -#: gui/storagewizarddialog.cpp:184 -#, c-format -msgid "Fields %s have mistakes in them." -msgstr "Die Felder %s enthalten fehlerhafte Eingaben." - -#: gui/storagewizarddialog.cpp:199 -msgid "All OK!" -msgstr "Alles OK!" - -#: gui/storagewizarddialog.cpp:201 -msgid "Invalid code" -msgstr "Code ungültig" - -#: gui/storagewizarddialog.cpp:209 -msgid "" -"Failed to open URL!\n" -"Please navigate to this page manually." -msgstr "" -"Fehler beim Öffnen der URL!\n" -"Sie sollten diese Seite manuell aufrufen." - -#: gui/themebrowser.cpp:45 -msgid "Select a Theme" -msgstr "Theme auswählen" - -#: gui/ThemeEngine.cpp:256 -msgid "Disabled GFX" -msgstr "GFX ausgeschaltet" - -#: gui/ThemeEngine.cpp:256 -msgctxt "lowres" -msgid "Disabled GFX" -msgstr "GFX ausgeschaltet" - -#: gui/ThemeEngine.cpp:257 -msgid "Standard renderer" -msgstr "Standard-Renderer" - -#: gui/ThemeEngine.cpp:257 engines/scumm/dialogs.cpp:660 -msgid "Standard" -msgstr "Standard" - -#: gui/ThemeEngine.cpp:259 -msgid "Antialiased renderer" -msgstr "Kantenglättung" - -#: gui/ThemeEngine.cpp:259 -msgid "Antialiased" -msgstr "Kantenglättung" - -#: gui/unknown-game-dialog.cpp:52 -msgid "Add anyway" -msgstr "Trotzdem hinzufügen" - -#: gui/unknown-game-dialog.cpp:59 -msgid "Copy to clipboard" -msgstr "In Zwischenablage kopieren" - -#: gui/unknown-game-dialog.cpp:65 -msgid "Report game" -msgstr "Spiel melden" - -#: gui/unknown-game-dialog.cpp:108 -msgid "" -"Use the button below to copy the required game information into your " -"clipboard." -msgstr "" -"Verwenden Sie den untenstehenden Button, um die benötigten Informationen in " -"die Zwischenablage zu kopieren." - -#: gui/unknown-game-dialog.cpp:113 -msgid "You can also directly report your game to the Bug Tracker." -msgstr "Sie können das Spiel auch direkt an unseren Bug-Tracker melden." - -#: gui/unknown-game-dialog.cpp:213 -msgid "" -"All necessary information about your game has been copied into the clipboard" -msgstr "Alle benötigten Informationen wurden in die Zwischenablage kopiert" - -#: gui/unknown-game-dialog.cpp:215 -msgid "Copying the game information to the clipboard has failed!" -msgstr "Kopieren der Spielinformationen in die Zwischenablage fehlgeschlagen!" - -#: gui/updates-dialog.cpp:49 -msgid "" -"ScummVM now supports automatic check for updates\n" -"which requires access to the Internet. Would you\n" -"like to enable this feature?" -msgstr "" -"ScummVM unterstützt die automatische Suche nach Aktualisierungen,\n" -"wozu ein Internetzugang erforderlich ist.\n" -"Möchten Sie diese Funktion aktivieren?" - -#: gui/updates-dialog.cpp:52 -msgid "" -"You can change this setting later in the Misc tab\n" -"in the Options dialog." -msgstr "" -"Sie können diese Einstellung später im Reiter \"Sonstiges\"\n" -"im Optionsfenster ändern." - -#: gui/updates-dialog.cpp:116 -msgid "Proceed" -msgstr "Fortfahren" - -#: gui/widget.cpp:356 gui/widget.cpp:358 gui/widget.cpp:364 gui/widget.cpp:366 -msgid "Clear value" -msgstr "Wert löschen" - -#: base/main.cpp:254 -#, c-format -msgid "Engine does not support debug level '%s'" -msgstr "Engine unterstützt den Debug-Level \"%s\" nicht" - -#: base/main.cpp:343 -msgid "Menu" -msgstr "Menü" - -#: base/main.cpp:346 backends/platform/symbian/src/SymbianActions.cpp:45 -#: backends/platform/wince/CEActionsPocket.cpp:45 -#: backends/platform/wince/CEActionsSmartphone.cpp:46 -msgid "Skip" -msgstr "Überspringen" - -#: base/main.cpp:349 backends/platform/symbian/src/SymbianActions.cpp:50 -#: backends/platform/wince/CEActionsPocket.cpp:42 -msgid "Pause" -msgstr "Pause" - -#: base/main.cpp:352 -msgid "Skip line" -msgstr "Zeile überspringen" - -#: base/main.cpp:563 -msgid "Error running game:" -msgstr "Fehler beim Ausführen des Spiels:" - -#: base/main.cpp:610 -msgid "Could not find any engine capable of running the selected game" -msgstr "Konnte keine Spiel-Engine finden, die dieses Spiel starten kann" - -#: common/error.cpp:38 -msgid "No error" -msgstr "Kein Fehler" - -#: common/error.cpp:40 -msgid "Game data not found" -msgstr "Spieldateien nicht gefunden" - -#: common/error.cpp:42 -msgid "Game id not supported" -msgstr "Spiel-ID nicht unterstützt" - -#: common/error.cpp:44 -msgid "Unsupported color mode" -msgstr "Farbmodus nicht unterstützt" - -#: common/error.cpp:46 -msgid "Audio device initialization failed" -msgstr "Initialisierung des Audio-Gerätes fehlgeschlagen" - -#: common/error.cpp:49 -msgid "Read permission denied" -msgstr "Lese-Berechtigung nicht vorhanden" - -#: common/error.cpp:51 -msgid "Write permission denied" -msgstr "Schreib-Berechtigung nicht vorhanden" - -#: common/error.cpp:54 -msgid "Path does not exist" -msgstr "Verzeichnis existiert nicht" - -#: common/error.cpp:56 -msgid "Path not a directory" -msgstr "Pfad ist kein Verzeichnis" - -#: common/error.cpp:58 -msgid "Path not a file" -msgstr "Pfad ist keine Datei" - -#: common/error.cpp:61 -msgid "Cannot create file" -msgstr "Kann Datei nicht erstellen" - -#: common/error.cpp:63 -msgid "Reading data failed" -msgstr "Daten konnten nicht gelesen werden" - -#: common/error.cpp:65 -msgid "Writing data failed" -msgstr "Daten konnten nicht geschrieben werden" - -#: common/error.cpp:68 -msgid "Could not find suitable engine plugin" -msgstr "Konnte kein passendes Engine-Plugin finden" - -#: common/error.cpp:70 -msgid "Engine plugin does not support saved games" -msgstr "Engine-Plugin unterstützt keine Spielstände" - -#: common/error.cpp:73 -msgid "User canceled" -msgstr "Abbruch durch Benutzer" - -#: common/error.cpp:77 -msgid "Unknown error" -msgstr "Unbekannter Fehler" - -#. I18N: Hercules is graphics card name -#: common/rendermode.cpp:35 -msgid "Hercules Green" -msgstr "Hercules-Grün" - -#: common/rendermode.cpp:36 -msgid "Hercules Amber" -msgstr "Hercules-Bernstein" - -#: common/rendermode.cpp:42 -msgid "PC-9821 (256 Colors)" -msgstr "PC-9821 (256 Farben)" - -#: common/rendermode.cpp:43 -msgid "PC-9801 (16 Colors)" -msgstr "PC-9801 (16 Farben)" - -#: common/rendermode.cpp:73 -msgctxt "lowres" -msgid "Hercules Green" -msgstr "Hercules-Grün" - -#: common/rendermode.cpp:74 -msgctxt "lowres" -msgid "Hercules Amber" -msgstr "Hercules-Bernst." - -#: common/updates.cpp:58 -msgid "Daily" -msgstr "Täglich" - -#: common/updates.cpp:60 -msgid "Weekly" -msgstr "Wöchentlich" - -#: common/updates.cpp:62 -msgid "Monthly" -msgstr "Monatlich" - -#: common/updates.cpp:64 -msgid "" -msgstr "" - -#: engines/dialogs.cpp:85 -msgid "~R~esume" -msgstr "~F~ortsetzen" - -#: engines/dialogs.cpp:87 engines/mohawk/dialogs.cpp:140 -msgid "~L~oad" -msgstr "~L~aden" - -#: engines/dialogs.cpp:91 engines/mohawk/dialogs.cpp:141 -msgid "~S~ave" -msgstr "~S~peichern" - -#: engines/dialogs.cpp:95 -msgid "~O~ptions" -msgstr "~O~ptionen" - -#: engines/dialogs.cpp:100 -msgid "~H~elp" -msgstr "~H~ilfe" - -#: engines/dialogs.cpp:102 -msgid "~A~bout" -msgstr "Übe~r~" - -#: engines/dialogs.cpp:105 engines/dialogs.cpp:181 -msgid "~R~eturn to Launcher" -msgstr "Zur Spiele~l~iste zurück" - -#: engines/dialogs.cpp:107 engines/dialogs.cpp:183 -msgctxt "lowres" -msgid "~R~eturn to Launcher" -msgstr "Zur Spiele~l~iste" - -#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761 -#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72 -#: engines/cge2/events.cpp:64 engines/cine/various.cpp:348 -#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199 -#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262 -#: engines/glk/streams.cpp:1408 engines/gnap/menu.cpp:464 -#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350 -#: engines/mohawk/dialogs.cpp:163 engines/mohawk/myst.cpp:954 -#: engines/mohawk/riven.cpp:685 engines/neverhood/menumodule.cpp:880 -#: engines/pegasus/pegasus.cpp:379 engines/sci/engine/guest_additions.cpp:675 -#: engines/sci/engine/kfile.cpp:1054 engines/sherlock/scalpel/scalpel.cpp:1250 -#: engines/sherlock/tattoo/widget_files.cpp:75 engines/startrek/saveload.cpp:42 -#: engines/toltecs/menu.cpp:291 engines/toon/toon.cpp:3340 -#: engines/tsage/scenes.cpp:599 engines/wage/saveload.cpp:758 -#: engines/zvision/file/save_manager.cpp:49 -msgid "Save game:" -msgstr "Speichern:" - -#: engines/dialogs.cpp:116 backends/platform/symbian/src/SymbianActions.cpp:44 -#: backends/platform/wince/CEActionsPocket.cpp:43 -#: backends/platform/wince/CEActionsPocket.cpp:267 -#: backends/platform/wince/CEActionsSmartphone.cpp:45 -#: backends/platform/wince/CEActionsSmartphone.cpp:231 -#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900 -#: engines/cge/events.cpp:72 engines/cge2/events.cpp:64 -#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212 -#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383 -#: engines/dreamweb/saveload.cpp:262 engines/glk/streams.cpp:1408 -#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298 -#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:163 -#: engines/mohawk/myst.cpp:954 engines/mohawk/riven.cpp:685 -#: engines/neverhood/menumodule.cpp:880 engines/parallaction/saveload.cpp:209 -#: engines/pegasus/pegasus.cpp:379 engines/sci/engine/guest_additions.cpp:676 -#: engines/sci/engine/kfile.cpp:1054 engines/scumm/dialogs.cpp:184 -#: engines/sherlock/scalpel/scalpel.cpp:1250 -#: engines/sherlock/tattoo/widget_files.cpp:75 engines/startrek/saveload.cpp:42 -#: engines/toltecs/menu.cpp:291 engines/toon/toon.cpp:3340 -#: engines/tsage/scenes.cpp:599 engines/wage/saveload.cpp:758 -#: engines/zvision/file/save_manager.cpp:49 -msgid "Save" -msgstr "Speichern" - -#: engines/dialogs.cpp:145 -msgid "" -"Sorry, this engine does not currently provide in-game help. Please consult " -"the README for basic information, and for instructions on how to obtain " -"further assistance." -msgstr "" -"Leider bietet diese Engine keine Spielhilfe. Bitte lesen Sie die LIESMICH-" -"Datei für grundlegende Informationen und Anweisungen zu weiterer Hilfe." - -#: engines/dialogs.cpp:234 engines/pegasus/pegasus.cpp:395 -#, c-format -msgid "" -"Failed to save game (%s)! Please consult the README for basic information, " -"and for instructions on how to obtain further assistance." -msgstr "" -"Speichern des Spielstands %s fehlgeschlagen! Bitte lesen Sie die LIESMICH-" -"Datei für grundlegende Informationen und Anweisungen zu weiterer Hilfe." - -#: engines/dialogs.cpp:307 engines/mohawk/dialogs.cpp:98 -#: engines/tsage/dialogs.cpp:112 -msgid "~O~K" -msgstr "~O~K" - -#: engines/dialogs.cpp:308 engines/mohawk/dialogs.cpp:99 -#: engines/tsage/dialogs.cpp:113 -msgid "~C~ancel" -msgstr "~A~bbrechen" - -#: engines/dialogs.cpp:311 -msgid "~K~eys" -msgstr "~T~asten" - -#: engines/engine.cpp:317 -msgid "Could not initialize color format." -msgstr "Konnte Farbenformat nicht initialisieren." - -#: engines/engine.cpp:325 -msgid "Could not switch to video mode: '" -msgstr "Konnte nicht zu Grafikmodus wechseln: \"" - -#: engines/engine.cpp:334 -msgid "Could not switch to stretch mode: '" -msgstr "Fehler beim Wechsel in Skaliermodus: '" - -#: engines/engine.cpp:343 -msgid "Could not apply aspect ratio setting." -msgstr "Konnte Einstellung für Seitenverhältniskorrektur nicht anwenden." - -#: engines/engine.cpp:348 -msgid "Could not apply fullscreen setting." -msgstr "Konnte Einstellung für Vollbildmodus nicht anwenden." - -#: engines/engine.cpp:353 -msgid "Could not apply filtering setting." -msgstr "Konnte Filtereinstellungen nicht anwenden." - -#: engines/engine.cpp:461 -msgid "" -"You appear to be playing this game directly\n" -"from the CD. This is known to cause problems,\n" -"and it is therefore recommended that you copy\n" -"the data files to your hard disk instead.\n" -"See the README file for details." -msgstr "" -"Sie scheinen dieses Spiel direkt von CD zu\n" -"spielen. Dies kann bekanntermaßen zu Problemen\n" -"führen und es wird deshalb empfohlen, die\n" -"Dateien des Spiels auf die Festplatte zu\n" -"kopieren und von dort aus zu spielen.\n" -"Lesen Sie die Liesmich-Datei für\n" -"weitere Informationen." - -#: engines/engine.cpp:472 -msgid "" -"This game has audio tracks in its disk. These\n" -"tracks need to be ripped from the disk using\n" -"an appropriate CD audio extracting tool in\n" -"order to listen to the game's music.\n" -"See the README file for details." -msgstr "" -"Dieses Spiel hat Audio-Titel auf seiner CD.\n" -"Diese Titel müssen von der CD mittels eines\n" -"geeigneten Extrahierungsprogramms für\n" -"Audio-CDs beschafft werden, um diese im\n" -"Spiel hören zu können. Lesen Sie die\n" -"Liesmich-Datei für weitere Informationen." - -#: engines/engine.cpp:530 -#, c-format -msgid "" -"Failed to load saved game (%s)! Please consult the README for basic " -"information, and for instructions on how to obtain further assistance." -msgstr "" -"Laden des Spielstands %s fehlgeschlagen! Bitte lesen Sie die LIESMICH-Datei " -"für grundlegende Informationen und Anweisungen zu weiterer Hilfe." - -#: engines/engine.cpp:543 -msgid "" -"WARNING: The game you are about to start is not yet fully supported by " -"ScummVM. As such, it is likely to be unstable, and any saved game you make " -"might not work in future versions of ScummVM." -msgstr "" -"WARNUNG: Das Spiel, welches Sie starten wollen, wird noch nicht vollständig " -"von ScummVM unterstützt. Somit ist es wahrscheinlich, dass es instabil ist " -"und jegliche Spielstände, die Sie erstellen, könnten in zukünftigen " -"Versionen von ScummVM nicht mehr funktionieren." - -#: engines/engine.cpp:546 engines/wintermute/wintermute.cpp:165 -msgid "Start anyway" -msgstr "Trotzdem starten" - -#: engines/game.cpp:166 -#, c-format -msgid "" -"The game in '%s' seems to be an unknown game variant.\n" -"\n" -"Please report the following data to the ScummVM team at %s along with the " -"name of the game you tried to add and its version, language, etc.:" -msgstr "" -"Das Spiel in '%s' scheint eine unbekannte Version zu sein.\n" -"\n" -"Bitte teilen Sie dem ScummVM-Team unter %s die folgenden Informationen " -"zusammen mit dem Namen, der Version und der Sprache des Spiels, welches Sie " -"hinzufügen möchten, mit:" - -#: engines/game.cpp:170 -#, c-format -msgid "Matched game IDs for the %s engine:" -msgstr "Übereinstimmende Spiele-IDs für die Engine %s:" - -#: audio/adlib.cpp:2290 -msgid "AdLib emulator" -msgstr "AdLib-Emulator" - -#: audio/fmopl.cpp:71 -msgid "MAME OPL emulator" -msgstr "MAME OPL-Emulator" - -#: audio/fmopl.cpp:73 -msgid "DOSBox OPL emulator" -msgstr "DOSBox OPL-Emulator" - -#: audio/fmopl.cpp:76 -msgid "Nuked OPL emulator" -msgstr "Nuked OPL-Emulator" - -#: audio/fmopl.cpp:79 -msgid "ALSA Direct FM" -msgstr "ALSA Direct FM" - -#: audio/fmopl.cpp:82 -msgid "OPL2LPT" -msgstr "OPL2LPT" - -#: audio/mididrv.cpp:209 -#, c-format -msgid "" -"The selected audio device '%s' was not found (e.g. might be turned off or " -"disconnected)." -msgstr "" -"Das ausgewählte Audiogerät \"%s\" wurde nicht gefunden (könnte " -"beispielsweise ausgeschaltet oder nicht angeschlossen sein)." - -#: audio/mididrv.cpp:209 audio/mididrv.cpp:221 audio/mididrv.cpp:257 -#: audio/mididrv.cpp:272 -msgid "Attempting to fall back to the next available device..." -msgstr "Es wird versucht, auf das nächste verfügbare Gerät zurückzugreifen." - -#: audio/mididrv.cpp:221 -#, c-format -msgid "" -"The selected audio device '%s' cannot be used. See log file for more " -"information." -msgstr "" -"Das ausgewählte Audiogerät \"%s\" kann nicht verwendet werden. Schauen Sie " -"für weitere Informationen in der Log-Datei nach." - -#: audio/mididrv.cpp:257 -#, c-format -msgid "" -"The preferred audio device '%s' was not found (e.g. might be turned off or " -"disconnected)." -msgstr "" -"Das bevorzugte Audiogerät \"%s\" wurde nicht gefunden (könnte beispielsweise " -"ausgeschaltet oder nicht angeschlossen sein)." - -#: audio/mididrv.cpp:272 -#, c-format -msgid "" -"The preferred audio device '%s' cannot be used. See log file for more " -"information." -msgstr "" -"Das bevorzugte Audiogerät \"%s\" kann nicht verwendet werden. Schauen Sie " -"für weitere Informationen in der Log-Datei nach." - -#: audio/mods/paula.cpp:303 -msgid "Amiga Audio emulator" -msgstr "Amiga-Audio-Emulator" - -#: audio/null.h:44 -msgid "No music" -msgstr "Keine Musik" - -#: audio/softsynth/appleiigs.cpp:33 -msgid "Apple II GS emulator (NOT IMPLEMENTED)" -msgstr "Apple II GS-Emulator (NICHT INTEGRIERT)" - -#: audio/softsynth/cms.cpp:350 -msgid "Creative Music System emulator" -msgstr "Creative Music System-Emulator" - -#: audio/softsynth/fmtowns_pc98/towns_pc98_plugins.cpp:33 -msgid "FM-Towns Audio" -msgstr "FM-Towns-Audio" - -#: audio/softsynth/fmtowns_pc98/towns_pc98_plugins.cpp:58 -msgid "PC-98 Audio" -msgstr "PC-98-Audio" - -#: audio/softsynth/mt32.cpp:175 -msgid "Initializing MT-32 Emulator" -msgstr "Initialisiere MT-32-Emulator" - -#: audio/softsynth/mt32.cpp:437 -msgid "MT-32 emulator" -msgstr "MT-32-Emulator" - -#: audio/softsynth/pcspk.cpp:139 -msgid "PC Speaker emulator" -msgstr "PC-Lautsprecher-Emulator" - -#: audio/softsynth/pcspk.cpp:158 -msgid "IBM PCjr emulator" -msgstr "IBM PCjr-Emulator" - -#: audio/softsynth/sid.cpp:1430 -msgid "C64 Audio emulator" -msgstr "C64-Audio-Emulator" - -#: backends/cloud/storage.cpp:211 -msgid "Saved games sync complete." -msgstr "Spielstände synchronisiert." - -#: backends/cloud/storage.cpp:222 -msgid "Saved games sync was cancelled." -msgstr "Spielstand-Synchronisierung abgebrochen." - -#: backends/cloud/storage.cpp:224 -msgid "" -"Saved games sync failed.\n" -"Check your Internet connection." -msgstr "" -"Spielstand-Synchronisierung fehlgeschlagen.\n" -"Überprüfen Sie Ihre Internetverbindung." - -#: backends/cloud/storage.cpp:328 -#, c-format -msgid "" -"Download complete.\n" -"Failed to download %u files." -msgstr "" -"Download abgeschlossen.\n" -"%u Dateien konnten nicht heruntergeladen werden." - -#: backends/cloud/storage.cpp:330 -msgid "Download complete." -msgstr "Download abgeschlossen." - -#: backends/cloud/storage.cpp:340 -msgid "Download failed." -msgstr "Download fehlgeschlagen." - -#: backends/events/default/default-events.cpp:190 -msgid "Do you really want to return to the Launcher?" -msgstr "Möchten Sie wirklich zur Spieleliste zurückkehren?" - -#: backends/events/default/default-events.cpp:190 -msgid "Launcher" -msgstr "Spieleliste" - -#: backends/events/default/default-events.cpp:212 -msgid "Do you really want to quit?" -msgstr "Möchten Sie wirklich beenden?" - -#: backends/events/default/default-events.cpp:212 -#: backends/platform/symbian/src/SymbianActions.cpp:52 -#: backends/platform/wince/CEActionsPocket.cpp:44 -#: backends/platform/wince/CEActionsSmartphone.cpp:52 -#: engines/mohawk/myst_stacks/menu.cpp:318 -#: engines/mohawk/riven_stacks/aspit.cpp:455 engines/scumm/dialogs.cpp:188 -#: engines/scumm/help.cpp:83 engines/scumm/help.cpp:85 -msgid "Quit" -msgstr "Beenden" - -#: backends/events/gph/gph-events.cpp:391 -#: backends/events/gph/gph-events.cpp:434 -#: backends/events/openpandora/op-events.cpp:174 -msgid "Touchscreen 'Tap Mode' - Left Click" -msgstr "Touchscreen-Tipp-Modus - Linksklick" - -#: backends/events/gph/gph-events.cpp:393 -#: backends/events/gph/gph-events.cpp:436 -#: backends/events/openpandora/op-events.cpp:176 -msgid "Touchscreen 'Tap Mode' - Right Click" -msgstr "Touchscreen-Tipp-Modus - Rechtsklick" - -#: backends/events/gph/gph-events.cpp:395 -#: backends/events/gph/gph-events.cpp:438 -#: backends/events/openpandora/op-events.cpp:178 -msgid "Touchscreen 'Tap Mode' - Hover (No Click)" -msgstr "Touchscreen-Tipp-Modus - schweben (kein Klick)" - -#: backends/events/gph/gph-events.cpp:415 -msgid "Maximum Volume" -msgstr "Höchste Lautstärke" - -#: backends/events/gph/gph-events.cpp:417 -msgid "Increasing Volume" -msgstr "Lautstärke höher" - -#: backends/events/gph/gph-events.cpp:423 -msgid "Minimal Volume" -msgstr "Niedrigste Lautstärke" - -#: backends/events/gph/gph-events.cpp:425 -msgid "Decreasing Volume" -msgstr "Lautstärke niedriger" - -#: backends/events/maemosdl/maemosdl-events.cpp:180 -msgid "Clicking Enabled" -msgstr "Klicken aktiviert" - -#: backends/events/maemosdl/maemosdl-events.cpp:180 -msgid "Clicking Disabled" -msgstr "Klicken deaktiviert" - -#: backends/events/openpandora/op-events.cpp:180 -msgid "Touchscreen 'Tap Mode' - Hover (DPad Clicks)" -msgstr "Touchscreen-Tipp-Modus - schweben (DPad-Klicks)" - -#: backends/events/symbiansdl/symbiansdl-events.cpp:191 -msgid "Do you want to quit ?" -msgstr "Möchten Sie beenden?" - -#. I18N: Trackpad mode toggle status. -#: backends/events/webossdl/webossdl-events.cpp:332 -msgid "Trackpad mode is now" -msgstr "Trackpad-Modus ist jetzt" - -#. I18N: Trackpad mode on or off. -#. I18N: Auto-drag on or off. -#: backends/events/webossdl/webossdl-events.cpp:335 -#: backends/events/webossdl/webossdl-events.cpp:362 -msgid "ON" -msgstr "AN" - -#: backends/events/webossdl/webossdl-events.cpp:335 -#: backends/events/webossdl/webossdl-events.cpp:362 -msgid "OFF" -msgstr "AUS" - -#: backends/events/webossdl/webossdl-events.cpp:339 -msgid "Swipe two fingers to the right to toggle." -msgstr "Zum Umschalten mit zwei Fingern nach rechts wischen." - -#. I18N: Auto-drag toggle status. -#: backends/events/webossdl/webossdl-events.cpp:359 -msgid "Auto-drag mode is now" -msgstr "Automatisches Ziehen ist jetzt" - -#: backends/events/webossdl/webossdl-events.cpp:366 -msgid "Swipe three fingers to the right to toggle." -msgstr "Zum Umschalten mit drei Fingern nach rechts wischen." - -#: backends/graphics/opengl/opengl-graphics.cpp:152 -msgid "OpenGL" -msgstr "OpenGL" - -#: backends/graphics/opengl/opengl-graphics.cpp:240 -#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:75 -msgid "Center" -msgstr "Zentriert" - -#: backends/graphics/opengl/opengl-graphics.cpp:241 -#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:76 -msgid "Pixel-perfect scaling" -msgstr "Pixelgenaue Skalierung" - -#: backends/graphics/opengl/opengl-graphics.cpp:242 -#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:77 -msgid "Fit to window" -msgstr "An Fenster anpassen" - -#: backends/graphics/opengl/opengl-graphics.cpp:243 -#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:78 -msgid "Stretch to window" -msgstr "Auf Fenstergröße strecken" - -#: backends/graphics/openglsdl/openglsdl-graphics.cpp:603 -#, c-format -msgid "Resolution: %dx%d" -msgstr "Auflösung: %dx%d" - -#: backends/graphics/openglsdl/openglsdl-graphics.cpp:624 -#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2511 -msgid "Enabled aspect ratio correction" -msgstr "Seitenverhältniskorrektur an" - -#: backends/graphics/openglsdl/openglsdl-graphics.cpp:626 -#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2517 -msgid "Disabled aspect ratio correction" -msgstr "Seitenverhältniskorrektur aus" - -#: backends/graphics/openglsdl/openglsdl-graphics.cpp:646 -#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2534 -msgid "Filtering enabled" -msgstr "Bilineare Filterung aktiviert" - -#: backends/graphics/openglsdl/openglsdl-graphics.cpp:648 -#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2536 -msgid "Filtering disabled" -msgstr "Bilineare Filterung deaktiviert" - -#: backends/graphics/openglsdl/openglsdl-graphics.cpp:676 -#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2565 -msgid "Stretch mode" -msgstr "Skaliermodus" - -#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:54 -#: backends/graphics/wincesdl/wincesdl-graphics.cpp:88 -#: backends/graphics/wincesdl/wincesdl-graphics.cpp:95 -msgid "Normal (no scaling)" -msgstr "Normal (keine Skalierung)" - -#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:83 -msgctxt "lowres" -msgid "Normal (no scaling)" -msgstr "Normal ohn.Skalieren" - -#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2627 -msgid "Active graphics filter:" -msgstr "Aktiver Grafikfilter:" - -#: backends/keymapper/remap-dialog.cpp:48 -msgid "Keymap:" -msgstr "Tasten-Layout:" - -#: backends/keymapper/remap-dialog.cpp:67 -msgid " (Effective)" -msgstr " (Aktuell)" - -#: backends/keymapper/remap-dialog.cpp:107 -msgid " (Active)" -msgstr " (Aktiv)" - -#: backends/keymapper/remap-dialog.cpp:107 -msgid " (Blocked)" -msgstr " (Blockiert)" - -#: backends/keymapper/remap-dialog.cpp:120 -msgid " (Global)" -msgstr " (Global)" - -#: backends/keymapper/remap-dialog.cpp:128 -msgid " (Game)" -msgstr " (Spiel)" - -#: backends/midi/windows.cpp:163 -msgid "Windows MIDI" -msgstr "Windows MIDI" - -#: backends/platform/ds/arm9/source/dsoptions.cpp:56 -#: engines/scumm/dialogs.cpp:287 -msgid "~C~lose" -msgstr "~S~chließen" - -#: backends/platform/ds/arm9/source/dsoptions.cpp:57 -msgid "ScummVM Main Menu" -msgstr "ScummVM-Hauptmenü" - -#: backends/platform/ds/arm9/source/dsoptions.cpp:63 -msgid "~L~eft handed mode" -msgstr "~L~inke-Hand-Modus" - -#: backends/platform/ds/arm9/source/dsoptions.cpp:64 -msgid "~I~ndy fight controls" -msgstr "~K~ampfsteuerung für Indiana Jones" - -#: backends/platform/ds/arm9/source/dsoptions.cpp:65 -msgid "Show mouse cursor" -msgstr "Mauszeiger anzeigen" - -#: backends/platform/ds/arm9/source/dsoptions.cpp:66 -msgid "Snap to edges" -msgstr "An Ecken anheften" - -#: backends/platform/ds/arm9/source/dsoptions.cpp:68 -msgid "Touch X Offset" -msgstr "Zu X-Position gehen" - -#: backends/platform/ds/arm9/source/dsoptions.cpp:75 -msgid "Touch Y Offset" -msgstr "Zu Y-Position gehen" - -#: backends/platform/ds/arm9/source/dsoptions.cpp:87 -msgid "Use laptop trackpad-style cursor control" -msgstr "Den Trackpad-Modus für Maussteuerung benutzen" - -#: backends/platform/ds/arm9/source/dsoptions.cpp:88 -msgid "Tap for left click, double tap right click" -msgstr "Tippen für Linksklick, Doppeltippen für Rechtsklick" - -#: backends/platform/ds/arm9/source/dsoptions.cpp:90 -msgid "Sensitivity" -msgstr "Empfindlichkeit" - -#: backends/platform/ds/arm9/source/dsoptions.cpp:99 -msgid "Initial top screen scale:" -msgstr "Vergrößerung des oberen Bildschirms:" - -#: backends/platform/ds/arm9/source/dsoptions.cpp:105 -msgid "Main screen scaling:" -msgstr "Hauptbildschirm-Skalierung:" - -#: backends/platform/ds/arm9/source/dsoptions.cpp:107 -msgid "Hardware scale (fast, but low quality)" -msgstr "Hardware-Skalierung (schnell, aber schlechte Qualität)" - -#: backends/platform/ds/arm9/source/dsoptions.cpp:108 -msgid "Software scale (good quality, but slower)" -msgstr "Software-Skalierung (gute Qualität, aber langsamer)" - -#: backends/platform/ds/arm9/source/dsoptions.cpp:109 -msgid "Unscaled (you must scroll left and right)" -msgstr "Nicht skalieren (Sie müssen nach links und nach rechts scrollen)" - -#: backends/platform/ds/arm9/source/dsoptions.cpp:111 -msgid "Brightness:" -msgstr "Helligkeit:" - -#: backends/platform/ds/arm9/source/dsoptions.cpp:121 -msgid "High quality audio (slower) (reboot)" -msgstr "Hohe Audioqualität (langsamer) (erfordert Neustart)" - -#: backends/platform/ds/arm9/source/dsoptions.cpp:122 -msgid "Disable power off" -msgstr "Stromsparmodus abschalten" - -#: backends/platform/ios7/ios7_osys_events.cpp:309 -#: backends/platform/ios7/ios7_osys_events.cpp:519 -#: backends/platform/iphone/osys_events.cpp:300 -msgid "Mouse-click-and-drag mode enabled." -msgstr "Maus-klick-und-zieh-Modus aktiviert." - -#: backends/platform/ios7/ios7_osys_events.cpp:311 -#: backends/platform/ios7/ios7_osys_events.cpp:521 -#: backends/platform/iphone/osys_events.cpp:302 -msgid "Mouse-click-and-drag mode disabled." -msgstr "Maus-klick-und-zieh-Modus ausgeschaltet." - -#: backends/platform/ios7/ios7_osys_events.cpp:322 -#: backends/platform/ios7/ios7_osys_events.cpp:540 -#: backends/platform/iphone/osys_events.cpp:313 -msgid "Touchpad mode enabled." -msgstr "Touchpad-Modus aktiviert." - -#: backends/platform/ios7/ios7_osys_events.cpp:324 -#: backends/platform/ios7/ios7_osys_events.cpp:542 -#: backends/platform/iphone/osys_events.cpp:315 -msgid "Touchpad mode disabled." -msgstr "Touchpad-Modus ausgeschaltet." - -#: backends/platform/maemo/maemo.cpp:206 -msgid "Click Mode" -msgstr "Klickmodus" - -#: backends/platform/maemo/maemo.cpp:212 -#: backends/platform/symbian/src/SymbianActions.cpp:42 -#: backends/platform/tizen/form.cpp:274 -#: backends/platform/wince/CEActionsPocket.cpp:60 -#: backends/platform/wince/CEActionsSmartphone.cpp:43 -msgid "Left Click" -msgstr "Linksklick" - -#: backends/platform/maemo/maemo.cpp:215 -msgid "Middle Click" -msgstr "Mittelklick" - -#: backends/platform/maemo/maemo.cpp:218 -#: backends/platform/symbian/src/SymbianActions.cpp:43 -#: backends/platform/tizen/form.cpp:266 -#: backends/platform/wince/CEActionsSmartphone.cpp:44 -msgid "Right Click" -msgstr "Rechtsklick" - -#: backends/platform/sdl/macosx/appmenu_osx.mm:205 -msgid "Hide ScummVM" -msgstr "ScummVM ausblenden" - -#: backends/platform/sdl/macosx/appmenu_osx.mm:206 -msgid "Hide Others" -msgstr "Andere ausblenden" - -#: backends/platform/sdl/macosx/appmenu_osx.mm:207 -msgid "Show All" -msgstr "Alle einblenden" - -#: backends/platform/sdl/macosx/appmenu_osx.mm:211 -msgid "Window" -msgstr "Fenster" - -#: backends/platform/sdl/macosx/appmenu_osx.mm:212 -msgid "Minimize" -msgstr "Minimieren" - -#: backends/platform/sdl/macosx/appmenu_osx.mm:214 -msgid "Help" -msgstr "Hilfe" - -#: backends/platform/sdl/macosx/appmenu_osx.mm:215 -msgid "User Manual" -msgstr "Benutzer-Handbuch" - -#: backends/platform/sdl/macosx/appmenu_osx.mm:217 -msgid "General Information" -msgstr "Allgemeine Informationen" - -#: backends/platform/sdl/macosx/appmenu_osx.mm:218 -msgid "What's New in ScummVM" -msgstr "Neues in ScummVM" - -#: backends/platform/sdl/macosx/appmenu_osx.mm:220 -msgid "Credits" -msgstr "Mitwirkende" - -#: backends/platform/sdl/macosx/appmenu_osx.mm:221 -msgid "GPL License" -msgstr "GPL-Lizenz" - -#: backends/platform/sdl/macosx/appmenu_osx.mm:222 -msgid "LGPL License" -msgstr "LGPL-Lizenz" - -#: backends/platform/sdl/macosx/appmenu_osx.mm:223 -msgid "Freefont License" -msgstr "Freefont-Lizenz" - -#: backends/platform/sdl/macosx/appmenu_osx.mm:224 -msgid "OFL License" -msgstr "OFL-Lizenz" - -#: backends/platform/sdl/macosx/appmenu_osx.mm:225 -msgid "BSD License" -msgstr "BSD-Lizenz" - -#: backends/platform/symbian/src/SymbianActions.cpp:38 -#: backends/platform/wince/CEActionsSmartphone.cpp:39 -#: engines/glk/scott/scott.cpp:394 -msgid "Up" -msgstr "Hoch" - -#: backends/platform/symbian/src/SymbianActions.cpp:39 -#: backends/platform/wince/CEActionsSmartphone.cpp:40 -#: engines/glk/scott/scott.cpp:394 -msgid "Down" -msgstr "Runter" - -#: backends/platform/symbian/src/SymbianActions.cpp:40 -#: backends/platform/wince/CEActionsSmartphone.cpp:41 -msgid "Left" -msgstr "Links" - -#: backends/platform/symbian/src/SymbianActions.cpp:41 -#: backends/platform/wince/CEActionsSmartphone.cpp:42 -msgid "Right" -msgstr "Rechts" - -#: backends/platform/symbian/src/SymbianActions.cpp:46 -#: backends/platform/wince/CEActionsSmartphone.cpp:47 -msgid "Zone" -msgstr "Zone" - -#: backends/platform/symbian/src/SymbianActions.cpp:47 -#: backends/platform/wince/CEActionsPocket.cpp:54 -#: backends/platform/wince/CEActionsSmartphone.cpp:48 -msgid "Multi Function" -msgstr "Multifunktion" - -#: backends/platform/symbian/src/SymbianActions.cpp:48 -msgid "Swap character" -msgstr "Figur wechseln" - -#: backends/platform/symbian/src/SymbianActions.cpp:49 -msgid "Skip text" -msgstr "Text überspringen" - -#: backends/platform/symbian/src/SymbianActions.cpp:51 -msgid "Fast mode" -msgstr "Schneller Modus" - -#: backends/platform/symbian/src/SymbianActions.cpp:53 -msgid "Debugger" -msgstr "Debugger" - -#: backends/platform/symbian/src/SymbianActions.cpp:54 -msgid "Global menu" -msgstr "Hauptmenü" - -#: backends/platform/symbian/src/SymbianActions.cpp:55 -msgid "Virtual keyboard" -msgstr "Virtuelle Tastatur" - -#: backends/platform/symbian/src/SymbianActions.cpp:56 -msgid "Key mapper" -msgstr "Tasten zuordnen" - -#: backends/platform/tizen/form.cpp:262 -msgid "Right Click Once" -msgstr "Einmal Rechtsklick" - -#: backends/platform/tizen/form.cpp:270 -msgid "Move Only" -msgstr "Nur bewegen" - -#: backends/platform/tizen/form.cpp:293 -msgid "Escape Key" -msgstr "Escape-Taste" - -#: backends/platform/tizen/form.cpp:298 -msgid "Game Menu" -msgstr "Spielmenü" - -#: backends/platform/tizen/form.cpp:303 -msgid "Show Keypad" -msgstr "Ziffernblock zeigen" - -#: backends/platform/tizen/form.cpp:308 -msgid "Control Mouse" -msgstr "Maus steuern" - -#: backends/platform/tizen/fs.cpp:259 -msgid "[ Data ]" -msgstr "[ Daten ]" - -#: backends/platform/tizen/fs.cpp:263 -msgid "[ Resources ]" -msgstr "[ Ressourcen ]" - -#: backends/platform/tizen/fs.cpp:267 -msgid "[ SDCard ]" -msgstr "[ SD-Karte ]" - -#: backends/platform/tizen/fs.cpp:271 -msgid "[ Media ]" -msgstr "[ Datenträger ]" - -#: backends/platform/tizen/fs.cpp:275 -msgid "[ Shared ]" -msgstr "[ Öffentlich ]" - -#: backends/platform/wii/options.cpp:51 -msgid "Video" -msgstr "Video" - -#: backends/platform/wii/options.cpp:54 -msgid "Current video mode:" -msgstr "Aktueller Grafikmodus:" - -#: backends/platform/wii/options.cpp:56 -msgid "Double-strike" -msgstr "Doppelzeilen (kein Zeilensprungverfahren)" - -#: backends/platform/wii/options.cpp:60 -msgid "Horizontal underscan:" -msgstr "Horizontale Bildverkleinerung:" - -#: backends/platform/wii/options.cpp:66 -msgid "Vertical underscan:" -msgstr "Vertikale Bildverkleinerung:" - -#: backends/platform/wii/options.cpp:71 -msgid "Input" -msgstr "Eingabe" - -#: backends/platform/wii/options.cpp:74 -msgid "GC Pad sensitivity:" -msgstr "GC-Pad-Empfindlichkeit:" - -#: backends/platform/wii/options.cpp:80 -msgid "GC Pad acceleration:" -msgstr "GC-Pad-Beschleunigung:" - -#: backends/platform/wii/options.cpp:86 -msgid "DVD" -msgstr "DVD" - -#: backends/platform/wii/options.cpp:89 backends/platform/wii/options.cpp:101 -msgid "Status:" -msgstr "Status:" - -#: backends/platform/wii/options.cpp:90 backends/platform/wii/options.cpp:102 -msgid "Unknown" -msgstr "Unbekannt" - -#: backends/platform/wii/options.cpp:93 -msgid "Mount DVD" -msgstr "DVD einbinden" - -#: backends/platform/wii/options.cpp:94 -msgid "Unmount DVD" -msgstr "DVD aushängen" - -#: backends/platform/wii/options.cpp:98 -msgid "SMB" -msgstr "SMB" - -#: backends/platform/wii/options.cpp:106 -msgid "Server:" -msgstr "Server:" - -#: backends/platform/wii/options.cpp:110 -msgid "Share:" -msgstr "Öffentliches Verzeichnis:" - -#: backends/platform/wii/options.cpp:118 -msgid "Password:" -msgstr "Passwort:" - -#: backends/platform/wii/options.cpp:121 -msgid "Init network" -msgstr "Netzwerk starten" - -#: backends/platform/wii/options.cpp:123 -msgid "Mount SMB" -msgstr "SMB einbinden" - -#: backends/platform/wii/options.cpp:124 -msgid "Unmount SMB" -msgstr "SMB aushängen" - -#: backends/platform/wii/options.cpp:143 -msgid "DVD Mounted successfully" -msgstr "DVD erfolgreich eingebunden" - -#: backends/platform/wii/options.cpp:146 -msgid "Error while mounting the DVD" -msgstr "Fehler beim Einbinden der DVD" - -#: backends/platform/wii/options.cpp:148 -msgid "DVD not mounted" -msgstr "DVD nicht eingebunden" - -#: backends/platform/wii/options.cpp:161 -msgid "Network up, share mounted" -msgstr "Netzwerk gestartet, öffentliches Verzeichnis eingebunden" - -#: backends/platform/wii/options.cpp:163 -msgid "Network up" -msgstr "Netzwerk gestartet" - -#: backends/platform/wii/options.cpp:166 -msgid ", error while mounting the share" -msgstr ", Fehler beim Einbinden des öffentlichen Verzeichnisses" - -#: backends/platform/wii/options.cpp:168 -msgid ", share not mounted" -msgstr ", öffentliches Verzeichnis nicht eingebunden" - -#: backends/platform/wii/options.cpp:174 -msgid "Network down" -msgstr "Netzwerk ist nicht verfügbar" - -#: backends/platform/wii/options.cpp:178 -msgid "Initializing network" -msgstr "Netzwerk wird gestartet" - -#: backends/platform/wii/options.cpp:182 -msgid "Timeout while initializing network" -msgstr "Zeitüberschreitung beim Starten des Netzwerks" - -#: backends/platform/wii/options.cpp:186 -#, c-format -msgid "Network not initialized (%d)" -msgstr "Netzwerk nicht gestartet (%d)" - -#: backends/platform/wince/CEActionsPocket.cpp:46 -msgid "Hide Toolbar" -msgstr "Werkzeugleiste verbergen" - -#: backends/platform/wince/CEActionsPocket.cpp:47 -msgid "Show Keyboard" -msgstr "Tastatur zeigen" - -#: backends/platform/wince/CEActionsPocket.cpp:48 -msgid "Sound on/off" -msgstr "Ton ein/aus" - -#: backends/platform/wince/CEActionsPocket.cpp:49 -msgid "Right click" -msgstr "Rechtsklick" - -#: backends/platform/wince/CEActionsPocket.cpp:50 -msgid "Show/Hide Cursor" -msgstr "Cursor zeigen/verbergen" - -#: backends/platform/wince/CEActionsPocket.cpp:51 -msgid "Free look" -msgstr "Freie Ansicht" - -#: backends/platform/wince/CEActionsPocket.cpp:52 -msgid "Zoom up" -msgstr "Herauszoomen" - -#: backends/platform/wince/CEActionsPocket.cpp:53 -msgid "Zoom down" -msgstr "Hineinzoomen" - -#: backends/platform/wince/CEActionsPocket.cpp:55 -#: backends/platform/wince/CEActionsSmartphone.cpp:49 -msgid "Bind Keys" -msgstr "Tasten zuweisen" - -#: backends/platform/wince/CEActionsPocket.cpp:56 -msgid "Cursor Up" -msgstr "Zeiger hoch" - -#: backends/platform/wince/CEActionsPocket.cpp:57 -msgid "Cursor Down" -msgstr "Zeiger runter" - -#: backends/platform/wince/CEActionsPocket.cpp:58 -msgid "Cursor Left" -msgstr "Zeiger nach links" - -#: backends/platform/wince/CEActionsPocket.cpp:59 -msgid "Cursor Right" -msgstr "Zeiger nach rechts" - -#: backends/platform/wince/CEActionsPocket.cpp:267 -#: backends/platform/wince/CEActionsSmartphone.cpp:231 -msgid "Do you want to load or save the game?" -msgstr "Möchten Sie ein Spiel laden oder speichern?" - -#: backends/platform/wince/CEActionsPocket.cpp:326 -#: backends/platform/wince/CEActionsSmartphone.cpp:287 -msgid " Are you sure you want to quit ? " -msgstr " Möchten Sie wirklich beenden? " - -#: backends/platform/wince/CEActionsSmartphone.cpp:50 -msgid "Keyboard" -msgstr "Tastatur" - -#: backends/platform/wince/CEActionsSmartphone.cpp:51 -msgid "Rotate" -msgstr "Drehen" - -#: backends/platform/wince/CELauncherDialog.cpp:56 -msgid "Using SDL driver " -msgstr "Verwende SDL-Treiber " - -#: backends/platform/wince/CELauncherDialog.cpp:60 -msgid "Display " -msgstr "Anzeige " - -#: backends/platform/wince/CELauncherDialog.cpp:83 -msgid "Do you want to perform an automatic scan ?" -msgstr "Möchten Sie eine automatische Suche durchführen?" - -#: backends/platform/wince/wince-sdl.cpp:518 -msgid "Map right click action" -msgstr "Aktion \"Rechtsklick\" zuweisen" - -#: backends/platform/wince/wince-sdl.cpp:522 -msgid "You must map a key to the 'Right Click' action to play this game" -msgstr "" -"Sie müssen der Aktion \"Rechtsklick\" eine Taste zuweisen, um dieses Spiel " -"spielen zu können" - -#: backends/platform/wince/wince-sdl.cpp:531 -msgid "Map hide toolbar action" -msgstr "Aktion \"Werkzeugleiste verbergen\" zuweisen" - -#: backends/platform/wince/wince-sdl.cpp:535 -msgid "You must map a key to the 'Hide toolbar' action to play this game" -msgstr "" -"Sie müssen der Aktion \"Werkzeugleiste verbergen\" eine Taste zuweisen, um " -"dieses Spiel spielen zu können" - -#: backends/platform/wince/wince-sdl.cpp:544 -msgid "Map Zoom Up action (optional)" -msgstr "Aktion \"Herauszoomen\" zuweisen (optional)" - -#: backends/platform/wince/wince-sdl.cpp:547 -msgid "Map Zoom Down action (optional)" -msgstr "Aktion \"Hineinzoomen\" zuweisen (optional)" - -#: backends/platform/wince/wince-sdl.cpp:555 -msgid "" -"Don't forget to map a key to 'Hide Toolbar' action to see the whole inventory" -msgstr "" -"Vergessen Sie nicht, der Aktion \"Werkzeugleiste verbergen\" eine Taste " -"zuzuweisen, um das ganze Inventar sehen zu können" - -#: backends/updates/macosx/macosx-updates.mm:79 -msgid "Check for Updates..." -msgstr "Suche nach Aktualisierungen..." - -#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:971 -#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64 -#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131 -#: engines/supernova/supernova.cpp:178 engines/teenagent/resources.cpp:97 -#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4926 -#, c-format -msgid "Unable to locate the '%s' engine data file." -msgstr "Engine-Datendatei '%s' kann nicht gefunden werden." - -#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:985 -#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73 -#: engines/mortevielle/mortevielle.cpp:314 engines/supernova/supernova.cpp:187 -#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4938 -#, c-format -msgid "The '%s' engine data file is corrupt." -msgstr "Die Engine-Datendatei '%s' ist beschädigt." - -#: engines/access/resources.cpp:61 engines/drascula/drascula.cpp:996 -#: engines/hugo/hugo.cpp:458 engines/lure/lure.cpp:76 -#: engines/mortevielle/mortevielle.cpp:324 engines/tony/tony.cpp:221 -#: engines/toon/toon.cpp:4949 -#, c-format -msgid "" -"Incorrect version of the '%s' engine data file found. Expected %d.%d but got " -"%d.%d." -msgstr "" -"Falsche Version der Engine-Datendatei '%s' gefunden. %d.%d erwartet, aber %d." -"%d bekommen." - -#: engines/adl/detection.cpp:49 engines/adl/detection.cpp:59 -msgid "Color mode" -msgstr "Farbmodus einschalten" - -#: engines/adl/detection.cpp:50 engines/adl/detection.cpp:60 -msgid "Use color graphics" -msgstr "Farbgrafik verwenden" - -#: engines/adl/detection.cpp:69 -msgid "Scanlines" -msgstr "Abtastzeilen/Scanlines" - -#: engines/adl/detection.cpp:70 -msgid "Show scanlines" -msgstr "Abtastzeilen (Scanlines) anzeigen" - -#: engines/agi/detection.cpp:147 engines/cine/detection.cpp:70 -#: engines/drascula/detection.cpp:331 engines/dreamweb/detection.cpp:48 -#: engines/neverhood/detection.cpp:177 engines/sci/detection.cpp:458 -#: engines/sherlock/detection.cpp:71 engines/toltecs/detection.cpp:200 -#: engines/zvision/detection_tables.h:51 -msgid "Use original save/load screens" -msgstr "Originale Spielstand-Menüs" - -#: engines/agi/detection.cpp:148 engines/cine/detection.cpp:71 -#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49 -#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:459 -#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201 -#: engines/zvision/detection_tables.h:52 -msgid "Use the original save/load screens instead of the ScummVM ones" -msgstr "" -"Verwende die originalen Speicher- und Lade-Menüs statt der Menüs von ScummVM" - -#: engines/agi/detection.cpp:157 -msgid "Use an alternative palette" -msgstr "Alternative Farbpalette verwenden" - -#: engines/agi/detection.cpp:158 -msgid "" -"Use an alternative palette, common for all Amiga games. This was the old " -"behavior" -msgstr "" -"Verwende eine alternative Farbpalette für alle Amiga-Spiele. Dies war das " -"alte Verhalten" - -#: engines/agi/detection.cpp:167 -msgid "Mouse support" -msgstr "Maus-Unterstützung" - -#: engines/agi/detection.cpp:168 -msgid "" -"Enables mouse support. Allows to use mouse for movement and in game menus." -msgstr "" -"Aktiviere Maus-Unterstützung. Erlaubt die Verwendung der Maus zur Bewegung " -"und in Menüs innerhalb des Spiels." - -#: engines/agi/detection.cpp:177 -msgid "Use Hercules hires font" -msgstr "Verwende hochauflösende Hercules-Schrift" - -#: engines/agi/detection.cpp:178 -msgid "Uses Hercules hires font, when font file is available." -msgstr "" -"Verwende hochauflösende Hercules-Schriftart, wenn die Schriftarten-Datei " -"verfügbar ist." - -#: engines/agi/detection.cpp:187 -msgid "Pause when entering commands" -msgstr "Pausiere, wenn Befehle eingegeben werden" - -#: engines/agi/detection.cpp:188 -msgid "" -"Shows a command prompt window and pauses the game (like in SCI) instead of a " -"real-time prompt." -msgstr "" -"Zeige ein Fenster mit einer Kommandozeile und pausiere das Spiel (wie in " -"SCI) anstelle einer Eingabe in Echtzeit." - -#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888 -#: engines/cge/events.cpp:83 engines/cge2/events.cpp:75 -#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276 -#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396 -#: engines/dreamweb/saveload.cpp:170 engines/glk/streams.cpp:1417 -#: engines/gnap/menu.cpp:473 engines/hugo/file.cpp:400 -#: engines/mads/nebular/dialogs_nebular.cpp:377 -#: engines/neverhood/menumodule.cpp:893 -#: engines/sci/engine/guest_additions.cpp:678 engines/sci/engine/kfile.cpp:1173 -#: engines/sherlock/scalpel/scalpel.cpp:1263 -#: engines/sherlock/tattoo/widget_files.cpp:94 engines/startrek/saveload.cpp:67 -#: engines/toltecs/menu.cpp:266 engines/toon/toon.cpp:3434 -#: engines/zvision/file/save_manager.cpp:62 -msgid "Restore game:" -msgstr "Spiel laden:" - -#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888 -#: engines/cge/events.cpp:83 engines/cge2/events.cpp:75 -#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276 -#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396 -#: engines/dreamweb/saveload.cpp:170 engines/glk/streams.cpp:1417 -#: engines/gnap/menu.cpp:473 engines/hugo/file.cpp:400 -#: engines/mads/nebular/dialogs_nebular.cpp:377 -#: engines/neverhood/menumodule.cpp:893 -#: engines/sci/engine/guest_additions.cpp:679 engines/sci/engine/kfile.cpp:1173 -#: engines/sherlock/scalpel/scalpel.cpp:1263 -#: engines/sherlock/tattoo/widget_files.cpp:94 engines/startrek/saveload.cpp:67 -#: engines/toltecs/menu.cpp:266 engines/toon/toon.cpp:3434 -#: engines/zvision/file/save_manager.cpp:62 -msgid "Restore" -msgstr "Laden" - -#: engines/agos/saveload.cpp:159 engines/scumm/scumm.cpp:2446 -#, c-format -msgid "" -"Failed to load saved game from file:\n" -"\n" -"%s" -msgstr "" -"Konnte Spielstand nicht aus folgender Datei laden:\n" -"\n" -"%s" - -#: engines/agos/saveload.cpp:194 engines/scumm/scumm.cpp:2436 -#, c-format -msgid "" -"Failed to save game to file:\n" -"\n" -"%s" -msgstr "" -"Konnte Spielstand nicht in folgender Datei speichern:\n" -"\n" -"%s" - -#: engines/agos/saveload.cpp:202 engines/scumm/scumm.cpp:2457 -#, c-format -msgid "" -"Successfully saved game in file:\n" -"\n" -"%s" -msgstr "" -"Spielstand erfolgreich in folgender Datei gespeichert:\n" -"\n" -"%s" - -#: engines/agos/animation.cpp:558 -#, c-format -msgid "Cutscene file '%s' not found!" -msgstr "Zwischensequenz \"%s\" nicht gefunden!" - -#: engines/bladerunner/bladerunner.cpp:322 -msgid "Failed to initialize resources" -msgstr "Konnte Ressourcen nicht initialisieren" - -#: engines/bladerunner/bladerunner.cpp:908 -msgid "A required game resource was not found" -msgstr "Eine benötigte Spiel-Ressource konnte nicht gefunden werden" - -#: engines/bladerunner/bladerunner.cpp:2039 -msgid "" -"WARNING: This game was saved in Restored Cut Content mode, but you are " -"playing in Original Content mode. The mode will be adjusted to Restored Cut " -"Content for this session until you completely Quit the game." -msgstr "" -"WARNUNG: Dieses Spiel wurde im \"Entfernte Inhalte wiederherstellen\"-Modus " -"gespeichert. Sie spielen das Spiel jedoch im \"Original-Inhalte\"-Modus. Der " -"Modus wird für diese Spielesitzung auf \"Entfernte Inhalte wiederherstellen" -"\" gesetzt, bis Sie das Spiel komplett beenden." - -#: engines/bladerunner/bladerunner.cpp:2041 -msgid "" -"WARNING: This game was saved in Original Content mode, but you are playing " -"in Restored Cut Content mode. The mode will be adjusted to Original Content " -"mode for this session until you completely Quit the game." -msgstr "" -"WARNUNG: Dieses Spiel wurde im \"Original-Inhalte\"-Modus gespeichert. Sie " -"spielen das Spiel jedoch im \"Entfernte Inhalte wiederherstellen\"-Modus. " -"Der Modus wird für diese Spielesitzung auf \"Original-Inhalte\" gesetzt, bis " -"Sie das Spiel komplett beenden." - -#: engines/bladerunner/bladerunner.cpp:2043 -msgid "Continue" -msgstr "Fortsetzen" - -#: engines/bladerunner/detection.cpp:48 -msgid "Sitcom mode" -msgstr "Sitcom-Modus" - -#: engines/bladerunner/detection.cpp:49 -msgid "Game will add laughter after actor's line or narration" -msgstr "" -"Das Spiel wird Gelächter am Ende eines Dialogs oder einer Erzählung " -"hinzufügen" - -#: engines/bladerunner/detection.cpp:57 -msgid "Shorty mode" -msgstr "Shorty-Modus" - -#: engines/bladerunner/detection.cpp:58 -msgid "Game will shrink the actors and make their voices high pitched" -msgstr "" -"Das Spiel wird die Akteure schrumpfen und ihre Stimmen höher klingen lassen" - -#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:111 -msgid "Color Blind Mode" -msgstr "Modus für Farbenblinde" - -#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:112 -msgid "Enable Color Blind Mode by default" -msgstr "Modus für Farbenblinde standardmäßig einschalten" - -#: engines/drascula/saveload.cpp:47 -msgid "" -"ScummVM found that you have old saved games for Drascula that should be " -"converted.\n" -"The old saved game format is no longer supported, so you will not be able to " -"load your games if you don't convert them.\n" -"\n" -"Press OK to convert them now, otherwise you will be asked again the next " -"time you start the game.\n" -msgstr "" -"ScummVM hat erkannt, dass Sie alte Spielstände von Drascula haben, die " -"umgewandelt werden sollten.\n" -"Das alte Speicherformat wird nicht mehr unterstützt, daher können Sie diese " -"Spielstände unkonvertiert nicht laden.\n" -"\n" -"Klicken Sie auf OK, um diese jetzt umzuwandeln, sonst werden Sie erneut " -"gefragt, wenn Sie nächstes Mal dieses Spiel starten.\n" - -#: engines/dreamweb/detection.cpp:58 -msgid "Use bright palette mode" -msgstr "Modus für helle Palette verwenden" - -#: engines/dreamweb/detection.cpp:59 -msgid "Display graphics using the game's bright palette" -msgstr "Zeigt Grafiken über helle Spielpalette an" - -#: engines/glk/glk_api.cpp:63 -msgid "[ press any key to exit ]" -msgstr "[ zum Beenden beliebige Taste drücken ]" - -#: engines/glk/quetzal.cpp:115 engines/glk/quetzal.cpp:124 -msgid "Untitled Savegame" -msgstr "Unbenannter Spielstand" - -#: engines/glk/advsys/advsys.cpp:35 -msgid "Could not start AdvSys game" -msgstr "AdvSys-Spiel konnte nicht gestartet werden" - -#: engines/glk/advsys/advsys.cpp:48 engines/glk/advsys/vm.cpp:319 -msgid "Sorry, the savegame couldn't be restored" -msgstr "" -"Entschuldigung, aber der Spielstand konnte nicht wiederhergestellt werden" - -#: engines/glk/advsys/vm.cpp:314 -msgid "Sorry, the savegame couldn't be created" -msgstr "Entschuldigung, aber der Spielstand konnte nicht erstellt werden" - -#: engines/glk/advsys/vm.cpp:560 -msgid "Speak up! I can't hear you!\n" -msgstr "Sprich lauter! Ich kann dich nicht hören!\n" - -#: engines/glk/advsys/vm.cpp:596 -#, c-format -msgid "I don't know the word \"%s\".\n" -msgstr "Ich kenne das Wort \"%s\" nicht.\n" - -#: engines/glk/advsys/vm.cpp:682 -msgid "I don't understand.\n" -msgstr "Ich verstehe nicht.\n" - -#: engines/glk/alan2/alan2.cpp:78 -msgid "This is too short to be a valid Alan2 file." -msgstr "Das ist zu kurz, um eine gültige Alan2-Datei zu sein." - -#: engines/glk/alan2/alan2.cpp:83 -msgid "This is not a valid Alan2 file." -msgstr "Dies ist keine gültige Alan2-Datei." - -#: engines/glk/frotz/frotz.cpp:126 -msgid "Error reading save file" -msgstr "Fehler beim Lesen der Spielstand-Datei" - -#: engines/glk/frotz/frotz.cpp:144 -msgid "Error writing save file\n" -msgstr "Fehler beim Schreiben der Spielstand-Datei\n" - -#: engines/glk/glulxe/glulxe.cpp:79 engines/glk/magnetic/magnetic.cpp:73 -msgid "This is too short to be a valid Glulx file." -msgstr "Das ist zu kurz, um eine gültige Glulx-Datei zu sein." - -#: engines/glk/glulxe/glulxe.cpp:84 engines/glk/magnetic/magnetic.cpp:78 -msgid "This is not a valid Glulx file." -msgstr "Dies ist keine gültige Glulx-Datei." - -#: engines/glk/glulxe/glulxe.cpp:91 engines/glk/magnetic/magnetic.cpp:85 -msgid "This Glulx file is too old a version to execute." -msgstr "Die Version dieser Glulx-Datei ist zu alt, um sie ausführen zu können." - -#: engines/glk/glulxe/glulxe.cpp:95 engines/glk/magnetic/magnetic.cpp:89 -msgid "This Glulx file is too new a version to execute." -msgstr "Diese Glulx-Datei ist zu neu, um Sie ausführen zu können." - -#: engines/glk/scott/scott.cpp:99 -msgid "I don't understand your command. " -msgstr "Ich verstehe Ihren Befehl nicht. " - -#: engines/glk/scott/scott.cpp:102 -msgid "I can't do that yet. " -msgstr "Ich kann das noch nicht tun. " - -#: engines/glk/scott/scott.cpp:118 -msgid "Light has run out! " -msgstr "Das Licht ist ausgegangen! " - -#: engines/glk/scott/scott.cpp:120 -msgid "Your light has run out. " -msgstr "Ihr Licht ist ausgegangen. " - -#: engines/glk/scott/scott.cpp:129 -msgid "Light runs out in " -msgstr "Licht geht aus in " - -#: engines/glk/scott/scott.cpp:131 -msgid " turns. " -msgstr " Runden. " - -#: engines/glk/scott/scott.cpp:134 -msgid "Your light is growing dim. " -msgstr "Ihr Licht wird schwächer. " - -#: engines/glk/scott/scott.cpp:394 -msgid "North" -msgstr "Norden" - -#: engines/glk/scott/scott.cpp:394 -msgid "South" -msgstr "Süden" - -#: engines/glk/scott/scott.cpp:394 -msgid "East" -msgstr "Osten" - -#: engines/glk/scott/scott.cpp:394 -msgid "West" -msgstr "Westen" - -#: engines/glk/scott/scott.cpp:406 -msgid "You can't see. It is too dark!\n" -msgstr "Sie können nichts sehen. Es ist zu dunkel!\n" - -#: engines/glk/scott/scott.cpp:408 -msgid "I can't see. It is too dark!\n" -msgstr "Ich kann nichts sehen. Es ist zu dunkel!\n" - -#: engines/glk/scott/scott.cpp:418 -#, c-format -msgid "You are in a %s\n" -msgstr "Sie sind in einem %s\n" - -#: engines/glk/scott/scott.cpp:420 -#, c-format -msgid "I'm in a %s\n" -msgstr "Ich bin in einem %s\n" - -#: engines/glk/scott/scott.cpp:425 -msgid "" -"\n" -"Obvious exits: " -msgstr "" -"\n" -"Ausgänge: " - -#: engines/glk/scott/scott.cpp:438 -msgid "none" -msgstr "keine" - -#: engines/glk/scott/scott.cpp:447 -msgid "" -"\n" -"You can also see: " -msgstr "" -"\n" -"Sie sehen auch: " - -#: engines/glk/scott/scott.cpp:450 -msgid "" -"\n" -"I can also see: " -msgstr "" -"\n" -"Ich sehe auch: " - -#: engines/glk/scott/scott.cpp:533 -msgid "Saved.\n" -msgstr "Gespeichert.\n" - -#: engines/glk/scott/scott.cpp:624 -msgid "You use word(s) I don't know! " -msgstr "Sie haben ein Wort verwendet, das ich nicht kenne! " - -#: engines/glk/scott/scott.cpp:752 engines/glk/scott/scott.cpp:1075 -#: engines/glk/scott/scott.cpp:1097 -msgid "You are carrying too much. " -msgstr "Sie tragen zu viel. " - -#: engines/glk/scott/scott.cpp:754 -msgid "I've too much to carry! " -msgstr "Ich habe zu viel zu tragen! " - -#: engines/glk/scott/scott.cpp:785 -msgid "You are dead.\n" -msgstr "Sie sind tot.\n" - -#: engines/glk/scott/scott.cpp:787 -msgid "I am dead.\n" -msgstr "Ich bin tot.\n" - -#: engines/glk/scott/scott.cpp:799 -msgid "The game is now over.\n" -msgstr "Das Spiel ist nun vorbei.\n" - -#: engines/glk/scott/scott.cpp:814 -msgid "You have stored " -msgstr "Du hast aufgenommen " - -#: engines/glk/scott/scott.cpp:816 -msgid "I've stored " -msgstr "Ich habe aufgenommen " - -#: engines/glk/scott/scott.cpp:818 -msgid " treasures. On a scale of 0 to 100, that rates " -msgstr " Schätze. Auf einer Skala von 0 bis 100 bringt das " - -#: engines/glk/scott/scott.cpp:822 -msgid "Well done.\n" -msgstr "Gut gemacht.\n" - -#: engines/glk/scott/scott.cpp:831 -msgid "You are carrying:\n" -msgstr "Sie tragen:\n" - -#: engines/glk/scott/scott.cpp:833 -msgid "I'm carrying:\n" -msgstr "Ich trage:\n" - -#: engines/glk/scott/scott.cpp:848 -msgid "Nothing" -msgstr "Nichts" - -#: engines/glk/scott/scott.cpp:977 -msgid "Give me a direction too." -msgstr "Gib mir auch eine Richtung." - -#: engines/glk/scott/scott.cpp:986 -msgid "Dangerous to move in the dark! " -msgstr "Es ist gefährlich, sich im Dunkeln zu bewegen! " - -#: engines/glk/scott/scott.cpp:994 -msgid "You fell down and broke your neck. " -msgstr "Sie sind gestürzt und haben sich das Genick gebrochen. " - -#: engines/glk/scott/scott.cpp:996 -msgid "I fell down and broke my neck. " -msgstr "Ich bin gestürzt und habe mir das Genick gebrochen. " - -#: engines/glk/scott/scott.cpp:1001 -msgid "You can't go in that direction. " -msgstr "Sie können nicht in diese Richtung gehen. " - -#: engines/glk/scott/scott.cpp:1003 -msgid "I can't go in that direction. " -msgstr "Ich kann nicht in diese Richtung gehen. " - -#: engines/glk/scott/scott.cpp:1061 -msgid "It is dark.\n" -msgstr "Es ist dunkel.\n" - -#: engines/glk/scott/scott.cpp:1077 engines/glk/scott/scott.cpp:1099 -msgid "I've too much to carry. " -msgstr "Ich habe zu viel zu tragen. " - -#: engines/glk/scott/scott.cpp:1082 engines/glk/scott/scott.cpp:1130 -msgid ": O.K.\n" -msgstr ": O.K.\n" - -#: engines/glk/scott/scott.cpp:1088 -msgid "Nothing taken." -msgstr "Nichts mitgenommen." - -#: engines/glk/scott/scott.cpp:1092 engines/glk/scott/scott.cpp:1140 -msgid "What ? " -msgstr "Was ? " - -#: engines/glk/scott/scott.cpp:1105 -msgid "It is beyond your power to do that. " -msgstr "Es liegt nicht in Ihrer Macht, dies zu tun. " - -#: engines/glk/scott/scott.cpp:1107 -msgid "It's beyond my power to do that. " -msgstr "Es liegt nicht in meiner Macht, dies zu tun. " - -#: engines/glk/scott/scott.cpp:1111 -msgid "O.K. " -msgstr "O.K. " - -#: engines/glk/scott/scott.cpp:1136 -msgid "Nothing dropped.\n" -msgstr "Nichts fallengelassen.\n" - -#: engines/glk/scott/scott.cpp:1146 -msgid "It's beyond your power to do that.\n" -msgstr "Es übersteigt Ihre Kraft, dies zu tun.\n" - -#: engines/glk/scott/scott.cpp:1148 -msgid "It's beyond my power to do that.\n" -msgstr "Es übersteigt meine Kraft, dies zu tun.\n" - -#: engines/gob/inter_playtoons.cpp:255 engines/gob/inter_v2.cpp:1467 -#: engines/gob/inter_geisha.cpp:232 engines/tinsel/saveload.cpp:538 -msgid "Failed to load saved game from file." -msgstr "Konnte Spielstand aus Datei nicht laden." - -#: engines/gob/inter_v2.cpp:1537 engines/gob/inter_geisha.cpp:263 -#: engines/tinsel/saveload.cpp:551 -msgid "Failed to save game to file." -msgstr "Konnte Spielstand nicht in Datei speichern." - -#: engines/gob/inter_v5.cpp:107 -msgid "Failed to delete file." -msgstr "Konnte Datei nicht löschen." - -#: engines/groovie/detection.cpp:323 -msgid "Fast movie speed" -msgstr "Schnelles Film-Tempo" - -#: engines/groovie/detection.cpp:324 -msgid "Play movies at an increased speed" -msgstr "Spielt Filme mit erhöhter Geschwindigkeit ab" - -#: engines/groovie/script.cpp:430 -msgid "Failed to save game" -msgstr "Konnte Spielstand nicht speichern" - -#: engines/hopkins/detection.cpp:76 engines/hopkins/detection.cpp:86 -msgid "Gore Mode" -msgstr "Blutmodus" - -#: engines/hopkins/detection.cpp:77 engines/hopkins/detection.cpp:87 -msgid "Enable Gore Mode when available" -msgstr "Blutmodus aktivieren, wenn verfügbar" - -#. I18N: Studio audience adds an applause and cheering sounds whenever -#. Malcolm makes a joke. -#: engines/kyra/detection.cpp:62 -msgid "Studio audience" -msgstr "Studio-Publikum" - -#: engines/kyra/detection.cpp:63 -msgid "Enable studio audience" -msgstr "Aktiviert Studio-Publikum" - -#. I18N: This option allows the user to skip text and cutscenes. -#: engines/kyra/detection.cpp:73 -msgid "Skip support" -msgstr "Erlaube Überspringen" - -#: engines/kyra/detection.cpp:74 -msgid "Allow text and cutscenes to be skipped" -msgstr "Erlaubt das Überspringen von Textteilen und Zwischensequenzen" - -#. I18N: Helium mode makes people sound like they've inhaled Helium. -#: engines/kyra/detection.cpp:84 -msgid "Helium mode" -msgstr "Helium-Modus" - -#: engines/kyra/detection.cpp:85 -msgid "Enable helium mode" -msgstr "Aktiviert Helium-Modus" - -#. I18N: When enabled, this option makes scrolling smoother when -#. changing from one screen to another. -#: engines/kyra/detection.cpp:99 -msgid "Smooth scrolling" -msgstr "Gleichmäßiges Scrollen" - -#: engines/kyra/detection.cpp:100 -msgid "Enable smooth scrolling when walking" -msgstr "Aktiviert gleichmäßiges Scrollen beim Gehen" - -#. I18N: When enabled, this option changes the cursor when it floats to the -#. edge of the screen to a directional arrow. The player can then click to -#. walk towards that direction. -#: engines/kyra/detection.cpp:112 -msgid "Floating cursors" -msgstr "Richtungspfeil-Mauszeiger" - -#: engines/kyra/detection.cpp:113 -msgid "Enable floating cursors" -msgstr "Aktiviert Richtungspfeil-Mauszeiger" - -#. I18N: HP stands for Hit Points -#: engines/kyra/detection.cpp:127 -msgid "HP bar graphs" -msgstr "Trefferpunkte-Balken" - -#: engines/kyra/detection.cpp:128 -msgid "Enable hit point bar graphs" -msgstr "Aktiviert grafische Trefferpunkte-Balken" - -#. I18N: L/R stands for Left/Right -#: engines/kyra/detection.cpp:138 -msgid "Fight Button L/R Swap" -msgstr "Tastenbelegung (Links/Rechts) vertauschen" - -#: engines/kyra/detection.cpp:139 -msgid "Left button to attack, right button to pick up items" -msgstr "Linker Button um anzugreifen, rechter Button, um Items aufzuheben" - -#: engines/kyra/engine/eobcommon.cpp:352 engines/kyra/engine/lol.cpp:481 -msgid "Move Forward" -msgstr "Nach vorn bewegen" - -#: engines/kyra/engine/eobcommon.cpp:353 engines/kyra/engine/lol.cpp:482 -msgid "Move Back" -msgstr "Nach hinten bewegen" - -#: engines/kyra/engine/eobcommon.cpp:354 -msgid "Move Left" -msgstr "Nach links gehen" - -#: engines/kyra/engine/eobcommon.cpp:355 -msgid "Move Right" -msgstr "Nach rechts gehen" - -#: engines/kyra/engine/eobcommon.cpp:356 engines/kyra/engine/lol.cpp:485 -#: engines/pegasus/pegasus.cpp:2514 -msgid "Turn Left" -msgstr "Nach links drehen" - -#: engines/kyra/engine/eobcommon.cpp:357 engines/kyra/engine/lol.cpp:486 -#: engines/pegasus/pegasus.cpp:2515 -msgid "Turn Right" -msgstr "Nach rechts drehen" - -#: engines/kyra/engine/eobcommon.cpp:358 -msgid "Open/Close Inventory" -msgstr "Inventar öffnen/schließen" - -#: engines/kyra/engine/eobcommon.cpp:359 -msgid "Switch Inventory/Character screen" -msgstr "Zwischen Inventar/Figurenbildschirm wechseln" - -#: engines/kyra/engine/eobcommon.cpp:360 -msgid "Camp" -msgstr "Camp" - -#: engines/kyra/engine/eobcommon.cpp:361 -msgid "Cast Spell" -msgstr "Zauber anwenden" - -#: engines/kyra/engine/eobcommon.cpp:364 -msgid "Spell Level 1" -msgstr "Zauberspruch Stufe 1" - -#: engines/kyra/engine/eobcommon.cpp:365 -msgid "Spell Level 2" -msgstr "Zauberspruch Stufe 2" - -#: engines/kyra/engine/eobcommon.cpp:366 -msgid "Spell Level 3" -msgstr "Zauberspruch Stufe 3" - -#: engines/kyra/engine/eobcommon.cpp:367 -msgid "Spell Level 4" -msgstr "Zauberspruch Stufe 4" - -#: engines/kyra/engine/eobcommon.cpp:368 -msgid "Spell Level 5" -msgstr "Zauberspruch Stufe 5" - -#: engines/kyra/engine/eobcommon.cpp:377 -msgid "Spell Level 6" -msgstr "Zauberspruch Stufe 6" - -#: engines/kyra/engine/lol.cpp:478 -msgid "Attack 1" -msgstr "Attacke 1" - -#: engines/kyra/engine/lol.cpp:479 -msgid "Attack 2" -msgstr "Attacke 2" - -#: engines/kyra/engine/lol.cpp:480 -msgid "Attack 3" -msgstr "Attacke 3" - -#: engines/kyra/engine/lol.cpp:483 -msgid "Slide Left" -msgstr "Nach links rutschen" - -#: engines/kyra/engine/lol.cpp:484 -msgid "Slide Right" -msgstr "Nach rechts rutschen" - -#: engines/kyra/engine/lol.cpp:487 -msgid "Rest" -msgstr "Ausruhen" - -#: engines/kyra/engine/lol.cpp:488 -msgid "Options" -msgstr "Optionen" - -#: engines/kyra/engine/lol.cpp:489 -msgid "Choose Spell" -msgstr "Zauberspruch auswählen" - -#: engines/kyra/gui/saveload_eob.cpp:569 -#, c-format -msgid "" -"The following original saved game file has been found in your game path:\n" -"\n" -"%s %s\n" -"\n" -"Do you wish to use this saved game file with ScummVM?\n" -"\n" -msgstr "" -"Die folgende originale Spielstand-Datei wurde in Ihrem Spieleverzeichnis " -"gefunden:\n" -"\n" -"%s %s\n" -"\n" -"Möchten Sie diese Spielstand-Datei in ScummVM verwenden?\n" -"\n" - -#: engines/kyra/gui/saveload_eob.cpp:602 -#, c-format -msgid "" -"A saved game file was found in the specified slot %d. Overwrite?\n" -"\n" -msgstr "" -"Eine Spielstand-Datei wurde im gewählten Speicherplatz %d gefunden. " -"Überschreiben?\n" -"\n" - -#: engines/kyra/gui/saveload_eob.cpp:635 -#, c-format -msgid "" -"%d original saved games have been successfully imported into\n" -"ScummVM. If you want to manually import original saved game later you will\n" -"need to open the ScummVM debug console and use the command " -"'import_savefile'.\n" -"\n" -msgstr "" -"%d originale Spielstand-Dateien wurden erfolgreich in ScummVM\n" -"importiert. Wenn Sie weitere Spielstand-Dateien später manuell importieren " -"wollen,\n" -"müssen Sie die ScummVM-Entwicklerkonsole öffnen und den Befehl " -"\"import_savefile\" verwenden.\n" -"\n" - -#: engines/kyra/graphics/screen_eob.cpp:2254 -msgid "" -"This AMIGA version requires the following font files:\n" -"\n" -"EOBF6.FONT\n" -"EOBF6/6\n" -"EOBF8.FONT\n" -"EOBF8/8\n" -"\n" -"If you used the orginal installer for the installation these files\n" -"should be located in the AmigaDOS system 'Fonts/' folder.\n" -"Please copy them into the EOB game data directory.\n" -msgstr "" -"Diese AMIGA-Version benötigt die folgenden Font-Dateien:\n" -"\n" -"EOBF6.FONT\n" -"EOBF6/6\n" -"EOBF8.FONT\n" -"EOBF8/8\n" -"\n" -"Wenn Sie das originale Installationsprogramm zur Installation\n" -"verwendet haben, sollten sich diese Dateien im Ordner 'Fonts/'\n" -"Ihrer AmigaDOS-Installation befinden. Bitte kopieren Sie diese\n" -"Dateien in das Spieldaten-Verzeichnis von EOB.\n" - -#: engines/kyra/graphics/screen_eob.cpp:2262 -msgid "" -"This AMIGA version requires the following font files:\n" -"\n" -"EOBF6.FONT\n" -"EOBF6/6\n" -"EOBF8.FONT\n" -"EOBF8/8\n" -"\n" -"This is a localized (non-English) version of EOB II which uses language " -"specific characters\n" -"contained only in the specific font files that came with your game. You " -"cannot use the font\n" -"files from the English version or from any EOB I game which seems to be what " -"you are doing.\n" -"\n" -"The game will continue, but the language specific characters will not be " -"displayed.\n" -"Please copy the correct font files into your EOB II game data directory.\n" -"\n" -msgstr "" -"Diese AMIGA-Version benötigt die folgenden Font-Dateien:\n" -"\n" -"EOBF6.FONT\n" -"EOBF6/6\n" -"EOBF8.FONT\n" -"EOBF8/8\n" -"\n" -"Dies ist eine lokalisierte (nicht-englische) Version von EOB II, die " -"sprachspezifische Zeichen\n" -"verwendet, die in speziellen Font-Dateien zusammen mit Ihrem Spiel " -"ausgeliefert wurden.\n" -"Sie können die Font-Dateien der englischen Version oder eines EOB I-Spiels " -"nicht verwenden.\n" -"\n" -"Das Spiel wird fortgesetzt, aber die sprachspezifischen Zeichen werden nicht " -"dargestellt.\n" -"Bitte kopieren Sie die korrenten Font-Dateien in Ihr EOB II-" -"Spielverzeichnis.\n" -"\n" - -#: engines/kyra/sound/sound_midi.cpp:72 -msgid "" -"You appear to be using a General MIDI device,\n" -"but your game only supports Roland MT32 MIDI.\n" -"We try to map the Roland MT32 instruments to\n" -"General MIDI ones. It is still possible that\n" -"some tracks sound incorrect." -msgstr "" -"Sie scheinen ein General MIDI-Gerät zu\n" -"verwenden, aber das Spiel unterstützt nur\n" -"Roland MT32 MIDI. Es wird versucht, die\n" -"Roland MT32-Instrumente denen von\n" -"General MIDI zuzuordnen. Es ist dennoch\n" -"möglich, dass ein paar Musikstücke nicht\n" -"richtig abgespielt werden." - -#: engines/mads/detection.cpp:91 -msgid "Easy mouse interface" -msgstr "Vereinfachte Maussteuerung" - -#: engines/mads/detection.cpp:92 -msgid "Shows object names when hovering the mouse over them" -msgstr "Zeigt Objektnamen an, wenn die Maus darüber bewegt wird" - -#: engines/mads/detection.cpp:101 engines/mads/detection.cpp:102 -msgid "Animated inventory items" -msgstr "Animierte Inventargegenstände" - -#: engines/mads/detection.cpp:111 engines/mads/detection.cpp:112 -msgid "Animated game interface" -msgstr "Animierte Spieloberfläche" - -#: engines/mads/detection.cpp:121 engines/mads/detection.cpp:122 -msgid "Naughty game mode" -msgstr "Unanständiger Spielmodus" - -#: engines/mohawk/detection.cpp:180 -msgid "Play the Myst fly by movie" -msgstr "Video vom Anflug auf Myst abspielen" - -#: engines/mohawk/detection.cpp:181 -msgid "The Myst fly by movie was not played by the original engine." -msgstr "" -"Das Video, welches den Anflug auf Myst zeigt, wurde in der ursprünglichen " -"Engine nicht abgespielt." - -#. I18N: Option for fast scene switching -#: engines/mohawk/dialogs.cpp:145 engines/mohawk/dialogs.cpp:285 -msgid "~Z~ip Mode Activated" -msgstr "~Z~ip-Modus aktiviert" - -#: engines/mohawk/dialogs.cpp:146 -msgid "~T~ransitions Enabled" -msgstr "Über~g~änge aktiviert" - -#. I18N: Drop book page -#: engines/mohawk/dialogs.cpp:148 -msgid "~D~rop Page" -msgstr "Seite ~a~blegen" - -#: engines/mohawk/dialogs.cpp:152 -msgid "Show ~M~ap" -msgstr "~K~arte anzeigen" - -#: engines/mohawk/dialogs.cpp:158 -msgid "Main Men~u~" -msgstr "Haupt~m~enü" - -#: engines/mohawk/dialogs.cpp:286 -msgid "~W~ater Effect Enabled" -msgstr "~W~assereffekt aktiviert" - -#: engines/mohawk/dialogs.cpp:288 -msgid "Transitions:" -msgstr "Übergänge:" - -#: engines/mohawk/dialogs.cpp:290 -msgid "Disabled" -msgstr "Ausgeschaltet" - -#: engines/mohawk/dialogs.cpp:291 -msgid "Fastest" -msgstr "Schnellste" - -#: engines/mohawk/dialogs.cpp:292 -msgid "Normal" -msgstr "Normal" - -#: engines/mohawk/dialogs.cpp:293 -msgid "Best" -msgstr "Beste" - -#: engines/mohawk/mohawk.cpp:55 -msgid "The game is paused. Press any key to continue." -msgstr "Das Spiel ist pausiert. Zum Weiterspielen beliebige Taste drücken." - -#: engines/mohawk/myst_stacks/menu.cpp:283 -#: engines/mohawk/riven_stacks/aspit.cpp:349 -msgid "" -"Are you sure you want to load a saved game? All unsaved progress will be " -"lost." -msgstr "" -"Sind Sie sicher, dass Sie ein gespeichertes Spiel laden möchten? Jeder nicht " -"gespeicherte Fortschritt geht dabei verloren." - -#: engines/mohawk/myst_stacks/menu.cpp:284 -#: engines/mohawk/riven_stacks/aspit.cpp:350 -msgid "Load game" -msgstr "Spiel laden" - -#: engines/mohawk/myst_stacks/menu.cpp:300 -#: engines/mohawk/riven_stacks/aspit.cpp:371 -msgid "" -"Are you sure you want to start a new game? All unsaved progress will be lost." -msgstr "" -"Sind Sie sicher, dass Sie ein neues Spiel starten möchten? Jeder nicht " -"gespeicherte Fortschritt geht dabei verloren." - -#: engines/mohawk/myst_stacks/menu.cpp:301 -#: engines/mohawk/riven_stacks/aspit.cpp:372 -msgid "New game" -msgstr "Neues Spiel" - -#: engines/mohawk/myst_stacks/menu.cpp:318 -#: engines/mohawk/riven_stacks/aspit.cpp:455 -msgid "Are you sure you want to quit? All unsaved progress will be lost." -msgstr "" -"Möchten Sie das Spiel wirklich beenden? Jeder nicht gespeicherte Fortschritt " -"geht dabei verloren." - -#: engines/mohawk/riven.cpp:158 -msgid "" -"You're missing a Riven executable. The Windows executable is 'riven.exe' or " -"'rivendmo.exe'. " -msgstr "" -"Ihnen fehlt eine Programmdatei von Riven. Die Windows-Programmdatei ist " -"'riven.exe' oder 'rivendmo.exe'. " - -#: engines/mohawk/riven.cpp:159 -msgid "" -"Using the 'arcriven.z' installer file also works. In addition, you can use " -"the Mac 'Riven' executable." -msgstr "" -"Die Installationsdatei 'arcriven.z' kann ebenfalls verwendet werden. " -"Zusätzlich können Sie auch die Mac-Programmdatei 'Riven' verwenden." - -#: engines/mohawk/riven.cpp:170 -msgid "" -"You're missing 'extras.mhk'. Using the 'arcriven.z' installer file also " -"works." -msgstr "" -"Die Datei 'extras.mhk' fehlt. Sie können auch die Installationsdatei " -"'arcriven.z verwenden." - -#: engines/mohawk/riven.cpp:515 -msgid "You are missing the following required Riven data files:\n" -msgstr "Ihnen fehlen die folgenden Spieldateien für Riven:\n" - -#: engines/mohawk/riven_stack.cpp:204 -msgid "" -"Exploration beyond this point available only within the full version of\n" -"the game." -msgstr "" -"Die weitere Erkundung über diesen Punkt hinaus ist nur in der Vollversion\n" -"des Spiels möglich." - -#: engines/mohawk/riven_stacks/aspit.cpp:429 -msgid "" -"At this point, the Riven Demo would\n" -"ask if you would like to open a web browser\n" -"to bring you to the Red Orb store to buy\n" -"the game. ScummVM cannot do that and\n" -"the site no longer exists." -msgstr "" -"An dieser Stelle würde die Riven-Demo\n" -"Sie fragen, ob Sie einen Web-Browser\n" -"öffnen möchten, um das Spiel direkt von\n" -"Red Orb zu kaufen. ScummVM kann dies nicht.\n" -"Die Webseite existiert nicht mehr." - -#: engines/neverhood/detection.cpp:184 -msgid "Skip the Hall of Records storyboard scenes" -msgstr "Szenenbuch-Sequenz in der Chronikhalle überspringen" - -#: engines/neverhood/detection.cpp:185 -msgid "Allows the player to skip past the Hall of Records storyboard scenes" -msgstr "" -"Ermöglicht dem Spieler, die Szenenbuch-Sequenz in der Chronikhalle zu " -"überspringen" - -#: engines/neverhood/detection.cpp:191 -msgid "Scale the making of videos to full screen" -msgstr "Making-Of-Videos auf Vollbild skalieren" - -#: engines/neverhood/detection.cpp:192 -msgid "Scale the making of videos, so that they use the whole screen" -msgstr "" -"Skaliert die Making-Of-Videos, sodass sie den gesamten Bildschirm ausfüllen" - -#: engines/parallaction/saveload.cpp:130 -#, c-format -msgid "" -"Can't save game in slot %i\n" -"\n" -msgstr "" -"Kann Spiel nicht auf Speicherplatz %i speichern\n" -"\n" - -#: engines/parallaction/saveload.cpp:194 -msgid "Load file" -msgstr "Datei laden" - -#: engines/parallaction/saveload.cpp:201 -msgid "Loading game..." -msgstr "Spiel wird geladen..." - -#: engines/parallaction/saveload.cpp:209 -msgid "Save file" -msgstr "Datei speichern" - -#: engines/parallaction/saveload.cpp:216 -msgid "Saving game..." -msgstr "Spiel wird gespeichert..." - -#: engines/parallaction/saveload.cpp:269 -msgid "" -"ScummVM found that you have old saved games for Nippon Safes that should be " -"renamed.\n" -"The old names are no longer supported, so you will not be able to load your " -"games if you don't convert them.\n" -"\n" -"Press OK to convert them now, otherwise you will be asked next time.\n" -msgstr "" -"ScummVM hat erkannt, dass Sie alte Spielstände von Nippon Safes haben, die " -"umbenannt werden sollten.\n" -"Die alten Dateinamen werden nicht mehr unterstützt, daher können Sie diese " -"Spielstände unkonvertiert nicht laden.\n" -"\n" -"Klicken Sie auf OK, um diese jetzt umzuwandeln, sonst werden Sie erneut " -"gefragt, wenn Sie nächstes Mal dieses Spiel starten.\n" - -#: engines/parallaction/saveload.cpp:316 -msgid "ScummVM successfully converted all your saved games." -msgstr "ScummVM hat alle Speicherstände erfolgreich umgewandelt." - -#: engines/parallaction/saveload.cpp:318 -msgid "" -"ScummVM printed some warnings in your console window and can't guarantee all " -"your files have been converted.\n" -"\n" -"Please report to the team." -msgstr "" -"ScummVM hat ein paar Warnungen im Konsolenfenster ausgegeben und kann nicht " -"gewährleisten, dass alle Speicherstände umgewandelt wurden.\n" -"\n" -"Bitte berichten Sie dies dem Team auf Englisch." - -#: engines/pegasus/pegasus.cpp:716 -msgid "Invalid file name for saving" -msgstr "Dateiname zum Speichern eingeben" - -#: engines/pegasus/pegasus.cpp:2512 -msgid "Up/Zoom In/Move Forward/Open Doors" -msgstr "Hoch/Hineinzoomen/Nach vorn/Türen öffnen" - -#: engines/pegasus/pegasus.cpp:2513 -msgid "Down/Zoom Out" -msgstr "Runter/Hinauszoomen" - -#: engines/pegasus/pegasus.cpp:2516 -msgid "Display/Hide Inventory Tray" -msgstr "Inventarleiste anzeigen/verbergen" - -#: engines/pegasus/pegasus.cpp:2517 -msgid "Display/Hide Biochip Tray" -msgstr "Biochip-Leiste anzeigen/verbergen" - -#: engines/pegasus/pegasus.cpp:2518 -msgid "Action/Select" -msgstr "Aktion/Auswählen" - -#: engines/pegasus/pegasus.cpp:2519 -msgid "Toggle Center Data Display" -msgstr "Mittige Datenanzeige wechseln" - -#: engines/pegasus/pegasus.cpp:2520 -msgid "Display/Hide Info Screen" -msgstr "Info-Bildschirm anzeigen/verbergen" - -#: engines/pegasus/pegasus.cpp:2521 -msgid "Display/Hide Pause Menu" -msgstr "Pause-Menü anzeigen/verbergen" - -#: engines/queen/detection.cpp:56 -msgid "Alternative intro" -msgstr "Alternativer Vorspann" - -#: engines/queen/detection.cpp:57 -msgid "Use an alternative game intro (CD version only)" -msgstr "Verwendet einen alternativen Vorspann (nur bei CD-Version)" - -#: engines/sci/detection.cpp:396 -msgid "Skip EGA dithering pass (full color backgrounds)" -msgstr "Überspringe EGA-Fehlerdiffusion (Vollfarbige Hintergründe)" - -#: engines/sci/detection.cpp:397 -msgid "Skip dithering pass in EGA games, graphics are shown with full colors" -msgstr "" -"Überspringe Fehlerdiffusion in EGA-Spielen, Grafik wird mit allen Farben " -"gezeigt" - -#: engines/sci/detection.cpp:406 -msgid "Enable high resolution graphics" -msgstr "Aktiviere hochauflösende Grafik" - -#: engines/sci/detection.cpp:407 -msgid "Enable high resolution graphics/content" -msgstr "Aktiviere hochauflösende Grafik/Inhalte" - -#: engines/sci/detection.cpp:416 -msgid "Enable black-lined video" -msgstr "Aktiviere schwarze Linien in Videos" - -#: engines/sci/detection.cpp:417 -msgid "Draw black lines over videos to increase their apparent sharpness" -msgstr "" -"Zeichne schwarze Linien über Videos, um die scheinbare Schärfe zu erhöhen" - -#: engines/sci/detection.cpp:427 -msgid "Use high-quality video scaling" -msgstr "Qualitativ hochwertige Videoskalierung verwenden" - -#: engines/sci/detection.cpp:428 -msgid "Use linear interpolation when upscaling videos, where possible" -msgstr "Verwende bilineare Filterung zur Skalierung von Videos, sofern möglich" - -#: engines/sci/detection.cpp:438 -msgid "Use high-quality \"LarryScale\" cel scaling" -msgstr "Qualitativ hochwertiges \"LarryScale\" cel-scaling verwenden" - -#: engines/sci/detection.cpp:439 -msgid "Use special cartoon scaler for drawing character sprites" -msgstr "" -"Verwendet einen speziellen Cartoon-Scaler, um Character-Sprites darzustellen" - -#: engines/sci/detection.cpp:448 -msgid "Prefer digital sound effects" -msgstr "Digitale Geräusch-Effekte bevorzugen" - -#: engines/sci/detection.cpp:449 -msgid "Prefer digital sound effects instead of synthesized ones" -msgstr "Bevorzugt digitale Geräusch-Effekte statt synthetisierter" - -#: engines/sci/detection.cpp:468 -msgid "Use IMF/Yamaha FB-01 for MIDI output" -msgstr "IMF/Yamaha FB-01 für MIDI-Ausgabe verwenden" - -#: engines/sci/detection.cpp:469 -msgid "" -"Use an IBM Music Feature card or a Yamaha FB-01 FM synth module for MIDI " -"output" -msgstr "" -"Verwendet eine Music Feature-Karte von IBM oder ein Yamaha FB-01 FM-" -"Synthetisierungsmodul für die MIDI-Ausgabe" - -#: engines/sci/detection.cpp:479 -msgid "Use CD audio" -msgstr "CD-Ton verwenden" - -#: engines/sci/detection.cpp:480 -msgid "Use CD audio instead of in-game audio, if available" -msgstr "Verwendet CD-Ton anstatt des Tons im Spiel, sofern verfügbar" - -#: engines/sci/detection.cpp:490 -msgid "Use Windows cursors" -msgstr "Windows-Mauszeiger verwenden" - -#: engines/sci/detection.cpp:491 -msgid "" -"Use the Windows cursors (smaller and monochrome) instead of the DOS ones" -msgstr "" -"Verwendet die Windows-Mauszeiger (kleiner und schwarz-weiß) anstatt der von " -"DOS" - -#: engines/sci/detection.cpp:501 -msgid "Use silver cursors" -msgstr "Silberne Mauszeiger verwenden" - -#: engines/sci/detection.cpp:502 -msgid "" -"Use the alternate set of silver cursors instead of the normal golden ones" -msgstr "" -"Verwendet alternativen Satz silberner Mauszeiger anstatt der normalen " -"goldenen" - -#: engines/sci/detection.cpp:512 -msgid "Enable content censoring" -msgstr "Zensur aktivieren" - -#: engines/sci/detection.cpp:513 -msgid "Enable the game's built-in optional content censoring" -msgstr "Aktiviere die im Spiel eingebaute optionale Zensur des Inhalts" - -#: engines/sci/detection.cpp:523 -msgid "Upscale videos" -msgstr "Videos hochskalieren" - -#: engines/sci/detection.cpp:524 -msgid "Upscale videos to double their size" -msgstr "Videos auf das Doppelte ihrer Größe skalieren" - -#: engines/sci/detection.cpp:854 engines/sci/engine/kfile.cpp:481 -msgid "(Autosave)" -msgstr "(Automatisches Speichern)" - -#: engines/sci/engine/kgraphics.cpp:995 -msgid "" -"Characters saved inside ScummVM are shown automatically. Character files " -"saved in the original interpreter need to be put inside ScummVM's saved " -"games directory and a prefix needs to be added depending on which game it " -"was saved in: 'qfg1-' for Quest for Glory 1, 'qfg2-' for Quest for Glory 2. " -"Example: 'qfg2-thief.sav'." -msgstr "" -"Charaktere, die in ScummVM gespeichert wurden, werden automatisch angezeigt. " -"Charakter-Dateien, die im originalen Interpreter gespeichert wurden, müssen " -"in das Spielstand-Verzeichnis von ScummVM kopiert und mit einem Präfix " -"ergänzt werden, der davon abhängig ist, in welchem Spiel die Charaktere " -"erstellt wurden: 'qfg1-' für Quest for Glory 1, 'qfg2-' für Quest for Glory " -"2. Beispiel: 'qfg2-thief.sav'." - -#: engines/sci/engine/kgraphics32.cpp:348 -#, c-format -msgid "Please use an external viewer to open the game's help file: %s" -msgstr "" -"Bitte verwenden Sie einen externen Betrachter, um die Hilfedatei des Spiels " -"zu öffnen: %s" - -#: engines/sci/engine/savegame.cpp:1300 -msgid "The format of this saved game is obsolete, unable to load it" -msgstr "Das Format dieses Spielstands ist veraltet; laden nicht möglich" - -#: engines/sci/engine/savegame.cpp:1302 -#, c-format -msgid "Savegame version is %d, maximum supported is %0d" -msgstr "Spielstand-Version ist %d, höchste unterstützte Version ist %0d" - -#: engines/sci/engine/savegame.cpp:1313 -msgid "" -"This saved game was created with a different version of the game, unable to " -"load it" -msgstr "" -"Dieser Spielstand wurde mit einer anderen Version des Spiels erstellt; laden " -"nicht möglich" - -#: engines/sci/resource.cpp:827 -msgid "" -"Missing or corrupt game resources have been detected. Some game features may " -"not work properly. Please check the console for more information, and verify " -"that your game files are valid." -msgstr "" -"Fehlende oder defekte Spiel-Ressourcen wurden erkannt. Einige " -"Spielfunktionen funktionieren möglicherweise nicht korrekt. Bitte überprüfen " -"Sie die Konsole auf weitere Informationen und stellen Sie sicher, dass Ihre " -"Spieldateien korrekt sind." - -#: engines/sci/sci.cpp:385 -msgid "" -"Subtitles are enabled, but subtitling in King's Quest 7 was unfinished and " -"disabled in the release version of the game. ScummVM allows the subtitles to " -"be re-enabled, but because they were removed from the original game, they do " -"not always render properly or reflect the actual game speech. This is not a " -"ScummVM bug -- it is a problem with the game's assets." -msgstr "" -"Untertitel sind aktiviert, die Untertitel in King's Quest 7 wurden jedoch " -"nicht fertiggestellt und im veröffentlichten Spiel deaktiviert. ScummVM " -"erlaubt, dass die Untertitel trotzdem aktiviert werden. Da diese jedoch im " -"Originalspiel entfernt wurden, werden sie nicht immer korrekt dargestellt " -"oder weichen von der Sprachausgabe ab. Dies ist kein Fehler in ScummVM -- es " -"ist ein Problem mit den Spieldaten." - -#: engines/sci/sci.cpp:409 -msgid "" -"You have selected General MIDI as a sound device. Sierra has provided after-" -"market support for General MIDI for this game in their \"General MIDI Utility" -"\". Please, apply this patch in order to enjoy MIDI music with this game. " -"Once you have obtained it, you can unpack all of the included *.PAT files in " -"your ScummVM extras folder and ScummVM will add the appropriate patch " -"automatically. Alternatively, you can follow the instructions in the READ.ME " -"file included in the patch and rename the associated *.PAT file to 4.PAT and " -"place it in the game folder. Without this patch, General MIDI music for this " -"game will sound badly distorted." -msgstr "" -"Sie haben General MIDI als Audio-Gerät ausgewählt. Sierra bietet für dieses " -"Spiel Unterstützung von General MIDI über das \"General MIDI Utility\" an, " -"welches separat erhältlich war. Bitte installieren Sie diesen Patch, um MIDI-" -"Musik in diesem Spiel zu erleben. Nachdem Sie den Patch erhalten haben, " -"können Sie alle darin befindlichen *.PAT-Dateien in Ihr ScummVM Extra-" -"Verzeichnis entpacken. ScummVM wird den passenden Patch dann automatisch " -"auswählen. Alternativ können Sie die Anweisungen in der READ.ME-Datei " -"befolgen, die mit dem Patch mitgeliefert wird, und die zugehörige *.PAT-" -"Datei in 4.PAT umbenennen und im Spiele-Verzeichnis ablegen. Ohne diesen " -"Patch wird die General MIDI-Musik erheblich verzerrt sein." - -#: engines/sci/sci.cpp:428 -msgid "" -"Your game is patched with a fan made script patch. Such patches have been " -"reported to cause issues, as they modify game scripts extensively. The " -"issues that these patches fix do not occur in ScummVM, so you are advised to " -"remove this patch from your game folder in order to avoid having unexpected " -"errors and/or issues later on." -msgstr "" -"Ihr Spiel wurde mit einem von Fans erstellten Patch gepatcht. Solche Patches " -"sind dafür bekannt, Fehler zu verursachen, da sie die Spiel-Skripte " -"umfangreich verändern. Die Fehler, die durch solche Patches behoben werden " -"treten nicht in ScummVM auf, weshalb Sie diesen Patch aus Ihrem Spiel-" -"Verzeichnis entfernen sollten, um unerwartete Fehler und/oder Probleme zu " -"verhindern." - -#: engines/scumm/detection.cpp:1123 -msgid "" -"Your game version appears to be unknown. If this is *NOT* a fan-modified\n" -"version (in particular, not a fan-made translation), please, report the\n" -"following data to the ScummVM team along with the name of the game you " -"tried\n" -"to add and its version, language, etc.:\n" -msgstr "" -"Ihre Spiel-Version ist offenbar unbekannt. Wenn es sich *NICHT* um eine\n" -"von Fans modifizierte Version (z.B. eine Fan-Übersetzung) handelt, teilen\n" -"Sie bitte dem ScummVM-Team die folgenden Daten sowie den Namen des Spiels,\n" -"welches Sie hinzufügen wollten, dessen Version, Sprache usw. mit:\n" - -#: engines/scumm/detection.cpp:1141 -msgid "" -"The Lite version of Putt-Putt Saves the Zoo iOS is not supported to avoid " -"piracy.\n" -"The full version is available for purchase from the iTunes Store." -msgstr "" -"Die \"Lite\"-Version von \"Putt-Putt Saves the Zoo iOS\" wird nicht " -"unterstützt,\n" -"um Software-Piraterie zu verhindern. Die Vollversion ist im iTunes Store " -"erhältlich." - -#: engines/scumm/detection.cpp:1352 -msgid "Show Object Line" -msgstr "Objektzeile zeigen" - -#: engines/scumm/detection.cpp:1353 -msgid "Show the names of objects at the bottom of the screen" -msgstr "Objektnamen und Verben am unteren Bildrand anzeigen" - -#: engines/scumm/dialogs.cpp:172 -#, c-format -msgid "Insert Disk %c and Press Button to Continue." -msgstr "Bitte Disk %c einlegen und Taste drücken." - -#: engines/scumm/dialogs.cpp:173 -#, c-format -msgid "Unable to Find %s, (%c%d) Press Button." -msgstr "Kann %s (%c%d) nicht finden, bitte Taste drücken." - -#: engines/scumm/dialogs.cpp:174 -#, c-format -msgid "Error reading disk %c, (%c%d) Press Button." -msgstr "Fehler beim Lesen von Disk %c (%c%d), bitte Taste drücken." - -#: engines/scumm/dialogs.cpp:175 -msgid "Game Paused. Press SPACE to Continue." -msgstr "Spielpause. Zum Weiterspielen Leertaste drücken." - -#. I18N: You may specify 'Yes' symbol at the end of the line, like this: -#. "Moechten Sie wirklich neu starten? (J/N)J" -#. Will react to J as 'Yes' -#: engines/scumm/dialogs.cpp:179 -msgid "Are you sure you want to restart? (Y/N)Y" -msgstr "Möchten Sie wirklich neu starten? (J/N)J" - -#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment -#: engines/scumm/dialogs.cpp:181 -msgid "Are you sure you want to quit? (Y/N)Y" -msgstr "Möchten Sie wirklich beenden? (J/N)J" - -#: engines/scumm/dialogs.cpp:186 -msgid "Play" -msgstr "Spielen" - -#: engines/scumm/dialogs.cpp:190 -msgid "Insert save/load game disk" -msgstr "Legen Sie eine Spielstand-Diskette ein" - -#: engines/scumm/dialogs.cpp:191 -msgid "You must enter a name" -msgstr "Sie müssen eine Bezeichnung eingeben" - -#: engines/scumm/dialogs.cpp:192 -msgid "The game was NOT saved (disk full?)" -msgstr "Spiel wurde NICHT gespeichert (Datenträger voll?)" - -#: engines/scumm/dialogs.cpp:193 -msgid "The game was NOT loaded" -msgstr "Spiel wurde NICHT geladen" - -#: engines/scumm/dialogs.cpp:194 -#, c-format -msgid "Saving '%s'" -msgstr "Speichere \"%s\"" - -#: engines/scumm/dialogs.cpp:195 -#, c-format -msgid "Loading '%s'" -msgstr "Lade \"%s\"" - -#: engines/scumm/dialogs.cpp:196 -msgid "Name your SAVE game" -msgstr "Name für Spielstand eingeben" - -#: engines/scumm/dialogs.cpp:197 -msgid "Select a game to LOAD" -msgstr "Spielstand zum LADEN auswählen" - -#: engines/scumm/dialogs.cpp:198 -msgid "Game title)" -msgstr "Spieltitel)" - -#. I18N: Previous page button -#: engines/scumm/dialogs.cpp:284 -msgid "~P~revious" -msgstr "~Z~urück" - -#. I18N: Next page button -#: engines/scumm/dialogs.cpp:286 -msgid "~N~ext" -msgstr "~W~eiter" - -#: engines/scumm/dialogs.cpp:599 -msgid "Speech Only" -msgstr "Nur Sprache" - -#: engines/scumm/dialogs.cpp:600 -msgid "Speech and Subtitles" -msgstr "Sprachausgabe und Untertitel" - -#: engines/scumm/dialogs.cpp:601 -msgid "Subtitles Only" -msgstr "Nur Untertitel" - -#: engines/scumm/dialogs.cpp:609 -msgctxt "lowres" -msgid "Speech & Subs" -msgstr "Sprache & Text" - -#: engines/scumm/dialogs.cpp:655 -msgid "Select a Proficiency Level." -msgstr "Wähle einen Schwierigkeitsgrad." - -#: engines/scumm/dialogs.cpp:657 -msgid "Refer to your Loom(TM) manual for help." -msgstr "Für Hilfe schauen Sie ins Loom(TM)-Handbuch." - -#: engines/scumm/dialogs.cpp:661 -msgid "Practice" -msgstr "Anfänger" - -#: engines/scumm/dialogs.cpp:662 -msgid "Expert" -msgstr "Experte" - -#: engines/scumm/help.cpp:74 -msgid "Common keyboard commands:" -msgstr "Allgemeine Tastenbefehle:" - -#: engines/scumm/help.cpp:75 -msgid "Save / Load dialog" -msgstr "Menü zum Speichern/Laden" - -#: engines/scumm/help.cpp:77 -msgid "Skip line of text" -msgstr "Textzeile überspringen" - -#: engines/scumm/help.cpp:78 -msgid "Esc" -msgstr "Esc" - -#: engines/scumm/help.cpp:78 -msgid "Skip cutscene" -msgstr "Zwischensequenz überspringen" - -#: engines/scumm/help.cpp:79 -msgid "Space" -msgstr "Leertaste" - -#: engines/scumm/help.cpp:79 -msgid "Pause game" -msgstr "Spielpause" - -#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85 -#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97 -#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99 -#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101 -#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103 -msgid "Ctrl" -msgstr "Strg" - -#: engines/scumm/help.cpp:80 -msgid "Load saved game 1-10" -msgstr "Spielstand 1-10 laden" - -#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85 -#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101 -#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103 -msgid "Alt" -msgstr "Alt" - -#: engines/scumm/help.cpp:81 -msgid "Save game 1-10" -msgstr "Spielstand 1-10 speichern" - -#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90 -msgid "Enter" -msgstr "Enter" - -#: engines/scumm/help.cpp:88 -msgid "Music volume up / down" -msgstr "Musiklautstärke höher/niedriger" - -#: engines/scumm/help.cpp:89 -msgid "Text speed slower / faster" -msgstr "Texttempo langsamer/schneller" - -#: engines/scumm/help.cpp:90 -msgid "Simulate left mouse button" -msgstr "Linke Maustaste simulieren" - -#: engines/scumm/help.cpp:91 -msgid "Tab" -msgstr "Tabulator" - -#: engines/scumm/help.cpp:91 -msgid "Simulate right mouse button" -msgstr "Rechte Maustaste simulieren" - -#: engines/scumm/help.cpp:94 -msgid "Special keyboard commands:" -msgstr "Spezielle Tastenbefehle:" - -#: engines/scumm/help.cpp:95 -msgid "Show / Hide console" -msgstr "Konsole zeigen/verbergen" - -#: engines/scumm/help.cpp:96 -msgid "Start the debugger" -msgstr "Debugger starten" - -#: engines/scumm/help.cpp:97 -msgid "Show memory consumption" -msgstr "Speicherverbrauch anzeigen" - -#: engines/scumm/help.cpp:98 -msgid "Run in fast mode (*)" -msgstr "Schneller Modus (*)" - -#: engines/scumm/help.cpp:99 -msgid "Run in really fast mode (*)" -msgstr "Sehr schneller Modus (*)" - -#: engines/scumm/help.cpp:100 -msgid "Toggle mouse capture" -msgstr "Mauseingrenzung in Fenster EIN/AUS" - -#: engines/scumm/help.cpp:101 -msgid "Switch between graphics filters" -msgstr "Zwischen Grafikfiltern wechseln" - -#: engines/scumm/help.cpp:102 -msgid "Increase / Decrease scale factor" -msgstr "Größenverhältnis höher/niedriger" - -#: engines/scumm/help.cpp:103 -msgid "Toggle aspect-ratio correction" -msgstr "Seitenverhältnis anpassen: EIN/AUS" - -#: engines/scumm/help.cpp:108 -msgid "* Note that using ctrl-f and" -msgstr "* Es wird davon abgeraten," - -#: engines/scumm/help.cpp:109 -msgid " ctrl-g are not recommended" -msgstr " Strg+F und Strg+G zu verwenden," - -#: engines/scumm/help.cpp:110 -msgid " since they may cause crashes" -msgstr " da dies Abstürze oder fehlerhaftes" - -#: engines/scumm/help.cpp:111 -msgid " or incorrect game behavior." -msgstr " Spielverhalten verursachen kann." - -#: engines/scumm/help.cpp:115 -msgid "Spinning drafts on the keyboard:" -msgstr "Sprüche mit Tastatur spinnen:" - -#: engines/scumm/help.cpp:117 -msgid "Main game controls:" -msgstr "Hauptspielsteuerung:" - -#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137 -#: engines/scumm/help.cpp:162 -msgid "Push" -msgstr "Drücke" - -#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138 -#: engines/scumm/help.cpp:163 -msgid "Pull" -msgstr "Ziehe" - -#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139 -#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198 -#: engines/scumm/help.cpp:208 -msgid "Give" -msgstr "Gib" - -#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140 -#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191 -#: engines/scumm/help.cpp:209 -msgid "Open" -msgstr "Öffne" - -#: engines/scumm/help.cpp:127 -msgid "Go to" -msgstr "Gehe zu" - -#: engines/scumm/help.cpp:128 -msgid "Get" -msgstr "Nimm" - -#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153 -#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199 -#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225 -#: engines/scumm/help.cpp:251 -msgid "Use" -msgstr "Benutze" - -#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142 -msgid "Read" -msgstr "Lies" - -#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148 -msgid "New kid" -msgstr "Person" - -#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154 -#: engines/scumm/help.cpp:172 -msgid "Turn on" -msgstr "Schalt ein" - -#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155 -#: engines/scumm/help.cpp:173 -msgid "Turn off" -msgstr "Schalt aus" - -#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168 -#: engines/scumm/help.cpp:195 -msgid "Walk to" -msgstr "Gehe zu" - -#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169 -#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211 -#: engines/scumm/help.cpp:228 -msgid "Pick up" -msgstr "Nimm" - -#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170 -msgid "What is" -msgstr "Was ist" - -#: engines/scumm/help.cpp:147 -msgid "Unlock" -msgstr "Schließ auf" - -#: engines/scumm/help.cpp:150 -msgid "Put on" -msgstr "Zieh an" - -#: engines/scumm/help.cpp:151 -msgid "Take off" -msgstr "Nimm ab" - -#: engines/scumm/help.cpp:157 -msgid "Fix" -msgstr "Reparier" - -#: engines/scumm/help.cpp:159 -msgid "Switch" -msgstr "Wechsle" - -#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229 -msgid "Look" -msgstr "Schau" - -#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224 -msgid "Talk" -msgstr "Rede" - -#: engines/scumm/help.cpp:175 -msgid "Travel" -msgstr "Reise" - -#: engines/scumm/help.cpp:176 -msgid "To Henry / To Indy" -msgstr "Zu Henry/Zu Indy" - -#. I18N: These are different musical notes -#: engines/scumm/help.cpp:180 -msgid "play C minor on distaff" -msgstr "spiele tiefes C auf Stab" - -#: engines/scumm/help.cpp:181 -msgid "play D on distaff" -msgstr "spiele D auf Stab" - -#: engines/scumm/help.cpp:182 -msgid "play E on distaff" -msgstr "spiele E auf Stab" - -#: engines/scumm/help.cpp:183 -msgid "play F on distaff" -msgstr "spiele F auf Stab" - -#: engines/scumm/help.cpp:184 -msgid "play G on distaff" -msgstr "spiele G auf Stab" - -#: engines/scumm/help.cpp:185 -msgid "play A on distaff" -msgstr "spiele A auf Stab" - -#: engines/scumm/help.cpp:186 -msgid "play B on distaff" -msgstr "spiele H auf Stab" - -#: engines/scumm/help.cpp:187 -msgid "play C major on distaff" -msgstr "spiele hohes C auf Stab" - -#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215 -msgid "puSh" -msgstr "Drücke" - -#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216 -msgid "pull (Yank)" -msgstr "Ziehe" - -#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213 -#: engines/scumm/help.cpp:249 -msgid "Talk to" -msgstr "Rede mit" - -#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212 -msgid "Look at" -msgstr "Schau an" - -#: engines/scumm/help.cpp:201 -msgid "turn oN" -msgstr "Mach an" - -#: engines/scumm/help.cpp:202 -msgid "turn oFf" -msgstr "Mach aus" - -#: engines/scumm/help.cpp:218 -msgid "KeyUp" -msgstr "Hoch-Taste" - -#: engines/scumm/help.cpp:218 -msgid "Highlight prev dialogue" -msgstr "Vorige Dialogwahl markieren" - -#: engines/scumm/help.cpp:219 -msgid "KeyDown" -msgstr "Runter-Taste" - -#: engines/scumm/help.cpp:219 -msgid "Highlight next dialogue" -msgstr "Nächste Dialogwahl markieren" - -#: engines/scumm/help.cpp:223 -msgid "Walk" -msgstr "Gehe" - -#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235 -#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250 -msgid "Inventory" -msgstr "Inventar" - -#: engines/scumm/help.cpp:227 -msgid "Object" -msgstr "Objekt" - -#: engines/scumm/help.cpp:230 -msgid "Black and White / Color" -msgstr "Graustufen-Modus/Farbe" - -#: engines/scumm/help.cpp:233 -msgid "Eyes" -msgstr "Augen" - -#: engines/scumm/help.cpp:234 -msgid "Tongue" -msgstr "Zunge" - -#: engines/scumm/help.cpp:236 -msgid "Punch" -msgstr "Schlage" - -#: engines/scumm/help.cpp:237 -msgid "Kick" -msgstr "Tritt" - -#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248 -msgid "Examine" -msgstr "Betrachte" - -#: engines/scumm/help.cpp:241 -msgid "Regular cursor" -msgstr "Normaler Mauszeiger" - -#. I18N: Comm is a communication device -#: engines/scumm/help.cpp:244 -msgid "Comm" -msgstr "Kommunikation" - -#: engines/scumm/help.cpp:247 -msgid "Save / Load / Options" -msgstr "Speichern / Laden / Optionen" - -#: engines/scumm/help.cpp:256 -msgid "Other game controls:" -msgstr "Weitere Steuerung:" - -#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268 -msgid "Inventory:" -msgstr "Inventar:" - -#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275 -msgid "Scroll list up" -msgstr "Liste hochblättern" - -#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276 -msgid "Scroll list down" -msgstr "Liste runterblättern" - -#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269 -msgid "Upper left item" -msgstr "Oberer linker Gegenstand" - -#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271 -msgid "Lower left item" -msgstr "Unterer linker Gegenstand" - -#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272 -msgid "Upper right item" -msgstr "Oberer rechter Gegenstand" - -#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274 -msgid "Lower right item" -msgstr "Unterer rechter Gegenstand" - -#: engines/scumm/help.cpp:270 -msgid "Middle left item" -msgstr "Mittlerer linker Gegenstand" - -#: engines/scumm/help.cpp:273 -msgid "Middle right item" -msgstr "Mittlerer rechter Gegenstand" - -#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285 -msgid "Switching characters:" -msgstr "Figuren wechseln:" - -#: engines/scumm/help.cpp:282 -msgid "Second kid" -msgstr "Zweites Kind" - -#: engines/scumm/help.cpp:283 -msgid "Third kid" -msgstr "Drittes Kind" - -#: engines/scumm/help.cpp:292 -msgid "Toggle Inventory/IQ Points display" -msgstr "Inventar-/IQ-Punkt-Anzeige umschalten" - -#: engines/scumm/help.cpp:293 -msgid "Toggle Keyboard/Mouse Fighting (*)" -msgstr "Schalte zwischen Tastatur-/Maus-Kämpfen um (*)" - -#: engines/scumm/help.cpp:295 -msgid "* Keyboard Fighting is always on," -msgstr "* Tastatur-Steuerung der Kämpfe ist immer an," - -#: engines/scumm/help.cpp:296 -msgid " so despite the in-game message this" -msgstr " demnach wird trotz der Meldung im Spiel" - -#: engines/scumm/help.cpp:297 -msgid " actually toggles Mouse Fighting Off/On" -msgstr " die Maus-Steuerung der Kämpfe ein-/ausgeschaltet" - -#: engines/scumm/help.cpp:304 -msgid "Fighting controls (numpad):" -msgstr "Kampfsteuerung (Ziffernblock):" - -#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306 -#: engines/scumm/help.cpp:307 -msgid "Step back" -msgstr "Schritt zurück" - -#: engines/scumm/help.cpp:308 -msgid "Block high" -msgstr "Deckung oben" - -#: engines/scumm/help.cpp:309 -msgid "Block middle" -msgstr "Deckung Mitte" - -#: engines/scumm/help.cpp:310 -msgid "Block low" -msgstr "Deckung unten" - -#: engines/scumm/help.cpp:311 -msgid "Punch high" -msgstr "Schlag oben" - -#: engines/scumm/help.cpp:312 -msgid "Punch middle" -msgstr "Schlag Mitte" - -#: engines/scumm/help.cpp:313 -msgid "Punch low" -msgstr "Schlag unten" - -#: engines/scumm/help.cpp:315 -msgid "Sucker punch" -msgstr "Unerwarteter Schlag" - -#: engines/scumm/help.cpp:318 -msgid "These are for Indy on left." -msgstr "Dies gilt für Indy links." - -#: engines/scumm/help.cpp:319 -msgid "When Indy is on the right," -msgstr "Wenn Indy rechts steht," - -#: engines/scumm/help.cpp:320 -msgid "7, 4, and 1 are switched with" -msgstr "werden 7, 4 und 1 je mit" - -#: engines/scumm/help.cpp:321 -msgid "9, 6, and 3, respectively." -msgstr "9, 6 und 3 vertauscht." - -#: engines/scumm/help.cpp:328 -msgid "Biplane controls (numpad):" -msgstr "Doppeldecker (Ziffernblock):" - -#: engines/scumm/help.cpp:329 -msgid "Fly to upper left" -msgstr "Nach oben links fliegen" - -#: engines/scumm/help.cpp:330 -msgid "Fly to left" -msgstr "Nach links fliegen" - -#: engines/scumm/help.cpp:331 -msgid "Fly to lower left" -msgstr "Nach unten links fliegen" - -#: engines/scumm/help.cpp:332 -msgid "Fly upwards" -msgstr "Nach oben fliegen" - -#: engines/scumm/help.cpp:333 -msgid "Fly straight" -msgstr "Geradeaus fliegen" - -#: engines/scumm/help.cpp:334 -msgid "Fly down" -msgstr "Nach unten fliegen" - -#: engines/scumm/help.cpp:335 -msgid "Fly to upper right" -msgstr "Nach oben rechts fliegen" - -#: engines/scumm/help.cpp:336 -msgid "Fly to right" -msgstr "Nach rechts fliegen" - -#: engines/scumm/help.cpp:337 -msgid "Fly to lower right" -msgstr "Nach unten rechts fliegen" - -#: engines/scumm/input.cpp:578 -msgid "Snap scroll on" -msgstr "Blättern einschalten" - -#: engines/scumm/input.cpp:580 -msgid "Snap scroll off" -msgstr "Blättern ausschalten" - -#: engines/scumm/input.cpp:593 -msgid "Music volume: " -msgstr "Musiklautstärke: " - -#: engines/scumm/input.cpp:610 -msgid "Subtitle speed: " -msgstr "Untertitel-Tempo: " - -#: engines/scumm/scumm.cpp:1883 -#, c-format -msgid "" -"Native MIDI support requires the Roland Upgrade from LucasArts,\n" -"but %s is missing. Using AdLib instead." -msgstr "" -"Systemeigene MIDI-Ünterstützung erfordert das\n" -"Roland-Upgrade von LucasArts, aber %s\n" -"fehlt. Stattdessen wird AdLib verwendet." - -#: engines/scumm/scumm.cpp:2742 -msgid "" -"Usually, Maniac Mansion would start now. But for that to work, the game " -"files for Maniac Mansion have to be in the 'Maniac' directory inside the " -"Tentacle game directory, and the game has to be added to ScummVM." -msgstr "" -"Normalerweise würde jetzt Maniac Mansion starten. ScummVM kann das jedoch " -"noch nicht. Um dieses Spiel zu spielen, klicken Sie auf \"Spiel hinzufügen\" " -"im Startmenü von ScummVM und wählen das Verzeichnis \"Maniac\" im " -"Verzeichnis dieses Spiels aus." - -#: engines/scumm/players/player_v3m.cpp:129 -msgid "" -"Could not find the 'Loom' Macintosh executable to read the\n" -"instruments from. Music will be disabled." -msgstr "" -"Macintosh-Programmdatei für Instrumente in \"Loom\" nicht\n" -"gefunden. Musik wird abgeschaltet." - -#: engines/scumm/players/player_v5m.cpp:107 -msgid "" -"Could not find the 'Monkey Island' Macintosh executable to read the\n" -"instruments from. Music will be disabled." -msgstr "" -"Macintosh-Programmdatei für Instrumente in \"Monkey Island\" nicht\n" -"gefunden. Musik wird abgeschaltet." - -#: engines/sherlock/detection.cpp:81 -msgid "Pixellated scene transitions" -msgstr "Verpixelte Szenenübergänge" - -#: engines/sherlock/detection.cpp:82 -msgid "When changing scenes, a randomized pixel transition is done" -msgstr "Bei Szenenwechseln wird ein zufälliger Pixelübergang verwendet" - -#: engines/sherlock/detection.cpp:91 -msgid "Don't show hotspots when moving mouse" -msgstr "Bei Mausbewegung keine Hotspots anzeigen" - -#: engines/sherlock/detection.cpp:92 -msgid "" -"Only show hotspot names after you actually click on a hotspot or action " -"button" -msgstr "" -"Zeigt Hotspot-Namen nur nach Klick auf selbigen oder auf einen Aktionspunkt" - -#: engines/sherlock/detection.cpp:101 -msgid "Show character portraits" -msgstr "Figurenportraits zeigen" - -#: engines/sherlock/detection.cpp:102 -msgid "Show portraits for the characters when conversing" -msgstr "Zeigt Portraits der Figuren bei Gesprächen" - -#: engines/sherlock/detection.cpp:111 -msgid "Slide dialogs into view" -msgstr "Menüs in Blickfeld gleiten lassen" - -#: engines/sherlock/detection.cpp:112 -msgid "Slide UI dialogs into view, rather than simply showing them immediately" -msgstr "Lässt Menüs in Blickfeld gleiten anstatt sie einfach sofort anzuzeigen" - -#: engines/sherlock/detection.cpp:121 -msgid "Transparent windows" -msgstr "Transparente Fenster" - -#: engines/sherlock/detection.cpp:122 -msgid "Show windows with a partially transparent background" -msgstr "Zeigt Fenster mit teilweise transparentem Hintergrund" - -#: engines/sky/compact.cpp:141 -msgid "The \"sky.cpt\" engine data file has an incorrect size." -msgstr "Die Engine-Datendatei \"sky.cpt\" hat eine falsche Größe." - -#: engines/sky/detection.cpp:44 -msgid "Floppy intro" -msgstr "Vorspann der Diskettenversion" - -#: engines/sky/detection.cpp:45 -msgid "Use the floppy version's intro (CD version only)" -msgstr "Verwendet den Vorspann der Diskettenversion (nur bei CD-Version)" - -#: engines/supernova/supernova.cpp:194 -#, c-format -msgid "" -"Incorrect version of the '%s' engine data file found. Expected %d but got %d." -msgstr "" -"Falsche Version der Engine-Datendatei '%s' gefunden. %d erwartet, aber %d " -"bekommen." - -#: engines/supernova/supernova.cpp:220 -#, c-format -msgid "Unable to locate the text for %s language in '%s' engine data file." -msgstr "" -"Der Text für die Sprache %s konnte nicht in der Engine-Datendatei '%s' " -"gefunden werden." - -#: engines/supernova/supernova.cpp:441 -#, c-format -msgid "Unable to find '%s' in game folder." -msgstr "'%s' konnte im Spiel-Ordner nicht gefunden werden." - -#: engines/sword1/animation.cpp:524 -#, c-format -msgid "PSX stream cutscene '%s' cannot be played in paletted mode" -msgstr "" -"PSX-Zwischensequenz \"%s\" kann in Palettenmodus nicht wiedergegeben werden" - -#: engines/sword1/animation.cpp:545 engines/sword2/animation.cpp:445 -msgid "DXA cutscenes found but ScummVM has been built without zlib" -msgstr "" -"DXA-Zwischensequenzen gefunden, aber ScummVM wurde ohne Zlib-Unterstützung " -"erstellt" - -#: engines/sword1/animation.cpp:561 engines/sword2/animation.cpp:461 -msgid "" -"MPEG-2 cutscenes found but ScummVM has been built without MPEG-2 support" -msgstr "" -"MPEG-2-Zwischensequenzen gefunden, aber ScummVM wurde ohne Unterstützung für " -"MPEG-2-Videos erstellt" - -#: engines/sword1/animation.cpp:568 engines/sword2/animation.cpp:470 -#, c-format -msgid "Cutscene '%s' not found" -msgstr "Zwischensequenz \"%s\" nicht gefunden" - -#: engines/sword1/control.cpp:885 -msgid "" -"ScummVM found that you have old saved games for Broken Sword 1 that should " -"be converted.\n" -"The old saved game format is no longer supported, so you will not be able to " -"load your games if you don't convert them.\n" -"\n" -"Press OK to convert them now, otherwise you will be asked again the next " -"time you start the game.\n" -msgstr "" -"ScummVM hat erkannt, dass Sie alte Spielstände von Baphomets Fluch 1 haben, " -"die umgewandelt werden sollten.\n" -"Das alte Speicherformat wird nicht mehr unterstützt, daher können Sie diese " -"Spielstände unkonvertiert nicht laden.\n" -"\n" -"Klicken Sie auf OK, um diese jetzt umzuwandeln, sonst werden Sie erneut " -"gefragt, wenn Sie nächstes Mal dieses Spiel starten.\n" - -#: engines/sword1/control.cpp:1259 -#, c-format -msgid "" -"Target new saved game already exists!\n" -"Would you like to keep the old saved game (%s) or the new one (%s)?\n" -msgstr "" -"Die für den neuen Spielstand vorgesehene Datei existiert bereits!\n" -"Möchten Sie den alten Speicherstand (%s) oder den neuen (%s) behalten?\n" - -#: engines/sword1/control.cpp:1262 -msgid "Keep the old one" -msgstr "Den alten behalten" - -#: engines/sword1/control.cpp:1262 -msgid "Keep the new one" -msgstr "Den neuen behalten" - -#: engines/sword1/logic.cpp:1633 -msgid "This is the end of the Broken Sword 1 Demo" -msgstr "Das ist das Ende der Demo von Broken Sword 1 (Baphomets Fluch 1)" - -#: engines/sword2/animation.cpp:425 -msgid "" -"PSX cutscenes found but ScummVM has been built without RGB color support" -msgstr "" -"PSX-Zwischensequenzen gefunden, aber ScummVM wurde ohne Unterstützung für " -"RGB-Farben erstellt" - -#: engines/sword2/sword2.cpp:79 -msgid "Show object labels" -msgstr "Objektnamen zeigen" - -#: engines/sword2/sword2.cpp:80 -msgid "Show labels for objects on mouse hover" -msgstr "Zeigt Objektbeschriftungen bei Mausberührung an" - -#: engines/sword25/detection.cpp:46 -msgid "Use English speech" -msgstr "Verwende englische Sprachausgabe" - -#: engines/sword25/detection.cpp:47 -msgid "" -"Use English speech instead of German for every language other than German" -msgstr "" -"Verwende englische Sprachausgabe anstelle der deutschen, wenn eine andere " -"Sprache als Deutsch verwendet wird" - -#: engines/teenagent/resources.cpp:118 -msgid "" -"The teenagent.dat file is compressed and zlib hasn't been included in this " -"executable. Please decompress it" -msgstr "" -"Die Datei \"teenagent.dat\" ist gepackt und zlib zum Entpacken wurde in " -"dieser ausführbaren Datei nicht miteingebunden. Bitte entpacken Sie die Datei" - -#: engines/tony/tony.cpp:258 -#, c-format -msgid "Font variant not present in '%s' engine data file." -msgstr "Schriftartvariante in Engine-Datendatei '%s' nicht vorhanden." - -#: engines/toon/toon.cpp:222 -#, c-format -msgid "Saved game in slot #%d " -msgstr "Spiel in Speicherplatz #%d gespeichert " - -#: engines/toon/toon.cpp:226 -#, c-format -msgid "Could not quick save into slot #%d" -msgstr "Speichern im Schnellspeicherplatz #%d fehlgeschlagen" - -#: engines/toon/toon.cpp:239 -#, c-format -msgid "Saved game #%d quick loaded" -msgstr "Spielstand #%d geladen" - -#: engines/toon/toon.cpp:243 -#, c-format -msgid "Could not quick load the saved game #%d" -msgstr "Schnellladen des Spielstandes #%d nicht möglich" - -#: engines/wintermute/detection.cpp:59 -msgid "Show FPS-counter" -msgstr "FPS-Zähler anzeigen" - -#: engines/wintermute/detection.cpp:60 -msgid "Show the current number of frames per second in the upper left corner" -msgstr "" -"Zeige die aktuelle Anzahl von Bildern pro Sekunde in der oberen linken Ecke" - -#: engines/wintermute/detection.cpp:69 -msgid "Sprite bilinear filtering (SLOW)" -msgstr "Bilineare Filterung für Sprites (LANGSAM)" - -#: engines/wintermute/detection.cpp:70 -msgid "Apply bilinear filtering to individual sprites" -msgstr "Bilineare Filterung auf einzelne Sprites anwenden" - -#: engines/wintermute/wintermute.cpp:153 -msgid "This game requires PNG, JPEG and Vorbis support." -msgstr "Dieses Spiel benötigt Unterstützung für PNG, JPEG und Vorbis." - -#: engines/wintermute/wintermute.cpp:164 -msgid "" -"This game requires 3D characters support, which is out of ScummVM's scope." -msgstr "" -"Dieses Spiel benötigt die Unterstützung von 3D-Charakteren, welche nicht in " -"ScummVM enthalten ist." - -#: engines/xeen/detection.cpp:89 -msgid "Show item costs in standard inventory mode" -msgstr "Item-Kosten im Standard-Inventarmodus anzeigen" - -#: engines/xeen/detection.cpp:90 -msgid "" -"Shows item costs in standard inventory mode, allowing the value of items to " -"be compared" -msgstr "" -"Zeigt die Gegenstandskosten im Standard-Inventarmodus an, um einen Vergleich " -"der Gegenstände zu ermöglichen" - -#: engines/xeen/detection.cpp:99 -msgid "More durable armor" -msgstr "Widerstandsfähigere Rüstung" - -#: engines/xeen/detection.cpp:100 -msgid "Armor won't break until character is at -80HP, rather than merely -10HP" -msgstr "" -"Rüstung zerbricht erst, wenn der Charakter -80HP besitzt und nicht bereits " -"bei -10HP" - -#: engines/zvision/detection_tables.h:61 -msgid "Double FPS" -msgstr "FPS verdoppeln" - -#: engines/zvision/detection_tables.h:62 -msgid "Increase framerate from 30 to 60 FPS" -msgstr "Bilder pro Sekunde im Spiel von 30 auf 60 erhöhen" - -#: engines/zvision/detection_tables.h:71 -msgid "Enable Venus" -msgstr "Venus aktivieren" - -#: engines/zvision/detection_tables.h:72 -msgid "Enable the Venus help system" -msgstr "Aktiviere das Venus-Hilfesystem" - -#: engines/zvision/detection_tables.h:81 -msgid "Disable animation while turning" -msgstr "Animation während Drehen ausschalten" - -#: engines/zvision/detection_tables.h:82 -msgid "Disable animation while turning in panorama mode" -msgstr "Animation während Drehen im Panorama-Modus ausschalten" - -#: engines/zvision/detection_tables.h:91 -msgid "Use high resolution MPEG video" -msgstr "Verwende hochauflösende MPEG-Filme" - -#: engines/zvision/detection_tables.h:92 -msgid "Use MPEG video from the DVD version instead of lower resolution AVI" -msgstr "" -"Verwende die hochauflösendenden MPEG-Filme der DVD-Version anstelle der " -"niedriger aufgelösten AVI-Filme" - -#: engines/zvision/file/save_manager.cpp:226 -#, c-format -msgid "" -"This saved game uses version %u, but this engine only supports up to version " -"%d. You will need an updated version of the engine to use this saved game." -msgstr "" -"Dieser Spielstand verwendet Version %u, diese Engine unterstützt jedoch nur " -"Spielstände bis zu Version %d. Sie benötigen eine aktualisierte Version der " -"Engine, um diesen Spielstand zu verwenden." - -#~ msgid "Software Rendering" -#~ msgstr "Software-Rendering" - -#~ msgid "Enable software rendering" -#~ msgstr "Software-Rendering aktivieren" - -#~ msgid "You have to restart ResidualVM before your changes will take effect." -#~ msgstr "" -#~ "Sie müssen ResidualVM neu starten, damit die Änderungen wirksam werden." - -#~ msgid "" -#~ "Please, report the following data to the ResidualVM team along with name" -#~ msgstr "" -#~ "Bitte melden Sie die folgenden Daten an das ResidualVM-Team, zusammen mit " -#~ "dem Namen" - -#~ msgid "Unnamed savegame" -#~ msgstr "Unbenannter Spielstand" - -#~ msgid "Windowed mode" -#~ msgstr "Fenstermodus" - -#~ msgid "" -#~ "A known buggy game script has been detected, which could prevent you from " -#~ "progressing later on in the game, during the sequence with the Green " -#~ "Man's riddles. Please, apply the latest patch for this game by Sierra to " -#~ "avoid possible problems." -#~ msgstr "" -#~ "Ein bekannter Fehler im Spiel-Skript wurde erkannt, der möglicherweise " -#~ "den weiteren Spielfortschritt innerhalb des \"Green Man\"-Rätsels " -#~ "verhindert. Bitte wenden Sie den letzten Patch an, den Sierra für dieses " -#~ "Spiel veröffentlicht hat, um mögliche Probleme zu vermeiden." - -#~ msgctxt "lowres" -#~ msgid "Music Device:" -#~ msgstr "Musikgerät:" - -#~ msgctxt "lowres" -#~ msgid "Text and Speech:" -#~ msgstr "Text u. Sprache:" - -#~ msgid "AdLib Emulator" -#~ msgstr "AdLib-Emulator" - -#~ msgid "Use the original save/load screens instead of the ScummVM interface" -#~ msgstr "" -#~ "Verwendet die originalen Menüs zum Speichern und Laden statt der von " -#~ "ScummVM" - -#~ msgid "(You can always enable it in the options dialog on the Misc tab)" -#~ msgstr "" -#~ "(Sie können diese auch jederzeit im Options-Dialog unter dem Reiter " -#~ "\"Sonstiges\" aktivieren)" - -#~ msgid "Check for updates automatically" -#~ msgstr "Automatisch nach Aktualisierungen suchen" - -#~ msgid "8 kHz" -#~ msgstr "8 kHz" - -#~ msgid "11 kHz" -#~ msgstr "11 kHz" - -#~ msgid "22 kHz" -#~ msgstr "22 kHz" - -#~ msgid "44 kHz" -#~ msgstr "44 kHz" - -#~ msgid "48 kHz" -#~ msgstr "48 kHz" - -#~ msgid "Output rate:" -#~ msgstr "Ausgabefrequenz:" - -#~ msgid "" -#~ "Higher value specifies better sound quality but may be not supported by " -#~ "your soundcard" -#~ msgstr "" -#~ "Höhere Werte bewirken eine bessere Soundqualität, werden aber " -#~ "möglicherweise nicht von jeder Soundkarte unterstützt" - -# Nicht übersetzen, da diese Nachricht nur für nicht-lateinische Sprachen relevant ist. -#~ msgid "" -#~ "The theme you selected does not support your current language. If you " -#~ "want to use this theme you need to switch to another language first." -#~ msgstr "" -#~ "Das ausgewählte Thema unterstützt nicht die aktuelle Sprache. Wenn Sie " -#~ "dieses Thema benutzen wollen, müssen Sie erst zu einer anderen Sprache " -#~ "wechseln." - -#~ msgid "3" -#~ msgstr "3" - -#~ msgid "5" -#~ msgstr "5" - -#~ msgid "8" -#~ msgstr "8" - -#~ msgid "10" -#~ msgstr "10" - -#~ msgid "13" -#~ msgstr "13" - -#~ msgid "15" -#~ msgstr "15" - -#~ msgid "18" -#~ msgstr "18" - -#~ msgid "20" -#~ msgstr "20" - -#, fuzzy -#~ msgid "Speed multiplier for mouse emulation" -#~ msgstr "Geschwindigkeitsfaktor für Maus-Emulation" - -#~ msgctxt "lowres" -#~ msgid "Mouse Speed:" -#~ msgstr "Maus-Geschwindigkeit:" - -#~ msgid "" -#~ "Unable to find \"sky.cpt\" file!\n" -#~ "Please download it from www.scummvm.org" -#~ msgstr "" -#~ "Konnte \"sky.cpt\" nicht finden!\n" -#~ "Bitte laden Sie die Datei von\n" -#~ "www.scummvm.org herunter" - -#~ msgid "" -#~ "The \"sky.cpt\" file has an incorrect size.\n" -#~ "Please (re)download it from www.scummvm.org" -#~ msgstr "" -#~ "Die Datei \"sky.cpt\" hat eine ungültige Größe.\n" -#~ "Bitte laden Sie diese Datei (erneut) von\n" -#~ "www.scummvm.org herunter" - -#~ msgid "" -#~ "You're missing the 'teenagent.dat' file. Get it from the ScummVM website" -#~ msgstr "" -#~ "Ihnen fehlt die Datei \"teenagent.dat\". Laden Sie sich diese von der " -#~ "ScummVM-Website unter https://www.scummvm.org herunter" - -#~ msgid "You're missing the 'toon.dat' file. Get it from the ScummVM website" -#~ msgstr "" -#~ "Ihnen fehlt die Datei \"toon.dat\". Laden Sie sich diese von der ScummVM-" -#~ "Website unter https://www.scummvm.org herunter" - -#~ msgid "File 'toon.dat' is corrupt. Get it from the ScummVM website" -#~ msgstr "" -#~ "Die Datei \"toon.dat\" ist defekt. Laden Sie diese von der ScummVM-" -#~ "Website herunter" - -#~ msgid "" -#~ "File 'toon.dat' is wrong version. Expected %d.%d but got %d.%d. Get it " -#~ "from the ScummVM website" -#~ msgstr "" -#~ "Falsche Version der Datei 'toon.dat'. %d.%d wurde erwartet, aber %d.%d " -#~ "erhalten. Laden Sie die Datei von der ScummVM-Website unter http://www." -#~ "scummvm.org herunter" - -#~ msgid "Invalid save file name" -#~ msgstr "Ungültiger Spielstandname" - -#~ msgid "Use original savegame dialog" -#~ msgstr "Originale Spielstand-Menüs verwenden" - -#~ msgid "" -#~ "Files button in-game shows original savegame dialog rather than the " -#~ "ScummVM menu" -#~ msgstr "" -#~ "Dateien-Schaltfläche im Spiel zeigt originales Spielstand-Menü statt dem " -#~ "von ScummVM." - -#~ msgid "The game in '%s' seems to be unknown." -#~ msgstr "Das Spiel im Verzeichnis \"%s\" scheint nicht bekannt zu sein." - -#~ msgid "" -#~ "Please, report the following data to the ScummVM team along with name" -#~ msgstr "" -#~ "Bitte geben Sie die folgenden Daten auf Englisch an das ScummVM-Team " -#~ "weiter sowie" - -#~ msgid "of the game you tried to add and its version/language/etc.:" -#~ msgstr "" -#~ "den Namen des Spiels, das Sie hinzufügen wollten, als auch die Version/" -#~ "Sprache/usw.:" - -#~ msgid "You have to restart ScummVM before your changes will take effect." -#~ msgstr "" -#~ "Sie müssen ScummVM neu starten, damit die Änderungen wirksam werden." - -#~ msgid "OpenGL (No filtering)" -#~ msgstr "OpenGL (ohne Filter)" - -#~ msgid "Specifies where Files Manager can access to" -#~ msgstr "Legt fest, auf welches Verzeichnis der Dateimanager zugreifen darf." - -#~ msgid "When this storage did saves sync last time" -#~ msgstr "Zeitpunkt der letzten Synchronisierung dieses Cloud-Speichers" - -#~ msgid "EGA undithering" -#~ msgstr "Antifehlerdiffusion für EGA" - -#~ msgid "Enable undithering in EGA games" -#~ msgstr "Aktiviert die Aufhebung der Fehlerdiffusion in EGA-Spielen." - -#~ msgid "MPEG-2 cutscenes found but ScummVM has been built without MPEG-2" -#~ msgstr "" -#~ "MPEG-2-Zwischensequenzen gefunden, aber ScummVM wurde ohne Unterstützung " -#~ "für MPEG-2-Videos erstellt." - -#~ msgctxt "lowres" -#~ msgid "Mass Add..." -#~ msgstr "Durchsuchen" - -#~ msgid "" -#~ "Turns off General MIDI mapping for games with Roland MT-32 soundtrack" -#~ msgstr "" -#~ "Schaltet die General-MIDI-Zuweisung für Spiele mit Roland-MT-32-Audiospur " -#~ "aus." - -#~ msgid "Standard (16bpp)" -#~ msgstr "Standard (16bpp)" - -#~ msgid "MPEG2 cutscenes are no longer supported" -#~ msgstr "MPEG2-Zwischensequenzen werden nicht mehr unterstützt." - -#~ msgid "OpenGL Conserve" -#~ msgstr "OpenGL: beibehalten" - -#~ msgid "OpenGL Original" -#~ msgstr "OpenGL: original" - -#~ msgid "Current display mode" -#~ msgstr "Aktueller Grafikmodus" - -#~ msgid "Current scale" -#~ msgstr "Aktueller Vergrößerungsfaktor" - -#~ msgid "Active filter mode: Linear" -#~ msgstr "Aktiver Filtermodus: linear" - -#~ msgid "Active filter mode: Nearest" -#~ msgstr "Aktiver Filtermodus: nächste Nachbarn" - -#~ msgid "" -#~ "Your game version has been detected using filename matching as a variant " -#~ "of %s." -#~ msgstr "" -#~ "Ihre Spielversion wurde durch Dateinamen-Übereinstimmung als Variante von " -#~ "%s erkannt." - -#~ msgid "Command line argument not processed" -#~ msgstr "Argument in Kommandozeile nicht verarbeitet" +# German translation for ScummVM. +# Copyright (C) 2010-2017 The ScummVM Team +# This file is distributed under the same license as the ScummVM package. +# Simon Sawatzki , Lothar Serra Mari , 2016. +# +msgid "" +msgstr "" +"Project-Id-Version: ScummVM 1.10.0git\n" +"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n" +"POT-Creation-Date: 2019-06-24 19:41+0200\n" +"PO-Revision-Date: 2019-06-23 23:15+0000\n" +"Last-Translator: Lothar Serra Mari \n" +"Language-Team: German \n" +"Language: de_DE\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.3\n" +"X-Language-name: Deutsch\n" + +#: gui/about.cpp:94 +#, c-format +msgid "(built on %s)" +msgstr "(erstellt am %s)" + +#: gui/about.cpp:101 +msgid "Features compiled in:" +msgstr "Verfügbare Funktionen:" + +#: gui/about.cpp:110 +msgid "Available engines:" +msgstr "Verfügbare Spiele-Engines:" + +#: gui/browser.cpp:75 backends/dialogs/macosx/macosx-dialogs.mm:87 +msgid "Show hidden files" +msgstr "Versteckte Dateien anzeigen" + +#: gui/browser.cpp:75 +msgid "Show files marked with the hidden attribute" +msgstr "" +"Dateien anzeigen, die mit dem Attribut \"versteckt\" gekennzeichnet sind" + +#: gui/browser.cpp:79 gui/remotebrowser.cpp:57 +msgid "Go up" +msgstr "Pfad hoch" + +#: gui/browser.cpp:79 gui/browser.cpp:81 gui/remotebrowser.cpp:57 +#: gui/remotebrowser.cpp:59 +msgid "Go to previous directory level" +msgstr "Zu höherer Pfadebene wechseln" + +#: gui/browser.cpp:81 gui/remotebrowser.cpp:59 +msgctxt "lowres" +msgid "Go up" +msgstr "Pfad hoch" + +#: gui/browser.cpp:82 gui/chooser.cpp:46 gui/editgamedialog.cpp:299 +#: gui/editrecorddialog.cpp:67 gui/filebrowser-dialog.cpp:65 +#: gui/fluidsynth-dialog.cpp:153 gui/KeysDialog.cpp:43 gui/massadd.cpp:92 +#: gui/options.cpp:1799 gui/predictivedialog.cpp:73 gui/recorderdialog.cpp:69 +#: gui/recorderdialog.cpp:155 gui/remotebrowser.cpp:60 +#: gui/saveload-dialog.cpp:389 gui/saveload-dialog.cpp:451 +#: gui/saveload-dialog.cpp:746 gui/saveload-dialog.cpp:1140 +#: gui/storagewizarddialog.cpp:68 gui/themebrowser.cpp:55 +#: gui/unknown-game-dialog.cpp:49 engines/engine.cpp:546 +#: backends/events/default/default-events.cpp:190 +#: backends/events/default/default-events.cpp:212 +#: backends/platform/wii/options.cpp:48 engines/drascula/saveload.cpp:49 +#: engines/mohawk/myst_stacks/menu.cpp:284 +#: engines/mohawk/myst_stacks/menu.cpp:301 +#: engines/mohawk/myst_stacks/menu.cpp:319 +#: engines/mohawk/riven_stacks/aspit.cpp:350 +#: engines/mohawk/riven_stacks/aspit.cpp:372 +#: engines/mohawk/riven_stacks/aspit.cpp:456 +#: engines/parallaction/saveload.cpp:271 engines/scumm/dialogs.cpp:187 +#: engines/sword1/control.cpp:887 engines/wintermute/wintermute.cpp:166 +msgid "Cancel" +msgstr "Abbrechen" + +#: gui/browser.cpp:83 gui/chooser.cpp:47 gui/filebrowser-dialog.cpp:66 +#: gui/remotebrowser.cpp:61 gui/themebrowser.cpp:56 +#: backends/dialogs/macosx/macosx-dialogs.mm:148 +#: backends/dialogs/win32/win32-dialogs.cpp:145 +msgid "Choose" +msgstr "Auswählen" + +#: gui/downloaddialog.cpp:48 +msgid "Select directory where to download game data" +msgstr "" +"Wählen Sie das Verzeichnis, in welches die Spieldaten heruntergeladen werden " +"sollen" + +#: gui/downloaddialog.cpp:49 gui/editgamedialog.cpp:482 gui/launcher.cpp:198 +msgid "Select directory with game data" +msgstr "Verzeichnis mit Spieldateien auswählen" + +#: gui/downloaddialog.cpp:51 gui/downloaddialog.cpp:263 +msgid "From: " +msgstr "Von: " + +#: gui/downloaddialog.cpp:52 gui/downloaddialog.cpp:264 +msgid "To: " +msgstr "Nach: " + +#: gui/downloaddialog.cpp:63 +msgid "Cancel download" +msgstr "Download abbrechen" + +#: gui/downloaddialog.cpp:65 +msgctxt "lowres" +msgid "Cancel download" +msgstr "Download abbr." + +#: gui/downloaddialog.cpp:67 +msgid "Hide" +msgstr "Verstecken" + +#: gui/downloaddialog.cpp:117 +msgid "" +"It looks like your connection is limited. Do you really want to download " +"files with it?" +msgstr "" +"Ihre Internetverbindung ist anscheinend getaktet. Möchten Sie die Dateien " +"wirklich über diese Verbindung herunterladen?" + +#: gui/downloaddialog.cpp:118 gui/downloaddialog.cpp:152 +#: gui/filebrowser-dialog.cpp:133 gui/fluidsynth-dialog.cpp:218 +#: gui/launcher.cpp:326 gui/launcher.cpp:395 gui/launcher.cpp:455 +#: gui/storagewizarddialog.cpp:112 +#: backends/events/symbiansdl/symbiansdl-events.cpp:191 +#: backends/platform/wince/CEActionsPocket.cpp:326 +#: backends/platform/wince/CEActionsSmartphone.cpp:287 +#: backends/platform/wince/CELauncherDialog.cpp:83 +#: engines/kyra/gui/saveload_eob.cpp:569 engines/kyra/gui/saveload_eob.cpp:602 +#: engines/sci/graphics/controls32.cpp:820 +msgid "Yes" +msgstr "Ja" + +#: gui/downloaddialog.cpp:118 gui/downloaddialog.cpp:153 +#: gui/filebrowser-dialog.cpp:133 gui/fluidsynth-dialog.cpp:218 +#: gui/launcher.cpp:326 gui/launcher.cpp:395 gui/launcher.cpp:455 +#: gui/storagewizarddialog.cpp:112 +#: backends/events/symbiansdl/symbiansdl-events.cpp:191 +#: backends/platform/wince/CEActionsPocket.cpp:326 +#: backends/platform/wince/CEActionsSmartphone.cpp:287 +#: backends/platform/wince/CELauncherDialog.cpp:83 +#: engines/kyra/gui/saveload_eob.cpp:569 engines/kyra/gui/saveload_eob.cpp:602 +#: engines/sci/graphics/controls32.cpp:820 +msgid "No" +msgstr "Nein" + +#: gui/downloaddialog.cpp:136 gui/launcher.cpp:554 +msgid "ScummVM couldn't open the specified directory!" +msgstr "ScummVM konnte das gewählte Verzeichnis nicht öffnen!" + +#: gui/downloaddialog.cpp:146 +msgid "" +"Cannot create a directory to download - the specified directory has a file " +"with the same name." +msgstr "" +"Kann kein Verzeichnis zum Herunterladen erstellen - das gewählte Verzeichnis " +"beinhaltet eine Datei mit dem gleichen Namen." + +#: gui/downloaddialog.cpp:146 gui/editgamedialog.cpp:300 +#: gui/fluidsynth-dialog.cpp:154 gui/KeysDialog.cpp:42 gui/launcher.cpp:504 +#: gui/launcher.cpp:508 gui/massadd.cpp:89 gui/options.cpp:1801 +#: gui/saveload-dialog.cpp:1141 engines/engine.cpp:465 engines/engine.cpp:476 +#: backends/platform/wii/options.cpp:47 +#: backends/platform/wince/CELauncherDialog.cpp:54 +#: engines/agos/animation.cpp:559 engines/drascula/saveload.cpp:49 +#: engines/groovie/script.cpp:430 engines/parallaction/saveload.cpp:271 +#: engines/sci/engine/kgraphics.cpp:74 engines/sci/graphics/controls32.cpp:817 +#: engines/scumm/dialogs.cpp:189 engines/scumm/scumm.cpp:1885 +#: engines/scumm/players/player_v3m.cpp:130 +#: engines/scumm/players/player_v5m.cpp:108 engines/sky/compact.cpp:141 +#: engines/sword1/animation.cpp:524 engines/sword1/animation.cpp:545 +#: engines/sword1/animation.cpp:561 engines/sword1/animation.cpp:569 +#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633 +#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445 +#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471 +#: engines/zvision/file/save_manager.cpp:230 +msgid "OK" +msgstr "OK" + +#: gui/downloaddialog.cpp:151 +#, c-format +msgid "" +"The \"%s\" already exists in the specified directory.\n" +"Do you really want to download files into that directory?" +msgstr "" +"\"%s\" existiert im gewählten Verzeichnis bereits.\n" +"Möchten Sie wirklich die Dateien in das gewählte Verzeichnis herunterladen?" + +#: gui/downloaddialog.cpp:251 +#, c-format +msgid "Downloaded %s %s / %s %s" +msgstr "%s %s / %s %s heruntergeladen" + +#: gui/downloaddialog.cpp:258 +#, c-format +msgid "Download speed: %s %s" +msgstr "Download-Geschwindigkeit: %s %s" + +#: gui/editgamedialog.cpp:136 +msgid "Game" +msgstr "Spiel" + +#: gui/editgamedialog.cpp:140 +msgid "ID:" +msgstr "ID:" + +#: gui/editgamedialog.cpp:140 gui/editgamedialog.cpp:142 +#: gui/editgamedialog.cpp:143 +msgid "" +"Short game identifier used for referring to saved games and running the game " +"from the command line" +msgstr "" +"Kurzer Spielname, um Spielstände zuzuordnen und das Spiel von der " +"Kommandozeile aus starten zu können" + +#: gui/editgamedialog.cpp:142 +msgctxt "lowres" +msgid "ID:" +msgstr "ID:" + +#: gui/editgamedialog.cpp:147 gui/editrecorddialog.cpp:59 +msgid "Name:" +msgstr "Name:" + +#: gui/editgamedialog.cpp:147 gui/editgamedialog.cpp:149 +#: gui/editgamedialog.cpp:150 +msgid "Full title of the game" +msgstr "Vollständiger Name des Spiels" + +#: gui/editgamedialog.cpp:149 +msgctxt "lowres" +msgid "Name:" +msgstr "Name:" + +#: gui/editgamedialog.cpp:153 +msgid "Language:" +msgstr "Sprache:" + +#: gui/editgamedialog.cpp:153 gui/editgamedialog.cpp:154 +msgid "" +"Language of the game. This will not turn your Spanish game version into " +"English" +msgstr "" +"Sprache des Spiels. Diese Funktion wird eine spanische Version des Spiels " +"nicht in eine deutsche verwandeln" + +#: gui/editgamedialog.cpp:155 gui/editgamedialog.cpp:169 gui/options.cpp:1055 +#: gui/options.cpp:1068 gui/options.cpp:1082 gui/options.cpp:1673 +#: audio/null.cpp:41 +msgid "" +msgstr "" + +#: gui/editgamedialog.cpp:165 +msgid "Platform:" +msgstr "Plattform:" + +#: gui/editgamedialog.cpp:165 gui/editgamedialog.cpp:167 +#: gui/editgamedialog.cpp:168 +msgid "Platform the game was originally designed for" +msgstr "Plattform, für die das Spiel ursprünglich erstellt wurde" + +#: gui/editgamedialog.cpp:167 +msgctxt "lowres" +msgid "Platform:" +msgstr "Plattform:" + +#: gui/editgamedialog.cpp:180 +msgid "Engine" +msgstr "Engine" + +#: gui/editgamedialog.cpp:188 gui/options.cpp:1415 gui/options.cpp:1525 +msgid "Graphics" +msgstr "Grafik" + +#: gui/editgamedialog.cpp:188 gui/options.cpp:1415 gui/options.cpp:1525 +msgid "GFX" +msgstr "GFX" + +#: gui/editgamedialog.cpp:194 +msgid "Override global graphic settings" +msgstr "Globale Grafik-Einstellungen übergehen" + +#: gui/editgamedialog.cpp:196 +msgctxt "lowres" +msgid "Override global graphic settings" +msgstr "Globale Grafik-Einstellungen übergehen" + +#: gui/editgamedialog.cpp:203 gui/options.cpp:1555 +msgid "Audio" +msgstr "Audio" + +#: gui/editgamedialog.cpp:206 +msgid "Override global audio settings" +msgstr "Globale Audio-Einstellungen übergehen" + +#: gui/editgamedialog.cpp:208 +msgctxt "lowres" +msgid "Override global audio settings" +msgstr "Globale Audio-Einstellungen übergehen" + +#: gui/editgamedialog.cpp:217 gui/options.cpp:1560 +msgid "Volume" +msgstr "Lautstärke" + +#: gui/editgamedialog.cpp:219 gui/options.cpp:1562 +msgctxt "lowres" +msgid "Volume" +msgstr "Lautst." + +#: gui/editgamedialog.cpp:222 +msgid "Override global volume settings" +msgstr "Globale Lautstärke-Einstellungen übergehen" + +#: gui/editgamedialog.cpp:224 +msgctxt "lowres" +msgid "Override global volume settings" +msgstr "Globale Lautstärke-Einstellungen übergehen" + +#: gui/editgamedialog.cpp:233 gui/options.cpp:1570 +msgid "MIDI" +msgstr "MIDI" + +#: gui/editgamedialog.cpp:236 +msgid "Override global MIDI settings" +msgstr "Globale MIDI-Einstellungen übergehen" + +#: gui/editgamedialog.cpp:238 +msgctxt "lowres" +msgid "Override global MIDI settings" +msgstr "Globale MIDI-Einstellungen übergehen" + +#: gui/editgamedialog.cpp:248 gui/options.cpp:1580 +msgid "MT-32" +msgstr "MT-32" + +#: gui/editgamedialog.cpp:251 +msgid "Override global MT-32 settings" +msgstr "Globale MT-32-Einstellungen übergehen" + +#: gui/editgamedialog.cpp:253 +msgctxt "lowres" +msgid "Override global MT-32 settings" +msgstr "Globale MT-32-Einstellungen übergehen" + +#: gui/editgamedialog.cpp:262 gui/options.cpp:1587 +msgid "Paths" +msgstr "Pfade" + +#: gui/editgamedialog.cpp:264 gui/options.cpp:1589 +msgctxt "lowres" +msgid "Paths" +msgstr "Pfade" + +#: gui/editgamedialog.cpp:271 +msgid "Game Path:" +msgstr "Spielpfad:" + +#: gui/editgamedialog.cpp:273 +msgctxt "lowres" +msgid "Game Path:" +msgstr "Spielpfad:" + +#: gui/editgamedialog.cpp:278 gui/options.cpp:1613 +msgid "Extra Path:" +msgstr "Extras:" + +#: gui/editgamedialog.cpp:278 gui/editgamedialog.cpp:280 +#: gui/editgamedialog.cpp:281 +msgid "Specifies path to additional data used by the game" +msgstr "Legt das Verzeichnis für zusätzliche Spieldateien fest" + +#: gui/editgamedialog.cpp:280 gui/options.cpp:1615 +msgctxt "lowres" +msgid "Extra Path:" +msgstr "Extras:" + +#: gui/editgamedialog.cpp:287 gui/options.cpp:1597 +msgid "Save Path:" +msgstr "Spielstände:" + +#: gui/editgamedialog.cpp:287 gui/editgamedialog.cpp:289 +#: gui/editgamedialog.cpp:290 gui/options.cpp:1597 gui/options.cpp:1599 +#: gui/options.cpp:1600 +msgid "Specifies where your saved games are put" +msgstr "Legt fest, wo die Spielstände gespeichert werden" + +#: gui/editgamedialog.cpp:289 gui/options.cpp:1599 +msgctxt "lowres" +msgid "Save Path:" +msgstr "Spielstände:" + +#: gui/editgamedialog.cpp:313 gui/editgamedialog.cpp:410 +#: gui/editgamedialog.cpp:469 gui/editgamedialog.cpp:530 gui/options.cpp:1608 +#: gui/options.cpp:1616 gui/options.cpp:1625 gui/options.cpp:1826 +#: gui/options.cpp:1832 gui/options.cpp:1840 gui/options.cpp:1863 +#: gui/options.cpp:1896 gui/options.cpp:1902 gui/options.cpp:1909 +#: gui/options.cpp:1917 gui/options.cpp:2119 gui/options.cpp:2122 +#: gui/options.cpp:2129 gui/options.cpp:2139 +msgctxt "path" +msgid "None" +msgstr "Keiner" + +#: gui/editgamedialog.cpp:318 gui/editgamedialog.cpp:416 +#: gui/editgamedialog.cpp:534 gui/options.cpp:1820 gui/options.cpp:1890 +#: gui/options.cpp:2125 backends/platform/wii/options.cpp:56 +msgid "Default" +msgstr "Standard" + +#: gui/editgamedialog.cpp:462 gui/options.cpp:2133 +msgid "Select SoundFont" +msgstr "SoundFont auswählen" + +#: gui/editgamedialog.cpp:501 +msgid "Select additional game directory" +msgstr "Verzeichnis mit zusätzlichen Dateien auswählen" + +#: gui/editgamedialog.cpp:514 gui/options.cpp:2056 +msgid "Select directory for saved games" +msgstr "Verzeichnis für Spielstände auswählen" + +#: gui/editgamedialog.cpp:520 +msgid "" +"Saved games sync feature doesn't work with non-default directories. If you " +"want your saved games to sync, use default directory." +msgstr "" +"Spielstand-Synchronisierung funktioniert nicht mit anderen Verzeichnissen. " +"Wenn Sie Ihre Spielstände synchronisieren möchten, verwenden Sie das " +"Standard-Verzeichnis." + +#: gui/editgamedialog.cpp:546 +msgid "This game ID is already taken. Please choose another one." +msgstr "Diese Spiel-ID ist bereits vergeben. Bitte eine andere wählen." + +#: gui/editrecorddialog.cpp:58 +msgid "Author:" +msgstr "Autor:" + +#: gui/editrecorddialog.cpp:60 +msgid "Notes:" +msgstr "Notizen:" + +#: gui/editrecorddialog.cpp:68 gui/predictivedialog.cpp:74 +msgid "Ok" +msgstr "OK" + +#: gui/filebrowser-dialog.cpp:50 +msgid "Choose file for loading" +msgstr "Zu ladende Datei auswählen" + +#: gui/filebrowser-dialog.cpp:50 +msgid "Enter filename for saving" +msgstr "Dateiname zum Speichern eingeben" + +#: gui/filebrowser-dialog.cpp:133 +msgid "Do you really want to overwrite the file?" +msgstr "Möchten Sie diese Datei wirklich überschreiben?" + +#: gui/fluidsynth-dialog.cpp:69 +msgid "Reverb" +msgstr "Hall" + +#: gui/fluidsynth-dialog.cpp:71 gui/fluidsynth-dialog.cpp:103 +msgid "Active" +msgstr "Aktiv" + +#: gui/fluidsynth-dialog.cpp:73 +msgid "Room:" +msgstr "Raum:" + +#: gui/fluidsynth-dialog.cpp:80 +msgid "Damp:" +msgstr "Dämpfung:" + +#: gui/fluidsynth-dialog.cpp:87 +msgid "Width:" +msgstr "Radius:" + +#: gui/fluidsynth-dialog.cpp:94 gui/fluidsynth-dialog.cpp:112 +msgid "Level:" +msgstr "Intensität:" + +#: gui/fluidsynth-dialog.cpp:101 +msgid "Chorus" +msgstr "Chorus" + +#: gui/fluidsynth-dialog.cpp:105 +msgid "N:" +msgstr "Stimmen:" + +#: gui/fluidsynth-dialog.cpp:119 +msgid "Speed:" +msgstr "Rate:" + +#: gui/fluidsynth-dialog.cpp:126 +msgid "Depth:" +msgstr "Trennzeit:" + +#: gui/fluidsynth-dialog.cpp:133 +msgid "Type:" +msgstr "Typ:" + +#: gui/fluidsynth-dialog.cpp:136 +msgid "Sine" +msgstr "Sinus" + +#: gui/fluidsynth-dialog.cpp:137 +msgid "Triangle" +msgstr "Dreieck" + +#: gui/fluidsynth-dialog.cpp:139 gui/options.cpp:1633 +msgid "Misc" +msgstr "Sonstiges" + +#: gui/fluidsynth-dialog.cpp:141 +msgid "Interpolation:" +msgstr "Interpolation:" + +#: gui/fluidsynth-dialog.cpp:144 +msgid "None (fastest)" +msgstr "Keine (am schnellsten)" + +#: gui/fluidsynth-dialog.cpp:145 +msgid "Linear" +msgstr "Linear" + +#: gui/fluidsynth-dialog.cpp:146 +msgid "Fourth-order" +msgstr "Vierstufig" + +#: gui/fluidsynth-dialog.cpp:147 +msgid "Seventh-order" +msgstr "Siebenstufig" + +#: gui/fluidsynth-dialog.cpp:151 +msgid "Reset" +msgstr "Zurücksetzen" + +#: gui/fluidsynth-dialog.cpp:151 +msgid "Reset all FluidSynth settings to their default values." +msgstr "Setzt alle FluidSynth-Einstellungen auf ihre Standard-Werte zurück." + +#: gui/fluidsynth-dialog.cpp:218 +msgid "" +"Do you really want to reset all FluidSynth settings to their default values?" +msgstr "" +"Möchten Sie wirklich alle FluidSynth-Einstellungen auf ihre Standard-Werte " +"zurücksetzen?" + +#: gui/gui-manager.cpp:119 gui/unknown-game-dialog.cpp:49 +#: backends/keymapper/remap-dialog.cpp:53 engines/scumm/help.cpp:126 +#: engines/scumm/help.cpp:141 engines/scumm/help.cpp:166 +#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:210 +msgid "Close" +msgstr "Schließen" + +#: gui/gui-manager.cpp:122 +msgid "Mouse click" +msgstr "Mausklick" + +#: gui/gui-manager.cpp:126 base/main.cpp:356 +msgid "Display keyboard" +msgstr "Tastatur anzeigen" + +#: gui/gui-manager.cpp:130 base/main.cpp:360 +msgid "Remap keys" +msgstr "Tasten neu zuweisen" + +#: gui/gui-manager.cpp:133 base/main.cpp:363 engines/scumm/help.cpp:87 +msgid "Toggle fullscreen" +msgstr "Vollbild umschalten" + +#: gui/KeysDialog.cpp:41 +msgid "Map" +msgstr "Zuweisen" + +#: gui/KeysDialog.cpp:49 +msgid "Select an action and click 'Map'" +msgstr "Aktion auswählen und \"Zuweisen\" klicken" + +#: gui/KeysDialog.cpp:80 gui/KeysDialog.cpp:102 gui/KeysDialog.cpp:141 +#, c-format +msgid "Associated key : %s" +msgstr "Zugewiesene Taste: %s" + +#: gui/KeysDialog.cpp:82 gui/KeysDialog.cpp:104 gui/KeysDialog.cpp:143 +msgid "Associated key : none" +msgstr "Zugewiesene Taste: keine" + +#: gui/KeysDialog.cpp:90 +msgid "Please select an action" +msgstr "Bitte eine Aktion auswählen" + +#: gui/KeysDialog.cpp:106 +msgid "Press the key to associate" +msgstr "Taste drücken, um sie zuzuweisen" + +#: gui/KeysDialog.cpp:145 gui/KeysDialog.h:36 +msgid "Choose an action to map" +msgstr "Eine Aktion zum Zuweisen auswählen" + +#: gui/launcher.cpp:142 engines/dialogs.cpp:111 engines/mohawk/dialogs.cpp:142 +msgid "~Q~uit" +msgstr "~B~eenden" + +#: gui/launcher.cpp:142 backends/platform/sdl/macosx/appmenu_osx.mm:209 +msgid "Quit ScummVM" +msgstr "ScummVM beenden" + +#: gui/launcher.cpp:143 +msgid "A~b~out..." +msgstr "Übe~r~..." + +#: gui/launcher.cpp:143 backends/platform/sdl/macosx/appmenu_osx.mm:203 +msgid "About ScummVM" +msgstr "Über ScummVM" + +#: gui/launcher.cpp:144 +msgid "~O~ptions..." +msgstr "~O~ptionen..." + +#: gui/launcher.cpp:144 +msgid "Change global ScummVM options" +msgstr "Globale ScummVM-Einstellungen ändern" + +#: gui/launcher.cpp:146 +msgid "~S~tart" +msgstr "~S~tarten" + +#: gui/launcher.cpp:146 +msgid "Start selected game" +msgstr "Ausgewähltes Spiel starten" + +#: gui/launcher.cpp:149 +msgid "~L~oad..." +msgstr "~L~aden..." + +#: gui/launcher.cpp:149 +msgid "Load saved game for selected game" +msgstr "Spielstand für ausgewähltes Spiel laden" + +#: gui/launcher.cpp:154 +msgid "~A~dd Game..." +msgstr "Spiel ~h~inzufügen..." + +#: gui/launcher.cpp:154 gui/launcher.cpp:161 +msgid "Hold Shift for Mass Add" +msgstr "" +"Umschalttaste (Shift) gedrückt halten, um Verzeichnisse nach Spielen zu " +"durchsuchen" + +#: gui/launcher.cpp:156 +msgid "~E~dit Game..." +msgstr "Spielo~p~tionen..." + +#: gui/launcher.cpp:156 gui/launcher.cpp:163 +msgid "Change game options" +msgstr "Spieloptionen ändern" + +#: gui/launcher.cpp:158 +msgid "~R~emove Game" +msgstr "Spiel ~e~ntfernen" + +#: gui/launcher.cpp:158 gui/launcher.cpp:165 +msgid "Remove game from the list. The game data files stay intact" +msgstr "Spiel aus der Liste entfernen. Die Spieldateien bleiben erhalten" + +#: gui/launcher.cpp:161 +msgctxt "lowres" +msgid "~A~dd Game..." +msgstr "~H~inzufügen..." + +#: gui/launcher.cpp:163 +msgctxt "lowres" +msgid "~E~dit Game..." +msgstr "Spielo~p~tion" + +#: gui/launcher.cpp:165 +msgctxt "lowres" +msgid "~R~emove Game" +msgstr "~E~ntfernen" + +#: gui/launcher.cpp:173 +msgid "Search in game list" +msgstr "In Spieleliste suchen" + +#: gui/launcher.cpp:177 gui/launcher.cpp:785 +msgid "Search:" +msgstr "Suchen:" + +#: gui/launcher.cpp:201 engines/dialogs.cpp:115 engines/cruise/menu.cpp:214 +#: engines/mohawk/dialogs.cpp:162 engines/mohawk/myst.cpp:942 +#: engines/mohawk/riven.cpp:673 engines/pegasus/pegasus.cpp:355 +#: engines/tsage/scenes.cpp:601 engines/wage/saveload.cpp:748 +msgid "Load game:" +msgstr "Spiel laden:" + +#: gui/launcher.cpp:201 engines/dialogs.cpp:115 +#: backends/platform/wince/CEActionsPocket.cpp:267 +#: backends/platform/wince/CEActionsSmartphone.cpp:231 +#: engines/cruise/menu.cpp:214 engines/mohawk/dialogs.cpp:162 +#: engines/mohawk/myst.cpp:942 engines/mohawk/riven.cpp:673 +#: engines/parallaction/saveload.cpp:194 engines/pegasus/pegasus.cpp:355 +#: engines/scumm/dialogs.cpp:185 engines/tsage/scenes.cpp:601 +#: engines/wage/saveload.cpp:748 +msgid "Load" +msgstr "Laden" + +#: gui/launcher.cpp:325 +msgid "" +"Do you really want to run the mass game detector? This could potentially add " +"a huge number of games." +msgstr "" +"Möchten Sie wirklich den PC nach Spielen durchsuchen? Möglicherweise wird " +"dabei eine größere Menge an Spielen hinzugefügt." + +#: gui/launcher.cpp:384 +msgid "This directory cannot be used yet, it is being downloaded into!" +msgstr "" +"Dieses Verzeichnis kann noch nicht verwendet werden, da noch Dateien " +"heruntergeladen werden!" + +#: gui/launcher.cpp:395 +msgid "Do you really want to remove this game configuration?" +msgstr "Möchten Sie diese Spielkonfiguration wirklich entfernen?" + +#: gui/launcher.cpp:454 +msgid "Do you want to load saved game?" +msgstr "Möchten Sie einen Spielstand laden?" + +#: gui/launcher.cpp:504 +msgid "This game does not support loading games from the launcher." +msgstr "" +"Für dieses Spiel wird das Laden aus der Spieleliste heraus nicht unterstützt." + +#: gui/launcher.cpp:508 +msgid "ScummVM could not find any engine capable of running the selected game!" +msgstr "ScummVM konnte keine passende Engine für dieses Spiel finden!" + +#: gui/launcher.cpp:573 +msgid "ScummVM could not find any game in the specified directory!" +msgstr "ScummVM konnte im gewählten Verzeichnis kein Spiel finden!" + +#: gui/launcher.cpp:588 +msgid "Unknown variant" +msgstr "Unbekannte Spiele-Variante" + +#: gui/launcher.cpp:594 +msgid "Pick the game:" +msgstr "Spiel auswählen:" + +#: gui/launcher.cpp:722 +msgid "Mass Add..." +msgstr "Durchsuchen..." + +#: gui/launcher.cpp:724 +msgid "Record..." +msgstr "Aufzeichnen..." + +#: gui/massadd.cpp:76 gui/massadd.cpp:79 +msgid "... progress ..." +msgstr "... läuft ..." + +#: gui/massadd.cpp:265 +msgid "Scan complete!" +msgstr "Suchlauf abgeschlossen!" + +#: gui/massadd.cpp:268 +#, c-format +msgid "Discovered %d new games, ignored %d previously added games." +msgstr "%d neue Spiele gefunden, %d bereits hinzugefügte Spiele ignoriert." + +#: gui/massadd.cpp:272 +#, c-format +msgid "Scanned %d directories ..." +msgstr "%d Ordner durchsucht..." + +#: gui/massadd.cpp:275 +#, c-format +msgid "Discovered %d new games, ignored %d previously added games ..." +msgstr "%d neue Spiele gefunden, %d bereits hinzugefügte Spiele ignoriert..." + +#: gui/onscreendialog.cpp:101 gui/onscreendialog.cpp:103 +msgid "Stop" +msgstr "Anhalten" + +#: gui/onscreendialog.cpp:106 +msgid "Edit record description" +msgstr "Aufnahme-Beschreibung ändern" + +#: gui/onscreendialog.cpp:108 +msgid "Switch to Game" +msgstr "Wechsle" + +#: gui/onscreendialog.cpp:110 +msgid "Fast replay" +msgstr "Schneller Modus" + +#: gui/options.cpp:122 common/updates.cpp:56 +msgid "Never" +msgstr "nie" + +#: gui/options.cpp:122 +msgid "Every 5 mins" +msgstr "Alle 5 Minuten" + +#: gui/options.cpp:122 +msgid "Every 10 mins" +msgstr "Alle 10 Minuten" + +#: gui/options.cpp:122 +msgid "Every 15 mins" +msgstr "Alle 15 Minuten" + +#: gui/options.cpp:122 +msgid "Every 30 mins" +msgstr "Alle 30 Minuten" + +#: gui/options.cpp:361 gui/options.cpp:691 gui/options.cpp:829 +#: gui/options.cpp:911 gui/options.cpp:1184 +msgctxt "soundfont" +msgid "None" +msgstr "Kein SoundFont" + +#: gui/options.cpp:552 +msgid "Failed to apply some of the graphic options changes:" +msgstr "Folgende Grafikoptionen konnten nicht geändert werden:" + +#: gui/options.cpp:564 +msgid "the video mode could not be changed" +msgstr "der Videomodus konnte nicht geändert werden" + +#: gui/options.cpp:577 +msgid "the stretch mode could not be changed" +msgstr "der Skaliermodus konnte nicht geändert werden" + +#: gui/options.cpp:583 +msgid "the aspect ratio setting could not be changed" +msgstr "Die Einstellung für das Seitenverhältnis konnte nicht geändert werden" + +#: gui/options.cpp:589 +msgid "the fullscreen setting could not be changed" +msgstr "Vollbildeinstellung konnte nicht geändert werden" + +#: gui/options.cpp:595 +msgid "the filtering setting could not be changed" +msgstr "Die Filtereinstellung konnte nicht geändert werden" + +#: gui/options.cpp:990 +msgid "Show On-screen control" +msgstr "Virtuelle Bedienelemente anzeigen" + +#: gui/options.cpp:994 +msgid "Touchpad mouse mode" +msgstr "Touchpad-Mausmodus" + +#: gui/options.cpp:998 +msgid "Swap Menu and Back buttons" +msgstr "Menü- und Zurück-Tasten vertauschen" + +#: gui/options.cpp:1003 +msgid "Pointer Speed:" +msgstr "Zeiger-Geschw.:" + +#: gui/options.cpp:1003 gui/options.cpp:1005 gui/options.cpp:1006 +msgid "Speed for keyboard/joystick mouse pointer control" +msgstr "Zeiger-Geschwindigkeit der Tastatur- bzw. Joystick-Maus" + +#: gui/options.cpp:1005 +msgctxt "lowres" +msgid "Pointer Speed:" +msgstr "Zeiger-Geschw.:" + +#: gui/options.cpp:1016 +msgid "Joy Deadzone:" +msgstr "Joystick-Totzone:" + +#: gui/options.cpp:1016 gui/options.cpp:1018 gui/options.cpp:1019 +msgid "Analog joystick Deadzone" +msgstr "Totzone des analogen Joysticks" + +#: gui/options.cpp:1018 +msgctxt "lowres" +msgid "Joy Deadzone:" +msgstr "Joystick-Totzone:" + +#: gui/options.cpp:1032 +msgid "HW Shader:" +msgstr "HW-Shader:" + +#: gui/options.cpp:1032 gui/options.cpp:1034 +msgid "Different hardware shaders give different visual effects" +msgstr "" +"Verschiedene Hardware-Shader erzeugen unterschiedliche visuelle Effekte" + +#: gui/options.cpp:1034 +msgctxt "lowres" +msgid "HW Shader:" +msgstr "HW-Shader:" + +#: gui/options.cpp:1035 +msgid "Different shaders give different visual effects" +msgstr "Verschiedene Shader erzeugen verschiedene Grafikeffekte" + +#: gui/options.cpp:1052 +msgid "Graphics mode:" +msgstr "Grafikmodus:" + +#: gui/options.cpp:1066 +msgid "Render mode:" +msgstr "Render-Modus:" + +#: gui/options.cpp:1066 gui/options.cpp:1067 +msgid "Special dithering modes supported by some games" +msgstr "Spezielle Dithering-Methoden unterstützt von manchen Spielen" + +#: gui/options.cpp:1079 +msgid "Stretch mode:" +msgstr "Skaliermodus:" + +#: gui/options.cpp:1090 +msgid "Fullscreen mode" +msgstr "Vollbildmodus" + +#: gui/options.cpp:1093 +msgid "Filter graphics" +msgstr "Bilineare Filterung" + +#: gui/options.cpp:1093 +msgid "Use linear filtering when scaling graphics" +msgstr "Verwende bilineare Filterung zur Grafik-Skalierung" + +#: gui/options.cpp:1096 +msgid "Aspect ratio correction" +msgstr "Seitenverhältnis korrigieren" + +#: gui/options.cpp:1096 +msgid "Correct aspect ratio for 320x200 games" +msgstr "Seitenverhältnis für Spiele mit der Auflösung 320x200 korrigieren" + +#: gui/options.cpp:1104 +msgid "Preferred device:" +msgstr "Bevorzugtes Gerät:" + +#: gui/options.cpp:1104 +msgid "Music device:" +msgstr "Musikgerät:" + +#: gui/options.cpp:1104 gui/options.cpp:1106 +msgid "Specifies preferred sound device or sound card emulator" +msgstr "" +"Legt das bevorzugte Audio-Wiedergabegerät oder den Soundkarten-Emulator fest" + +#: gui/options.cpp:1104 gui/options.cpp:1106 gui/options.cpp:1107 +msgid "Specifies output sound device or sound card emulator" +msgstr "Legt das Musikwiedergabe-Gerät oder den Soundkarten-Emulator fest" + +#: gui/options.cpp:1106 +msgctxt "lowres" +msgid "Preferred dev.:" +msgstr "Standard-Gerät:" + +#: gui/options.cpp:1106 +msgctxt "lowres" +msgid "Music device:" +msgstr "Musikgerät:" + +#: gui/options.cpp:1133 +msgid "AdLib emulator:" +msgstr "AdLib-Emulator:" + +#: gui/options.cpp:1133 gui/options.cpp:1134 +msgid "AdLib is used for music in many games" +msgstr "AdLib wird für die Musik in vielen Spielen verwendet" + +#: gui/options.cpp:1147 +msgid "GM device:" +msgstr "GM-Gerät:" + +#: gui/options.cpp:1147 +msgid "Specifies default sound device for General MIDI output" +msgstr "" +"Legt das standardmäßige Musikwiedergabe-Gerät für General-MIDI-Ausgabe fest" + +#: gui/options.cpp:1158 +msgid "Don't use General MIDI music" +msgstr "Keine General-MIDI-Musik" + +#: gui/options.cpp:1169 gui/options.cpp:1231 +msgid "Use first available device" +msgstr "Erstes verfügbares Gerät" + +#: gui/options.cpp:1181 +msgid "SoundFont:" +msgstr "SoundFont:" + +#: gui/options.cpp:1181 gui/options.cpp:1183 gui/options.cpp:1184 +msgid "SoundFont is supported by some audio cards, FluidSynth and Timidity" +msgstr "" +"SoundFont wird von einigen Soundkarten, FluidSynth und Timidity unterstützt" + +#: gui/options.cpp:1183 +msgctxt "lowres" +msgid "SoundFont:" +msgstr "SoundFont:" + +#: gui/options.cpp:1189 +msgid "Mixed AdLib/MIDI mode" +msgstr "Gemischter AdLib/MIDI-Modus" + +#: gui/options.cpp:1189 +msgid "Use both MIDI and AdLib sound generation" +msgstr "Kombiniert MIDI-Musik mit AdLib-Soundeffekten" + +#: gui/options.cpp:1192 +msgid "MIDI gain:" +msgstr "MIDI-Lautstärke:" + +#: gui/options.cpp:1202 +msgid "MT-32 Device:" +msgstr "MT-32-Gerät:" + +#: gui/options.cpp:1202 +msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output" +msgstr "" +"Legt das standardmäßige Audio-Wiedergabegerät für die Ausgabe von Roland " +"MT-32/LAPC1/CM32l/CM64 fest" + +#: gui/options.cpp:1207 +msgid "True Roland MT-32 (disable GM emulation)" +msgstr "Echte Roland MT-32 (GM-Emulation deaktiviert)" + +#: gui/options.cpp:1207 gui/options.cpp:1209 +msgid "" +"Check if you want to use your real hardware Roland-compatible sound device " +"connected to your computer" +msgstr "" +"Wählen Sie dies aus, wenn Sie ein echtes Roland-kompatibles Soundgerät " +"verwenden" + +#: gui/options.cpp:1209 +msgctxt "lowres" +msgid "True Roland MT-32 (no GM emulation)" +msgstr "Echte Roland MT-32 (keine GM-Emulation)" + +#: gui/options.cpp:1212 +msgid "Roland GS device (enable MT-32 mappings)" +msgstr "Roland-GS-Gerät (MT-32-Zuweisungen aktivieren)" + +#: gui/options.cpp:1212 +msgid "" +"Check if you want to enable patch mappings to emulate an MT-32 on a Roland " +"GS device" +msgstr "" +"Auswählen, wenn Sie ausbessernde Instrumentzuweisungen aktivieren möchten, " +"um MT-32 auf einem Roland-GS-Gerät zu emulieren" + +#: gui/options.cpp:1221 +msgid "Don't use Roland MT-32 music" +msgstr "Keine Roland-MT-32-Musik" + +#: gui/options.cpp:1248 +msgid "Text and speech:" +msgstr "Text und Sprache:" + +#: gui/options.cpp:1252 gui/options.cpp:1262 +msgid "Speech" +msgstr "Sprache" + +#: gui/options.cpp:1253 gui/options.cpp:1263 +msgid "Subtitles" +msgstr "Untertitel" + +#: gui/options.cpp:1254 +msgid "Both" +msgstr "Beides" + +#: gui/options.cpp:1256 +msgid "Subtitle speed:" +msgstr "Untertitel-Tempo:" + +#: gui/options.cpp:1258 +msgctxt "lowres" +msgid "Text and speech:" +msgstr "Text und Sprache:" + +#: gui/options.cpp:1262 +msgid "Spch" +msgstr "Spr." + +#: gui/options.cpp:1263 +msgid "Subs" +msgstr "Text" + +#: gui/options.cpp:1264 +msgctxt "lowres" +msgid "Both" +msgstr "S+T" + +#: gui/options.cpp:1264 +msgid "Show subtitles and play speech" +msgstr "Untertitel anzeigen und Sprachausgabe aktivieren" + +#: gui/options.cpp:1266 +msgctxt "lowres" +msgid "Subtitle speed:" +msgstr "Text-Tempo:" + +#: gui/options.cpp:1282 +msgid "Music volume:" +msgstr "Musiklautstärke:" + +#: gui/options.cpp:1284 +msgctxt "lowres" +msgid "Music volume:" +msgstr "Musiklautstärke:" + +#: gui/options.cpp:1291 +msgid "Mute all" +msgstr "Stumm" + +#: gui/options.cpp:1294 +msgid "SFX volume:" +msgstr "Effektlautstärke:" + +#: gui/options.cpp:1294 gui/options.cpp:1296 gui/options.cpp:1297 +msgid "Special sound effects volume" +msgstr "Lautstärke spezieller Geräusch-Effekte" + +#: gui/options.cpp:1296 +msgctxt "lowres" +msgid "SFX volume:" +msgstr "Effektlautst.:" + +#: gui/options.cpp:1304 +msgid "Speech volume:" +msgstr "Sprachlautstärke:" + +#: gui/options.cpp:1306 +msgctxt "lowres" +msgid "Speech volume:" +msgstr "Sprachlautst.:" + +#: gui/options.cpp:1536 +msgid "Shader" +msgstr "Shader" + +#: gui/options.cpp:1548 +msgid "Control" +msgstr "Steuerung" + +#: gui/options.cpp:1574 +msgid "FluidSynth Settings" +msgstr "FluidSynth-Einstellungen" + +#: gui/options.cpp:1605 +msgid "Theme Path:" +msgstr "Themes:" + +#: gui/options.cpp:1607 +msgctxt "lowres" +msgid "Theme Path:" +msgstr "Themes:" + +#: gui/options.cpp:1613 gui/options.cpp:1615 gui/options.cpp:1616 +msgid "Specifies path to additional data used by all games or ScummVM" +msgstr "" +"Legt das Verzeichnis für zusätzliche Spieldateien für alle Spiele in ScummVM " +"fest" + +#: gui/options.cpp:1622 +msgid "Plugins Path:" +msgstr "Plugins:" + +#: gui/options.cpp:1624 +msgctxt "lowres" +msgid "Plugins Path:" +msgstr "Plugins:" + +#: gui/options.cpp:1635 +msgctxt "lowres" +msgid "Misc" +msgstr "Andere" + +#: gui/options.cpp:1637 +msgid "Theme:" +msgstr "Theme:" + +#: gui/options.cpp:1641 +msgid "GUI renderer:" +msgstr "GUI-Renderer:" + +#: gui/options.cpp:1653 +msgid "Autosave:" +msgstr "Autom. Speichern:" + +#: gui/options.cpp:1655 +msgctxt "lowres" +msgid "Autosave:" +msgstr "Autospeichern:" + +#: gui/options.cpp:1663 +msgid "Keys" +msgstr "Tasten" + +#: gui/options.cpp:1670 +msgid "GUI language:" +msgstr "Sprache:" + +#: gui/options.cpp:1670 +msgid "Language of ScummVM GUI" +msgstr "Sprache der ScummVM-Oberfläche" + +#: gui/options.cpp:1696 +msgid "Switch the GUI language to the game language" +msgstr "Menüsprache auf Spielsprache einstellen" + +#: gui/options.cpp:1697 +msgid "" +"When starting a game, change the GUI language to the game language.That way, " +"if a game uses the ScummVM save and load dialogs, they are in the same " +"language as the game." +msgstr "" +"Die Sprache der Menüführung wird beim Starten des Spiels auf die Sprache des " +"Spiels gestellt. Damit ist sichergestellt, dass bei der Verwendung der " +"ScummVM-eigenen \"Speichern und Laden\"-Funktionalität gleiche Sprachen " +"verwendet werden." + +#: gui/options.cpp:1710 +msgid "Use native system file browser" +msgstr "Verwende betriebssystemeigenen Dateimanager" + +#: gui/options.cpp:1711 +msgid "" +"Use the native system file browser instead of the ScummVM one to select a " +"file or directory." +msgstr "" +"Verwende zur Auswahl einer Datei oder eines Verzeichnisses den " +"betriebssystemeigenen Dateimanager anstelle des ScummVM-eigenen Auswahlmenüs." + +#: gui/options.cpp:1718 gui/updates-dialog.cpp:86 +msgid "Update check:" +msgstr "Updates suchen:" + +#: gui/options.cpp:1718 +msgid "How often to check ScummVM updates" +msgstr "Wie oft nach Aktualisierungen von ScummVM suchen?" + +#: gui/options.cpp:1730 +msgid "Check now" +msgstr "Jetzt prüfen" + +#: gui/options.cpp:1738 +msgid "Cloud" +msgstr "Cloud" + +#: gui/options.cpp:1740 +msgctxt "lowres" +msgid "Cloud" +msgstr "Cloud" + +#: gui/options.cpp:1746 +msgid "Storage:" +msgstr "Cloud-Speicher:" + +#: gui/options.cpp:1746 +msgid "Active cloud storage" +msgstr "Aktiver Cloud-Speicher" + +#: gui/options.cpp:1753 gui/options.cpp:2336 +msgid "" +msgstr "" + +#: gui/options.cpp:1757 backends/platform/wii/options.cpp:114 +msgid "Username:" +msgstr "Benutzername:" + +#: gui/options.cpp:1757 +msgid "Username used by this storage" +msgstr "Benutzername, der von diesem Cloud-Speicher verwendet wird" + +#: gui/options.cpp:1760 +msgid "Used space:" +msgstr "Belegter Speicher:" + +#: gui/options.cpp:1760 +msgid "Space used by ScummVM's saved games on this storage" +msgstr "" +"Von ScummVM-Spielständen belegter Speicherplatz auf diesem Cloud-Speicher" + +#: gui/options.cpp:1763 +msgid "Last sync time:" +msgstr "Letzte Sync.:" + +#: gui/options.cpp:1763 +msgid "When the last saved games sync for this storage occured" +msgstr "Zeitpunkt der letzten Spielstand-Synchronisierung" + +#: gui/options.cpp:1766 gui/storagewizarddialog.cpp:71 +msgid "Connect" +msgstr "Verbinden" + +#: gui/options.cpp:1766 +msgid "Open wizard dialog to connect your cloud storage account" +msgstr "" +"Öffnet den Assistenten, der Sie durch die Einrichtung Ihres Cloud-Speichers " +"führt" + +#: gui/options.cpp:1767 +msgid "Refresh" +msgstr "Aktualisieren" + +#: gui/options.cpp:1767 +msgid "Refresh current cloud storage information (username and usage)" +msgstr "" +"Aktualisiert die Informationen über diesen Cloud-Speicher (Benutzername und " +"Belegung)" + +#: gui/options.cpp:1768 +msgid "Download" +msgstr "Herunterladen" + +#: gui/options.cpp:1768 +msgid "Open downloads manager dialog" +msgstr "Öffnet den Download-Manager" + +#: gui/options.cpp:1770 +msgid "Run server" +msgstr "Server starten" + +#: gui/options.cpp:1770 +msgid "Run local webserver" +msgstr "Startet den lokalen Webserver" + +#: gui/options.cpp:1771 gui/options.cpp:2446 +msgid "Not running" +msgstr "Nicht gestartet" + +#: gui/options.cpp:1775 +msgid "/root/ Path:" +msgstr "/root/-Pfad:" + +#: gui/options.cpp:1775 gui/options.cpp:1777 gui/options.cpp:1778 +msgid "Specifies which directory the Files Manager can access" +msgstr "Legt fest, auf welches Verzeichnis der Dateimanager zugreifen darf" + +#: gui/options.cpp:1777 +msgctxt "lowres" +msgid "/root/ Path:" +msgstr "/root/-Pfad:" + +#: gui/options.cpp:1787 +msgid "Server's port:" +msgstr "Server-Port:" + +#: gui/options.cpp:1787 +msgid "" +"Which port is used by the server\n" +"Auth with server is not available with non-default port" +msgstr "" +"Legt den Port für den Server fest.\n" +"Authentifizierung mit dem Server ist nicht verfügbar, wenn ein anderer Port " +"verwendet wird" + +#: gui/options.cpp:1800 +msgid "Apply" +msgstr "Übernehmen" + +#: gui/options.cpp:1943 +msgid "Failed to change cloud storage!" +msgstr "Konnte den Cloud-Speicher nicht ändern!" + +#: gui/options.cpp:1946 +msgid "Another cloud storage is already active." +msgstr "Ein anderer Cloud-Speicher arbeitet gerade." + +#: gui/options.cpp:2021 +msgid "Theme does not support selected language!" +msgstr "Das Theme unterstützt die gewählte Sprache nicht!" + +#: gui/options.cpp:2024 +msgid "Theme cannot be loaded!" +msgstr "Theme konnte nicht geladen werden!" + +#: gui/options.cpp:2027 +msgid "" +"\n" +"Misc settings will be restored." +msgstr "" +"\n" +"Verschiedene Einstellungen werden wiederhergestellt." + +#: gui/options.cpp:2063 +msgid "The chosen directory cannot be written to. Please select another one." +msgstr "" +"In das gewählte Verzeichnis kann nicht geschrieben werden. Bitte ein anderes " +"auswählen." + +#: gui/options.cpp:2072 +msgid "Select directory for GUI themes" +msgstr "Verzeichnis für Oberflächen-Themes" + +#: gui/options.cpp:2082 +msgid "Select directory for extra files" +msgstr "Verzeichnis für zusätzliche Dateien auswählen" + +#: gui/options.cpp:2093 +msgid "Select directory for plugins" +msgstr "Verzeichnis für Plugins auswählen" + +#: gui/options.cpp:2105 +msgid "Select directory for Files Manager /root/" +msgstr "" +"Wählen Sie das Verzeichnis aus, welches als Stammverzeichnis ('root') dient" + +#: gui/options.cpp:2343 +#, c-format +msgid "%llu bytes" +msgstr "%llu Bytes" + +#: gui/options.cpp:2351 +msgid "" +msgstr "" + +#: gui/options.cpp:2353 +msgid "" +msgstr "" + +#: gui/options.cpp:2437 +msgid "Stop server" +msgstr "Server anhalten" + +#: gui/options.cpp:2438 +msgid "Stop local webserver" +msgstr "Lokalen Webserver anhalten" + +#: gui/options.cpp:2529 +msgid "" +"Request failed.\n" +"Check your Internet connection." +msgstr "" +"Anfrage fehlgeschlagen.\n" +"Bitte überprüfen Sie Ihre Internetverbindung." + +#. I18N: You must leave "#" as is, only word 'next' is translatable +#: gui/predictivedialog.cpp:86 +msgid "# next" +msgstr "# nächste" + +#: gui/predictivedialog.cpp:87 +msgid "add" +msgstr "hinzufügen" + +#: gui/predictivedialog.cpp:92 gui/predictivedialog.cpp:167 +msgid "Delete char" +msgstr "Löschen" + +#: gui/predictivedialog.cpp:97 gui/predictivedialog.cpp:171 +msgid "<" +msgstr "<" + +#. I18N: Pre means 'Predictive', leave '*' as is +#: gui/predictivedialog.cpp:99 gui/predictivedialog.cpp:575 +msgid "* Pre" +msgstr "* Vorschau" + +#. I18N: 'Num' means Numbers +#: gui/predictivedialog.cpp:578 +msgid "* Num" +msgstr "* Zahlen" + +#. I18N: 'Abc' means Latin alphabet input +#: gui/predictivedialog.cpp:581 +msgid "* Abc" +msgstr "* ABC" + +#: gui/recorderdialog.cpp:63 +msgid "Recorder or Playback Gameplay" +msgstr "Spiel aufzeichnen/wiedergeben" + +#: gui/recorderdialog.cpp:68 gui/recorderdialog.cpp:155 +#: gui/saveload-dialog.cpp:393 gui/saveload-dialog.cpp:451 +msgid "Delete" +msgstr "Löschen" + +#: gui/recorderdialog.cpp:70 +msgid "Record" +msgstr "Aufnahme" + +#: gui/recorderdialog.cpp:71 +msgid "Playback" +msgstr "Wiedergabe" + +#: gui/recorderdialog.cpp:73 +msgid "Edit" +msgstr "Bearbeiten" + +#: gui/recorderdialog.cpp:85 gui/recorderdialog.cpp:241 +#: gui/recorderdialog.cpp:251 +msgid "Author: " +msgstr "Autor: " + +#: gui/recorderdialog.cpp:86 gui/recorderdialog.cpp:242 +#: gui/recorderdialog.cpp:252 +msgid "Notes: " +msgstr "Notizen: " + +#: gui/recorderdialog.cpp:154 +msgid "Do you really want to delete this record?" +msgstr "Möchten Sie diese Aufnahme wirklich löschen?" + +#: gui/recorderdialog.cpp:172 +msgid "Unknown Author" +msgstr "Unbekannter Autor" + +#: gui/remotebrowser.cpp:129 +msgid "ScummVM could not access the directory!" +msgstr "ScummVM konnte auf das gewählte Verzeichnis nicht zugreifen!" + +#: gui/saveload-dialog.cpp:340 +msgid "List view" +msgstr "Listenansicht" + +#: gui/saveload-dialog.cpp:341 +msgid "Grid view" +msgstr "Rasteransicht" + +#: gui/saveload-dialog.cpp:384 gui/saveload-dialog.cpp:551 +msgid "No date saved" +msgstr "Kein Datum gespeichert" + +#: gui/saveload-dialog.cpp:385 gui/saveload-dialog.cpp:552 +msgid "No time saved" +msgstr "Keine Zeit gespeichert" + +#: gui/saveload-dialog.cpp:386 gui/saveload-dialog.cpp:553 +msgid "No playtime saved" +msgstr "Keine Spielzeit gespeichert" + +#: gui/saveload-dialog.cpp:450 +msgid "Do you really want to delete this saved game?" +msgstr "Diesen Spielstand wirklich löschen?" + +#: gui/saveload-dialog.cpp:577 gui/saveload-dialog.cpp:1089 +msgid "Date: " +msgstr "Datum: " + +#: gui/saveload-dialog.cpp:581 gui/saveload-dialog.cpp:1095 +msgid "Time: " +msgstr "Zeit: " + +#: gui/saveload-dialog.cpp:587 gui/saveload-dialog.cpp:1103 +msgid "Playtime: " +msgstr "Spieldauer: " + +#: gui/saveload-dialog.cpp:600 gui/saveload-dialog.cpp:688 +msgid "Untitled saved game" +msgstr "Unbenannter Spielstand" + +#: gui/saveload-dialog.cpp:747 +msgid "Next" +msgstr "Vor" + +#: gui/saveload-dialog.cpp:750 +msgid "Prev" +msgstr "Zurück" + +#: gui/saveload-dialog.cpp:953 +msgid "New Save" +msgstr "Neuer Spielstand" + +#: gui/saveload-dialog.cpp:953 +msgid "Create a new saved game" +msgstr "Neuen Spielstand erstellen" + +#: gui/saveload-dialog.cpp:1082 +msgid "Name: " +msgstr "Name: " + +#: gui/saveload-dialog.cpp:1160 +#, c-format +msgid "Enter a description for slot %d:" +msgstr "Geben Sie eine Beschreibung für Speicherplatz %d ein:" + +#: gui/storagewizarddialog.cpp:55 +#, c-format +msgid "%s Storage Connection Wizard" +msgstr "Verbindungs-Assistent für %s" + +#: gui/storagewizarddialog.cpp:58 +msgid "Navigate to the following URL:" +msgstr "Rufen Sie folgende URL auf:" + +#: gui/storagewizarddialog.cpp:61 +msgid "Obtain the code from the storage, enter it" +msgstr "Geben Sie den Code Ihres Cloud-Speichers in das" + +#: gui/storagewizarddialog.cpp:62 +msgid "in the following field and press 'Connect':" +msgstr "folgende Feld ein und klicken Sie auf 'Verbinden':" + +#: gui/storagewizarddialog.cpp:69 +msgid "Open URL" +msgstr "URL öffnen" + +#: gui/storagewizarddialog.cpp:70 +msgid "Paste" +msgstr "Einfügen" + +#: gui/storagewizarddialog.cpp:70 +msgid "Pastes clipboard contents into fields" +msgstr "Fügt den Inhalt der Zwischenablage in die Felder ein" + +#: gui/storagewizarddialog.cpp:78 +msgid "You will be directed to ScummVM's page where" +msgstr "Sie werden zur Webseite von ScummVM weitergeleitet," + +#: gui/storagewizarddialog.cpp:79 +msgid "you should allow it to access your storage." +msgstr "wo Sie den Zugriff auf die Cloud erlauben sollten." + +#: gui/storagewizarddialog.cpp:112 +msgid "Another Storage is active. Do you want to interrupt it?" +msgstr "" +"Ein anderer Cloud-Speicher arbeitet gerade. Möchten Sie ihn unterbrechen?" + +#: gui/storagewizarddialog.cpp:121 +msgid "Wait until current Storage finishes up and try again." +msgstr "" +"Warten Sie, bis der Cloud-Speicher fertig ist und versuchen Sie es erneut." + +#: gui/storagewizarddialog.cpp:182 +#, c-format +msgid "Field %s has a mistake in it." +msgstr "Fehler in Feld %s." + +#: gui/storagewizarddialog.cpp:184 +#, c-format +msgid "Fields %s have mistakes in them." +msgstr "Die Felder %s enthalten fehlerhafte Eingaben." + +#: gui/storagewizarddialog.cpp:199 +msgid "All OK!" +msgstr "Alles OK!" + +#: gui/storagewizarddialog.cpp:201 +msgid "Invalid code" +msgstr "Code ungültig" + +#: gui/storagewizarddialog.cpp:209 +msgid "" +"Failed to open URL!\n" +"Please navigate to this page manually." +msgstr "" +"Fehler beim Öffnen der URL!\n" +"Sie sollten diese Seite manuell aufrufen." + +#: gui/themebrowser.cpp:45 +msgid "Select a Theme" +msgstr "Theme auswählen" + +#: gui/ThemeEngine.cpp:256 +msgid "Disabled GFX" +msgstr "GFX ausgeschaltet" + +#: gui/ThemeEngine.cpp:256 +msgctxt "lowres" +msgid "Disabled GFX" +msgstr "GFX ausgeschaltet" + +#: gui/ThemeEngine.cpp:257 +msgid "Standard renderer" +msgstr "Standard-Renderer" + +#: gui/ThemeEngine.cpp:257 engines/scumm/dialogs.cpp:660 +msgid "Standard" +msgstr "Standard" + +#: gui/ThemeEngine.cpp:259 +msgid "Antialiased renderer" +msgstr "Kantenglättung" + +#: gui/ThemeEngine.cpp:259 +msgid "Antialiased" +msgstr "Kantenglättung" + +#: gui/unknown-game-dialog.cpp:52 +msgid "Add anyway" +msgstr "Trotzdem hinzufügen" + +#: gui/unknown-game-dialog.cpp:59 +msgid "Copy to clipboard" +msgstr "In Zwischenablage kopieren" + +#: gui/unknown-game-dialog.cpp:65 +msgid "Report game" +msgstr "Spiel melden" + +#: gui/unknown-game-dialog.cpp:108 +msgid "" +"Use the button below to copy the required game information into your " +"clipboard." +msgstr "" +"Verwenden Sie den untenstehenden Button, um die benötigten Informationen in " +"die Zwischenablage zu kopieren." + +#: gui/unknown-game-dialog.cpp:113 +msgid "You can also directly report your game to the Bug Tracker." +msgstr "Sie können das Spiel auch direkt an unseren Bug-Tracker melden." + +#: gui/unknown-game-dialog.cpp:213 +msgid "" +"All necessary information about your game has been copied into the clipboard" +msgstr "Alle benötigten Informationen wurden in die Zwischenablage kopiert" + +#: gui/unknown-game-dialog.cpp:215 +msgid "Copying the game information to the clipboard has failed!" +msgstr "Kopieren der Spielinformationen in die Zwischenablage fehlgeschlagen!" + +#: gui/updates-dialog.cpp:49 +msgid "" +"ScummVM now supports automatic check for updates\n" +"which requires access to the Internet. Would you\n" +"like to enable this feature?" +msgstr "" +"ScummVM unterstützt die automatische Suche nach Aktualisierungen,\n" +"wozu ein Internetzugang erforderlich ist.\n" +"Möchten Sie diese Funktion aktivieren?" + +#: gui/updates-dialog.cpp:52 +msgid "" +"You can change this setting later in the Misc tab\n" +"in the Options dialog." +msgstr "" +"Sie können diese Einstellung später im Reiter \"Sonstiges\"\n" +"im Optionsfenster ändern." + +#: gui/updates-dialog.cpp:116 +msgid "Proceed" +msgstr "Fortfahren" + +#: gui/widget.cpp:356 gui/widget.cpp:358 gui/widget.cpp:364 gui/widget.cpp:366 +msgid "Clear value" +msgstr "Wert löschen" + +#: base/main.cpp:254 +#, c-format +msgid "Engine does not support debug level '%s'" +msgstr "Engine unterstützt den Debug-Level \"%s\" nicht" + +#: base/main.cpp:343 +msgid "Menu" +msgstr "Menü" + +#: base/main.cpp:346 backends/platform/symbian/src/SymbianActions.cpp:45 +#: backends/platform/wince/CEActionsPocket.cpp:45 +#: backends/platform/wince/CEActionsSmartphone.cpp:46 +msgid "Skip" +msgstr "Überspringen" + +#: base/main.cpp:349 backends/platform/symbian/src/SymbianActions.cpp:50 +#: backends/platform/wince/CEActionsPocket.cpp:42 +msgid "Pause" +msgstr "Pause" + +#: base/main.cpp:352 +msgid "Skip line" +msgstr "Zeile überspringen" + +#: base/main.cpp:563 +msgid "Error running game:" +msgstr "Fehler beim Ausführen des Spiels:" + +#: base/main.cpp:610 +msgid "Could not find any engine capable of running the selected game" +msgstr "Konnte keine Spiel-Engine finden, die dieses Spiel starten kann" + +#: common/error.cpp:38 +msgid "No error" +msgstr "Kein Fehler" + +#: common/error.cpp:40 +msgid "Game data not found" +msgstr "Spieldateien nicht gefunden" + +#: common/error.cpp:42 +msgid "Game id not supported" +msgstr "Spiel-ID nicht unterstützt" + +#: common/error.cpp:44 +msgid "Unsupported color mode" +msgstr "Farbmodus nicht unterstützt" + +#: common/error.cpp:46 +msgid "Audio device initialization failed" +msgstr "Initialisierung des Audio-Gerätes fehlgeschlagen" + +#: common/error.cpp:49 +msgid "Read permission denied" +msgstr "Lese-Berechtigung nicht vorhanden" + +#: common/error.cpp:51 +msgid "Write permission denied" +msgstr "Schreib-Berechtigung nicht vorhanden" + +#: common/error.cpp:54 +msgid "Path does not exist" +msgstr "Verzeichnis existiert nicht" + +#: common/error.cpp:56 +msgid "Path not a directory" +msgstr "Pfad ist kein Verzeichnis" + +#: common/error.cpp:58 +msgid "Path not a file" +msgstr "Pfad ist keine Datei" + +#: common/error.cpp:61 +msgid "Cannot create file" +msgstr "Kann Datei nicht erstellen" + +#: common/error.cpp:63 +msgid "Reading data failed" +msgstr "Daten konnten nicht gelesen werden" + +#: common/error.cpp:65 +msgid "Writing data failed" +msgstr "Daten konnten nicht geschrieben werden" + +#: common/error.cpp:68 +msgid "Could not find suitable engine plugin" +msgstr "Konnte kein passendes Engine-Plugin finden" + +#: common/error.cpp:70 +msgid "Engine plugin does not support saved games" +msgstr "Engine-Plugin unterstützt keine Spielstände" + +#: common/error.cpp:73 +msgid "User canceled" +msgstr "Abbruch durch Benutzer" + +#: common/error.cpp:77 +msgid "Unknown error" +msgstr "Unbekannter Fehler" + +#. I18N: Hercules is graphics card name +#: common/rendermode.cpp:35 +msgid "Hercules Green" +msgstr "Hercules-Grün" + +#: common/rendermode.cpp:36 +msgid "Hercules Amber" +msgstr "Hercules-Bernstein" + +#: common/rendermode.cpp:42 +msgid "PC-9821 (256 Colors)" +msgstr "PC-9821 (256 Farben)" + +#: common/rendermode.cpp:43 +msgid "PC-9801 (16 Colors)" +msgstr "PC-9801 (16 Farben)" + +#: common/rendermode.cpp:73 +msgctxt "lowres" +msgid "Hercules Green" +msgstr "Hercules-Grün" + +#: common/rendermode.cpp:74 +msgctxt "lowres" +msgid "Hercules Amber" +msgstr "Hercules-Bernst." + +#: common/updates.cpp:58 +msgid "Daily" +msgstr "Täglich" + +#: common/updates.cpp:60 +msgid "Weekly" +msgstr "Wöchentlich" + +#: common/updates.cpp:62 +msgid "Monthly" +msgstr "Monatlich" + +#: common/updates.cpp:64 +msgid "" +msgstr "" + +#: engines/dialogs.cpp:85 +msgid "~R~esume" +msgstr "~F~ortsetzen" + +#: engines/dialogs.cpp:87 engines/mohawk/dialogs.cpp:140 +msgid "~L~oad" +msgstr "~L~aden" + +#: engines/dialogs.cpp:91 engines/mohawk/dialogs.cpp:141 +msgid "~S~ave" +msgstr "~S~peichern" + +#: engines/dialogs.cpp:95 +msgid "~O~ptions" +msgstr "~O~ptionen" + +#: engines/dialogs.cpp:100 +msgid "~H~elp" +msgstr "~H~ilfe" + +#: engines/dialogs.cpp:102 +msgid "~A~bout" +msgstr "Übe~r~" + +#: engines/dialogs.cpp:105 engines/dialogs.cpp:181 +msgid "~R~eturn to Launcher" +msgstr "Zur Spiele~l~iste zurück" + +#: engines/dialogs.cpp:107 engines/dialogs.cpp:183 +msgctxt "lowres" +msgid "~R~eturn to Launcher" +msgstr "Zur Spiele~l~iste" + +#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761 +#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72 +#: engines/cge2/events.cpp:64 engines/cine/various.cpp:348 +#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199 +#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262 +#: engines/glk/streams.cpp:1408 engines/gnap/menu.cpp:464 +#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350 +#: engines/mohawk/dialogs.cpp:163 engines/mohawk/myst.cpp:954 +#: engines/mohawk/riven.cpp:685 engines/neverhood/menumodule.cpp:880 +#: engines/pegasus/pegasus.cpp:379 engines/sci/engine/guest_additions.cpp:675 +#: engines/sci/engine/kfile.cpp:1054 engines/sherlock/scalpel/scalpel.cpp:1250 +#: engines/sherlock/tattoo/widget_files.cpp:75 engines/startrek/saveload.cpp:42 +#: engines/toltecs/menu.cpp:291 engines/toon/toon.cpp:3340 +#: engines/tsage/scenes.cpp:599 engines/wage/saveload.cpp:758 +#: engines/zvision/file/save_manager.cpp:49 +msgid "Save game:" +msgstr "Speichern:" + +#: engines/dialogs.cpp:116 backends/platform/symbian/src/SymbianActions.cpp:44 +#: backends/platform/wince/CEActionsPocket.cpp:43 +#: backends/platform/wince/CEActionsPocket.cpp:267 +#: backends/platform/wince/CEActionsSmartphone.cpp:45 +#: backends/platform/wince/CEActionsSmartphone.cpp:231 +#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900 +#: engines/cge/events.cpp:72 engines/cge2/events.cpp:64 +#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212 +#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383 +#: engines/dreamweb/saveload.cpp:262 engines/glk/streams.cpp:1408 +#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298 +#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:163 +#: engines/mohawk/myst.cpp:954 engines/mohawk/riven.cpp:685 +#: engines/neverhood/menumodule.cpp:880 engines/parallaction/saveload.cpp:209 +#: engines/pegasus/pegasus.cpp:379 engines/sci/engine/guest_additions.cpp:676 +#: engines/sci/engine/kfile.cpp:1054 engines/scumm/dialogs.cpp:184 +#: engines/sherlock/scalpel/scalpel.cpp:1250 +#: engines/sherlock/tattoo/widget_files.cpp:75 engines/startrek/saveload.cpp:42 +#: engines/toltecs/menu.cpp:291 engines/toon/toon.cpp:3340 +#: engines/tsage/scenes.cpp:599 engines/wage/saveload.cpp:758 +#: engines/zvision/file/save_manager.cpp:49 +msgid "Save" +msgstr "Speichern" + +#: engines/dialogs.cpp:145 +msgid "" +"Sorry, this engine does not currently provide in-game help. Please consult " +"the README for basic information, and for instructions on how to obtain " +"further assistance." +msgstr "" +"Leider bietet diese Engine keine Spielhilfe. Bitte lesen Sie die LIESMICH-" +"Datei für grundlegende Informationen und Anweisungen zu weiterer Hilfe." + +#: engines/dialogs.cpp:234 engines/pegasus/pegasus.cpp:395 +#, c-format +msgid "" +"Failed to save game (%s)! Please consult the README for basic information, " +"and for instructions on how to obtain further assistance." +msgstr "" +"Speichern des Spielstands %s fehlgeschlagen! Bitte lesen Sie die LIESMICH-" +"Datei für grundlegende Informationen und Anweisungen zu weiterer Hilfe." + +#: engines/dialogs.cpp:307 engines/mohawk/dialogs.cpp:98 +#: engines/tsage/dialogs.cpp:112 +msgid "~O~K" +msgstr "~O~K" + +#: engines/dialogs.cpp:308 engines/mohawk/dialogs.cpp:99 +#: engines/tsage/dialogs.cpp:113 +msgid "~C~ancel" +msgstr "~A~bbrechen" + +#: engines/dialogs.cpp:311 +msgid "~K~eys" +msgstr "~T~asten" + +#: engines/engine.cpp:317 +msgid "Could not initialize color format." +msgstr "Konnte Farbenformat nicht initialisieren." + +#: engines/engine.cpp:325 +msgid "Could not switch to video mode: '" +msgstr "Konnte nicht zu Grafikmodus wechseln: \"" + +#: engines/engine.cpp:334 +msgid "Could not switch to stretch mode: '" +msgstr "Fehler beim Wechsel in Skaliermodus: '" + +#: engines/engine.cpp:343 +msgid "Could not apply aspect ratio setting." +msgstr "Konnte Einstellung für Seitenverhältniskorrektur nicht anwenden." + +#: engines/engine.cpp:348 +msgid "Could not apply fullscreen setting." +msgstr "Konnte Einstellung für Vollbildmodus nicht anwenden." + +#: engines/engine.cpp:353 +msgid "Could not apply filtering setting." +msgstr "Konnte Filtereinstellungen nicht anwenden." + +#: engines/engine.cpp:461 +msgid "" +"You appear to be playing this game directly\n" +"from the CD. This is known to cause problems,\n" +"and it is therefore recommended that you copy\n" +"the data files to your hard disk instead.\n" +"See the README file for details." +msgstr "" +"Sie scheinen dieses Spiel direkt von CD zu\n" +"spielen. Dies kann bekanntermaßen zu Problemen\n" +"führen und es wird deshalb empfohlen, die\n" +"Dateien des Spiels auf die Festplatte zu\n" +"kopieren und von dort aus zu spielen.\n" +"Lesen Sie die Liesmich-Datei für\n" +"weitere Informationen." + +#: engines/engine.cpp:472 +msgid "" +"This game has audio tracks in its disk. These\n" +"tracks need to be ripped from the disk using\n" +"an appropriate CD audio extracting tool in\n" +"order to listen to the game's music.\n" +"See the README file for details." +msgstr "" +"Dieses Spiel hat Audio-Titel auf seiner CD.\n" +"Diese Titel müssen von der CD mittels eines\n" +"geeigneten Extrahierungsprogramms für\n" +"Audio-CDs beschafft werden, um diese im\n" +"Spiel hören zu können. Lesen Sie die\n" +"Liesmich-Datei für weitere Informationen." + +#: engines/engine.cpp:530 +#, c-format +msgid "" +"Failed to load saved game (%s)! Please consult the README for basic " +"information, and for instructions on how to obtain further assistance." +msgstr "" +"Laden des Spielstands %s fehlgeschlagen! Bitte lesen Sie die LIESMICH-Datei " +"für grundlegende Informationen und Anweisungen zu weiterer Hilfe." + +#: engines/engine.cpp:543 +msgid "" +"WARNING: The game you are about to start is not yet fully supported by " +"ScummVM. As such, it is likely to be unstable, and any saved game you make " +"might not work in future versions of ScummVM." +msgstr "" +"WARNUNG: Das Spiel, welches Sie starten wollen, wird noch nicht vollständig " +"von ScummVM unterstützt. Somit ist es wahrscheinlich, dass es instabil ist " +"und jegliche Spielstände, die Sie erstellen, könnten in zukünftigen " +"Versionen von ScummVM nicht mehr funktionieren." + +#: engines/engine.cpp:546 engines/wintermute/wintermute.cpp:165 +msgid "Start anyway" +msgstr "Trotzdem starten" + +#: engines/game.cpp:166 +#, c-format +msgid "" +"The game in '%s' seems to be an unknown game variant.\n" +"\n" +"Please report the following data to the ScummVM team at %s along with the " +"name of the game you tried to add and its version, language, etc.:" +msgstr "" +"Das Spiel in '%s' scheint eine unbekannte Version zu sein.\n" +"\n" +"Bitte teilen Sie dem ScummVM-Team unter %s die folgenden Informationen " +"zusammen mit dem Namen, der Version und der Sprache des Spiels, welches Sie " +"hinzufügen möchten, mit:" + +#: engines/game.cpp:170 +#, c-format +msgid "Matched game IDs for the %s engine:" +msgstr "Übereinstimmende Spiele-IDs für die Engine %s:" + +#: audio/adlib.cpp:2290 +msgid "AdLib emulator" +msgstr "AdLib-Emulator" + +#: audio/fmopl.cpp:71 +msgid "MAME OPL emulator" +msgstr "MAME OPL-Emulator" + +#: audio/fmopl.cpp:73 +msgid "DOSBox OPL emulator" +msgstr "DOSBox OPL-Emulator" + +#: audio/fmopl.cpp:76 +msgid "Nuked OPL emulator" +msgstr "Nuked OPL-Emulator" + +#: audio/fmopl.cpp:79 +msgid "ALSA Direct FM" +msgstr "ALSA Direct FM" + +#: audio/fmopl.cpp:82 +msgid "OPL2LPT" +msgstr "OPL2LPT" + +#: audio/mididrv.cpp:209 +#, c-format +msgid "" +"The selected audio device '%s' was not found (e.g. might be turned off or " +"disconnected)." +msgstr "" +"Das ausgewählte Audiogerät \"%s\" wurde nicht gefunden (könnte " +"beispielsweise ausgeschaltet oder nicht angeschlossen sein)." + +#: audio/mididrv.cpp:209 audio/mididrv.cpp:221 audio/mididrv.cpp:257 +#: audio/mididrv.cpp:272 +msgid "Attempting to fall back to the next available device..." +msgstr "Es wird versucht, auf das nächste verfügbare Gerät zurückzugreifen." + +#: audio/mididrv.cpp:221 +#, c-format +msgid "" +"The selected audio device '%s' cannot be used. See log file for more " +"information." +msgstr "" +"Das ausgewählte Audiogerät \"%s\" kann nicht verwendet werden. Schauen Sie " +"für weitere Informationen in der Log-Datei nach." + +#: audio/mididrv.cpp:257 +#, c-format +msgid "" +"The preferred audio device '%s' was not found (e.g. might be turned off or " +"disconnected)." +msgstr "" +"Das bevorzugte Audiogerät \"%s\" wurde nicht gefunden (könnte beispielsweise " +"ausgeschaltet oder nicht angeschlossen sein)." + +#: audio/mididrv.cpp:272 +#, c-format +msgid "" +"The preferred audio device '%s' cannot be used. See log file for more " +"information." +msgstr "" +"Das bevorzugte Audiogerät \"%s\" kann nicht verwendet werden. Schauen Sie " +"für weitere Informationen in der Log-Datei nach." + +#: audio/mods/paula.cpp:303 +msgid "Amiga Audio emulator" +msgstr "Amiga-Audio-Emulator" + +#: audio/null.h:44 +msgid "No music" +msgstr "Keine Musik" + +#: audio/softsynth/appleiigs.cpp:33 +msgid "Apple II GS emulator (NOT IMPLEMENTED)" +msgstr "Apple II GS-Emulator (NICHT INTEGRIERT)" + +#: audio/softsynth/cms.cpp:350 +msgid "Creative Music System emulator" +msgstr "Creative Music System-Emulator" + +#: audio/softsynth/fmtowns_pc98/towns_pc98_plugins.cpp:33 +msgid "FM-Towns Audio" +msgstr "FM-Towns-Audio" + +#: audio/softsynth/fmtowns_pc98/towns_pc98_plugins.cpp:58 +msgid "PC-98 Audio" +msgstr "PC-98-Audio" + +#: audio/softsynth/mt32.cpp:175 +msgid "Initializing MT-32 Emulator" +msgstr "Initialisiere MT-32-Emulator" + +#: audio/softsynth/mt32.cpp:437 +msgid "MT-32 emulator" +msgstr "MT-32-Emulator" + +#: audio/softsynth/pcspk.cpp:139 +msgid "PC Speaker emulator" +msgstr "PC-Lautsprecher-Emulator" + +#: audio/softsynth/pcspk.cpp:158 +msgid "IBM PCjr emulator" +msgstr "IBM PCjr-Emulator" + +#: audio/softsynth/sid.cpp:1430 +msgid "C64 Audio emulator" +msgstr "C64-Audio-Emulator" + +#: backends/cloud/storage.cpp:211 +msgid "Saved games sync complete." +msgstr "Spielstände synchronisiert." + +#: backends/cloud/storage.cpp:222 +msgid "Saved games sync was cancelled." +msgstr "Spielstand-Synchronisierung abgebrochen." + +#: backends/cloud/storage.cpp:224 +msgid "" +"Saved games sync failed.\n" +"Check your Internet connection." +msgstr "" +"Spielstand-Synchronisierung fehlgeschlagen.\n" +"Überprüfen Sie Ihre Internetverbindung." + +#: backends/cloud/storage.cpp:328 +#, c-format +msgid "" +"Download complete.\n" +"Failed to download %u files." +msgstr "" +"Download abgeschlossen.\n" +"%u Dateien konnten nicht heruntergeladen werden." + +#: backends/cloud/storage.cpp:330 +msgid "Download complete." +msgstr "Download abgeschlossen." + +#: backends/cloud/storage.cpp:340 +msgid "Download failed." +msgstr "Download fehlgeschlagen." + +#: backends/events/default/default-events.cpp:190 +msgid "Do you really want to return to the Launcher?" +msgstr "Möchten Sie wirklich zur Spieleliste zurückkehren?" + +#: backends/events/default/default-events.cpp:190 +msgid "Launcher" +msgstr "Spieleliste" + +#: backends/events/default/default-events.cpp:212 +msgid "Do you really want to quit?" +msgstr "Möchten Sie wirklich beenden?" + +#: backends/events/default/default-events.cpp:212 +#: backends/platform/symbian/src/SymbianActions.cpp:52 +#: backends/platform/wince/CEActionsPocket.cpp:44 +#: backends/platform/wince/CEActionsSmartphone.cpp:52 +#: engines/mohawk/myst_stacks/menu.cpp:318 +#: engines/mohawk/riven_stacks/aspit.cpp:455 engines/scumm/dialogs.cpp:188 +#: engines/scumm/help.cpp:83 engines/scumm/help.cpp:85 +msgid "Quit" +msgstr "Beenden" + +#: backends/events/gph/gph-events.cpp:391 +#: backends/events/gph/gph-events.cpp:434 +#: backends/events/openpandora/op-events.cpp:174 +msgid "Touchscreen 'Tap Mode' - Left Click" +msgstr "Touchscreen-Tipp-Modus - Linksklick" + +#: backends/events/gph/gph-events.cpp:393 +#: backends/events/gph/gph-events.cpp:436 +#: backends/events/openpandora/op-events.cpp:176 +msgid "Touchscreen 'Tap Mode' - Right Click" +msgstr "Touchscreen-Tipp-Modus - Rechtsklick" + +#: backends/events/gph/gph-events.cpp:395 +#: backends/events/gph/gph-events.cpp:438 +#: backends/events/openpandora/op-events.cpp:178 +msgid "Touchscreen 'Tap Mode' - Hover (No Click)" +msgstr "Touchscreen-Tipp-Modus - schweben (kein Klick)" + +#: backends/events/gph/gph-events.cpp:415 +msgid "Maximum Volume" +msgstr "Höchste Lautstärke" + +#: backends/events/gph/gph-events.cpp:417 +msgid "Increasing Volume" +msgstr "Lautstärke höher" + +#: backends/events/gph/gph-events.cpp:423 +msgid "Minimal Volume" +msgstr "Niedrigste Lautstärke" + +#: backends/events/gph/gph-events.cpp:425 +msgid "Decreasing Volume" +msgstr "Lautstärke niedriger" + +#: backends/events/maemosdl/maemosdl-events.cpp:180 +msgid "Clicking Enabled" +msgstr "Klicken aktiviert" + +#: backends/events/maemosdl/maemosdl-events.cpp:180 +msgid "Clicking Disabled" +msgstr "Klicken deaktiviert" + +#: backends/events/openpandora/op-events.cpp:180 +msgid "Touchscreen 'Tap Mode' - Hover (DPad Clicks)" +msgstr "Touchscreen-Tipp-Modus - schweben (DPad-Klicks)" + +#: backends/events/symbiansdl/symbiansdl-events.cpp:191 +msgid "Do you want to quit ?" +msgstr "Möchten Sie beenden?" + +#. I18N: Trackpad mode toggle status. +#: backends/events/webossdl/webossdl-events.cpp:332 +msgid "Trackpad mode is now" +msgstr "Trackpad-Modus ist jetzt" + +#. I18N: Trackpad mode on or off. +#. I18N: Auto-drag on or off. +#: backends/events/webossdl/webossdl-events.cpp:335 +#: backends/events/webossdl/webossdl-events.cpp:362 +msgid "ON" +msgstr "AN" + +#: backends/events/webossdl/webossdl-events.cpp:335 +#: backends/events/webossdl/webossdl-events.cpp:362 +msgid "OFF" +msgstr "AUS" + +#: backends/events/webossdl/webossdl-events.cpp:339 +msgid "Swipe two fingers to the right to toggle." +msgstr "Zum Umschalten mit zwei Fingern nach rechts wischen." + +#. I18N: Auto-drag toggle status. +#: backends/events/webossdl/webossdl-events.cpp:359 +msgid "Auto-drag mode is now" +msgstr "Automatisches Ziehen ist jetzt" + +#: backends/events/webossdl/webossdl-events.cpp:366 +msgid "Swipe three fingers to the right to toggle." +msgstr "Zum Umschalten mit drei Fingern nach rechts wischen." + +#: backends/graphics/opengl/opengl-graphics.cpp:152 +msgid "OpenGL" +msgstr "OpenGL" + +#: backends/graphics/opengl/opengl-graphics.cpp:240 +#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:75 +msgid "Center" +msgstr "Zentriert" + +#: backends/graphics/opengl/opengl-graphics.cpp:241 +#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:76 +msgid "Pixel-perfect scaling" +msgstr "Pixelgenaue Skalierung" + +#: backends/graphics/opengl/opengl-graphics.cpp:242 +#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:77 +msgid "Fit to window" +msgstr "An Fenster anpassen" + +#: backends/graphics/opengl/opengl-graphics.cpp:243 +#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:78 +msgid "Stretch to window" +msgstr "Auf Fenstergröße strecken" + +#: backends/graphics/openglsdl/openglsdl-graphics.cpp:603 +#, c-format +msgid "Resolution: %dx%d" +msgstr "Auflösung: %dx%d" + +#: backends/graphics/openglsdl/openglsdl-graphics.cpp:624 +#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2511 +msgid "Enabled aspect ratio correction" +msgstr "Seitenverhältniskorrektur an" + +#: backends/graphics/openglsdl/openglsdl-graphics.cpp:626 +#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2517 +msgid "Disabled aspect ratio correction" +msgstr "Seitenverhältniskorrektur aus" + +#: backends/graphics/openglsdl/openglsdl-graphics.cpp:646 +#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2534 +msgid "Filtering enabled" +msgstr "Bilineare Filterung aktiviert" + +#: backends/graphics/openglsdl/openglsdl-graphics.cpp:648 +#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2536 +msgid "Filtering disabled" +msgstr "Bilineare Filterung deaktiviert" + +#: backends/graphics/openglsdl/openglsdl-graphics.cpp:676 +#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2565 +msgid "Stretch mode" +msgstr "Skaliermodus" + +#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:54 +#: backends/graphics/wincesdl/wincesdl-graphics.cpp:88 +#: backends/graphics/wincesdl/wincesdl-graphics.cpp:95 +msgid "Normal (no scaling)" +msgstr "Normal (keine Skalierung)" + +#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:83 +msgctxt "lowres" +msgid "Normal (no scaling)" +msgstr "Normal ohn.Skalieren" + +#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2627 +msgid "Active graphics filter:" +msgstr "Aktiver Grafikfilter:" + +#: backends/keymapper/remap-dialog.cpp:48 +msgid "Keymap:" +msgstr "Tasten-Layout:" + +#: backends/keymapper/remap-dialog.cpp:67 +msgid " (Effective)" +msgstr " (Aktuell)" + +#: backends/keymapper/remap-dialog.cpp:107 +msgid " (Active)" +msgstr " (Aktiv)" + +#: backends/keymapper/remap-dialog.cpp:107 +msgid " (Blocked)" +msgstr " (Blockiert)" + +#: backends/keymapper/remap-dialog.cpp:120 +msgid " (Global)" +msgstr " (Global)" + +#: backends/keymapper/remap-dialog.cpp:128 +msgid " (Game)" +msgstr " (Spiel)" + +#: backends/midi/windows.cpp:163 +msgid "Windows MIDI" +msgstr "Windows MIDI" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:56 +#: engines/scumm/dialogs.cpp:287 +msgid "~C~lose" +msgstr "~S~chließen" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:57 +msgid "ScummVM Main Menu" +msgstr "ScummVM-Hauptmenü" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:63 +msgid "~L~eft handed mode" +msgstr "~L~inke-Hand-Modus" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:64 +msgid "~I~ndy fight controls" +msgstr "~K~ampfsteuerung für Indiana Jones" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:65 +msgid "Show mouse cursor" +msgstr "Mauszeiger anzeigen" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:66 +msgid "Snap to edges" +msgstr "An Ecken anheften" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:68 +msgid "Touch X Offset" +msgstr "Zu X-Position gehen" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:75 +msgid "Touch Y Offset" +msgstr "Zu Y-Position gehen" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:87 +msgid "Use laptop trackpad-style cursor control" +msgstr "Den Trackpad-Modus für Maussteuerung benutzen" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:88 +msgid "Tap for left click, double tap right click" +msgstr "Tippen für Linksklick, Doppeltippen für Rechtsklick" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:90 +msgid "Sensitivity" +msgstr "Empfindlichkeit" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:99 +msgid "Initial top screen scale:" +msgstr "Vergrößerung des oberen Bildschirms:" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:105 +msgid "Main screen scaling:" +msgstr "Hauptbildschirm-Skalierung:" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:107 +msgid "Hardware scale (fast, but low quality)" +msgstr "Hardware-Skalierung (schnell, aber schlechte Qualität)" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:108 +msgid "Software scale (good quality, but slower)" +msgstr "Software-Skalierung (gute Qualität, aber langsamer)" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:109 +msgid "Unscaled (you must scroll left and right)" +msgstr "Nicht skalieren (Sie müssen nach links und nach rechts scrollen)" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:111 +msgid "Brightness:" +msgstr "Helligkeit:" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:121 +msgid "High quality audio (slower) (reboot)" +msgstr "Hohe Audioqualität (langsamer) (erfordert Neustart)" + +#: backends/platform/ds/arm9/source/dsoptions.cpp:122 +msgid "Disable power off" +msgstr "Stromsparmodus abschalten" + +#: backends/platform/ios7/ios7_osys_events.cpp:309 +#: backends/platform/ios7/ios7_osys_events.cpp:519 +#: backends/platform/iphone/osys_events.cpp:300 +msgid "Mouse-click-and-drag mode enabled." +msgstr "Maus-klick-und-zieh-Modus aktiviert." + +#: backends/platform/ios7/ios7_osys_events.cpp:311 +#: backends/platform/ios7/ios7_osys_events.cpp:521 +#: backends/platform/iphone/osys_events.cpp:302 +msgid "Mouse-click-and-drag mode disabled." +msgstr "Maus-klick-und-zieh-Modus ausgeschaltet." + +#: backends/platform/ios7/ios7_osys_events.cpp:322 +#: backends/platform/ios7/ios7_osys_events.cpp:540 +#: backends/platform/iphone/osys_events.cpp:313 +msgid "Touchpad mode enabled." +msgstr "Touchpad-Modus aktiviert." + +#: backends/platform/ios7/ios7_osys_events.cpp:324 +#: backends/platform/ios7/ios7_osys_events.cpp:542 +#: backends/platform/iphone/osys_events.cpp:315 +msgid "Touchpad mode disabled." +msgstr "Touchpad-Modus ausgeschaltet." + +#: backends/platform/maemo/maemo.cpp:206 +msgid "Click Mode" +msgstr "Klickmodus" + +#: backends/platform/maemo/maemo.cpp:212 +#: backends/platform/symbian/src/SymbianActions.cpp:42 +#: backends/platform/tizen/form.cpp:274 +#: backends/platform/wince/CEActionsPocket.cpp:60 +#: backends/platform/wince/CEActionsSmartphone.cpp:43 +msgid "Left Click" +msgstr "Linksklick" + +#: backends/platform/maemo/maemo.cpp:215 +msgid "Middle Click" +msgstr "Mittelklick" + +#: backends/platform/maemo/maemo.cpp:218 +#: backends/platform/symbian/src/SymbianActions.cpp:43 +#: backends/platform/tizen/form.cpp:266 +#: backends/platform/wince/CEActionsSmartphone.cpp:44 +msgid "Right Click" +msgstr "Rechtsklick" + +#: backends/platform/sdl/macosx/appmenu_osx.mm:205 +msgid "Hide ScummVM" +msgstr "ScummVM ausblenden" + +#: backends/platform/sdl/macosx/appmenu_osx.mm:206 +msgid "Hide Others" +msgstr "Andere ausblenden" + +#: backends/platform/sdl/macosx/appmenu_osx.mm:207 +msgid "Show All" +msgstr "Alle einblenden" + +#: backends/platform/sdl/macosx/appmenu_osx.mm:211 +msgid "Window" +msgstr "Fenster" + +#: backends/platform/sdl/macosx/appmenu_osx.mm:212 +msgid "Minimize" +msgstr "Minimieren" + +#: backends/platform/sdl/macosx/appmenu_osx.mm:214 +msgid "Help" +msgstr "Hilfe" + +#: backends/platform/sdl/macosx/appmenu_osx.mm:215 +msgid "User Manual" +msgstr "Benutzer-Handbuch" + +#: backends/platform/sdl/macosx/appmenu_osx.mm:217 +msgid "General Information" +msgstr "Allgemeine Informationen" + +#: backends/platform/sdl/macosx/appmenu_osx.mm:218 +msgid "What's New in ScummVM" +msgstr "Neues in ScummVM" + +#: backends/platform/sdl/macosx/appmenu_osx.mm:220 +msgid "Credits" +msgstr "Mitwirkende" + +#: backends/platform/sdl/macosx/appmenu_osx.mm:221 +msgid "GPL License" +msgstr "GPL-Lizenz" + +#: backends/platform/sdl/macosx/appmenu_osx.mm:222 +msgid "LGPL License" +msgstr "LGPL-Lizenz" + +#: backends/platform/sdl/macosx/appmenu_osx.mm:223 +msgid "Freefont License" +msgstr "Freefont-Lizenz" + +#: backends/platform/sdl/macosx/appmenu_osx.mm:224 +msgid "OFL License" +msgstr "OFL-Lizenz" + +#: backends/platform/sdl/macosx/appmenu_osx.mm:225 +msgid "BSD License" +msgstr "BSD-Lizenz" + +#: backends/platform/symbian/src/SymbianActions.cpp:38 +#: backends/platform/wince/CEActionsSmartphone.cpp:39 +#: engines/glk/scott/scott.cpp:394 +msgid "Up" +msgstr "Hoch" + +#: backends/platform/symbian/src/SymbianActions.cpp:39 +#: backends/platform/wince/CEActionsSmartphone.cpp:40 +#: engines/glk/scott/scott.cpp:394 +msgid "Down" +msgstr "Runter" + +#: backends/platform/symbian/src/SymbianActions.cpp:40 +#: backends/platform/wince/CEActionsSmartphone.cpp:41 +msgid "Left" +msgstr "Links" + +#: backends/platform/symbian/src/SymbianActions.cpp:41 +#: backends/platform/wince/CEActionsSmartphone.cpp:42 +msgid "Right" +msgstr "Rechts" + +#: backends/platform/symbian/src/SymbianActions.cpp:46 +#: backends/platform/wince/CEActionsSmartphone.cpp:47 +msgid "Zone" +msgstr "Zone" + +#: backends/platform/symbian/src/SymbianActions.cpp:47 +#: backends/platform/wince/CEActionsPocket.cpp:54 +#: backends/platform/wince/CEActionsSmartphone.cpp:48 +msgid "Multi Function" +msgstr "Multifunktion" + +#: backends/platform/symbian/src/SymbianActions.cpp:48 +msgid "Swap character" +msgstr "Figur wechseln" + +#: backends/platform/symbian/src/SymbianActions.cpp:49 +msgid "Skip text" +msgstr "Text überspringen" + +#: backends/platform/symbian/src/SymbianActions.cpp:51 +msgid "Fast mode" +msgstr "Schneller Modus" + +#: backends/platform/symbian/src/SymbianActions.cpp:53 +msgid "Debugger" +msgstr "Debugger" + +#: backends/platform/symbian/src/SymbianActions.cpp:54 +msgid "Global menu" +msgstr "Hauptmenü" + +#: backends/platform/symbian/src/SymbianActions.cpp:55 +msgid "Virtual keyboard" +msgstr "Virtuelle Tastatur" + +#: backends/platform/symbian/src/SymbianActions.cpp:56 +msgid "Key mapper" +msgstr "Tasten zuordnen" + +#: backends/platform/tizen/form.cpp:262 +msgid "Right Click Once" +msgstr "Einmal Rechtsklick" + +#: backends/platform/tizen/form.cpp:270 +msgid "Move Only" +msgstr "Nur bewegen" + +#: backends/platform/tizen/form.cpp:293 +msgid "Escape Key" +msgstr "Escape-Taste" + +#: backends/platform/tizen/form.cpp:298 +msgid "Game Menu" +msgstr "Spielmenü" + +#: backends/platform/tizen/form.cpp:303 +msgid "Show Keypad" +msgstr "Ziffernblock zeigen" + +#: backends/platform/tizen/form.cpp:308 +msgid "Control Mouse" +msgstr "Maus steuern" + +#: backends/platform/tizen/fs.cpp:259 +msgid "[ Data ]" +msgstr "[ Daten ]" + +#: backends/platform/tizen/fs.cpp:263 +msgid "[ Resources ]" +msgstr "[ Ressourcen ]" + +#: backends/platform/tizen/fs.cpp:267 +msgid "[ SDCard ]" +msgstr "[ SD-Karte ]" + +#: backends/platform/tizen/fs.cpp:271 +msgid "[ Media ]" +msgstr "[ Datenträger ]" + +#: backends/platform/tizen/fs.cpp:275 +msgid "[ Shared ]" +msgstr "[ Öffentlich ]" + +#: backends/platform/wii/options.cpp:51 +msgid "Video" +msgstr "Video" + +#: backends/platform/wii/options.cpp:54 +msgid "Current video mode:" +msgstr "Aktueller Grafikmodus:" + +#: backends/platform/wii/options.cpp:56 +msgid "Double-strike" +msgstr "Doppelzeilen (kein Zeilensprungverfahren)" + +#: backends/platform/wii/options.cpp:60 +msgid "Horizontal underscan:" +msgstr "Horizontale Bildverkleinerung:" + +#: backends/platform/wii/options.cpp:66 +msgid "Vertical underscan:" +msgstr "Vertikale Bildverkleinerung:" + +#: backends/platform/wii/options.cpp:71 +msgid "Input" +msgstr "Eingabe" + +#: backends/platform/wii/options.cpp:74 +msgid "GC Pad sensitivity:" +msgstr "GC-Pad-Empfindlichkeit:" + +#: backends/platform/wii/options.cpp:80 +msgid "GC Pad acceleration:" +msgstr "GC-Pad-Beschleunigung:" + +#: backends/platform/wii/options.cpp:86 +msgid "DVD" +msgstr "DVD" + +#: backends/platform/wii/options.cpp:89 backends/platform/wii/options.cpp:101 +msgid "Status:" +msgstr "Status:" + +#: backends/platform/wii/options.cpp:90 backends/platform/wii/options.cpp:102 +msgid "Unknown" +msgstr "Unbekannt" + +#: backends/platform/wii/options.cpp:93 +msgid "Mount DVD" +msgstr "DVD einbinden" + +#: backends/platform/wii/options.cpp:94 +msgid "Unmount DVD" +msgstr "DVD aushängen" + +#: backends/platform/wii/options.cpp:98 +msgid "SMB" +msgstr "SMB" + +#: backends/platform/wii/options.cpp:106 +msgid "Server:" +msgstr "Server:" + +#: backends/platform/wii/options.cpp:110 +msgid "Share:" +msgstr "Öffentliches Verzeichnis:" + +#: backends/platform/wii/options.cpp:118 +msgid "Password:" +msgstr "Passwort:" + +#: backends/platform/wii/options.cpp:121 +msgid "Init network" +msgstr "Netzwerk starten" + +#: backends/platform/wii/options.cpp:123 +msgid "Mount SMB" +msgstr "SMB einbinden" + +#: backends/platform/wii/options.cpp:124 +msgid "Unmount SMB" +msgstr "SMB aushängen" + +#: backends/platform/wii/options.cpp:143 +msgid "DVD Mounted successfully" +msgstr "DVD erfolgreich eingebunden" + +#: backends/platform/wii/options.cpp:146 +msgid "Error while mounting the DVD" +msgstr "Fehler beim Einbinden der DVD" + +#: backends/platform/wii/options.cpp:148 +msgid "DVD not mounted" +msgstr "DVD nicht eingebunden" + +#: backends/platform/wii/options.cpp:161 +msgid "Network up, share mounted" +msgstr "Netzwerk gestartet, öffentliches Verzeichnis eingebunden" + +#: backends/platform/wii/options.cpp:163 +msgid "Network up" +msgstr "Netzwerk gestartet" + +#: backends/platform/wii/options.cpp:166 +msgid ", error while mounting the share" +msgstr ", Fehler beim Einbinden des öffentlichen Verzeichnisses" + +#: backends/platform/wii/options.cpp:168 +msgid ", share not mounted" +msgstr ", öffentliches Verzeichnis nicht eingebunden" + +#: backends/platform/wii/options.cpp:174 +msgid "Network down" +msgstr "Netzwerk ist nicht verfügbar" + +#: backends/platform/wii/options.cpp:178 +msgid "Initializing network" +msgstr "Netzwerk wird gestartet" + +#: backends/platform/wii/options.cpp:182 +msgid "Timeout while initializing network" +msgstr "Zeitüberschreitung beim Starten des Netzwerks" + +#: backends/platform/wii/options.cpp:186 +#, c-format +msgid "Network not initialized (%d)" +msgstr "Netzwerk nicht gestartet (%d)" + +#: backends/platform/wince/CEActionsPocket.cpp:46 +msgid "Hide Toolbar" +msgstr "Werkzeugleiste verbergen" + +#: backends/platform/wince/CEActionsPocket.cpp:47 +msgid "Show Keyboard" +msgstr "Tastatur zeigen" + +#: backends/platform/wince/CEActionsPocket.cpp:48 +msgid "Sound on/off" +msgstr "Ton ein/aus" + +#: backends/platform/wince/CEActionsPocket.cpp:49 +msgid "Right click" +msgstr "Rechtsklick" + +#: backends/platform/wince/CEActionsPocket.cpp:50 +msgid "Show/Hide Cursor" +msgstr "Cursor zeigen/verbergen" + +#: backends/platform/wince/CEActionsPocket.cpp:51 +msgid "Free look" +msgstr "Freie Ansicht" + +#: backends/platform/wince/CEActionsPocket.cpp:52 +msgid "Zoom up" +msgstr "Herauszoomen" + +#: backends/platform/wince/CEActionsPocket.cpp:53 +msgid "Zoom down" +msgstr "Hineinzoomen" + +#: backends/platform/wince/CEActionsPocket.cpp:55 +#: backends/platform/wince/CEActionsSmartphone.cpp:49 +msgid "Bind Keys" +msgstr "Tasten zuweisen" + +#: backends/platform/wince/CEActionsPocket.cpp:56 +msgid "Cursor Up" +msgstr "Zeiger hoch" + +#: backends/platform/wince/CEActionsPocket.cpp:57 +msgid "Cursor Down" +msgstr "Zeiger runter" + +#: backends/platform/wince/CEActionsPocket.cpp:58 +msgid "Cursor Left" +msgstr "Zeiger nach links" + +#: backends/platform/wince/CEActionsPocket.cpp:59 +msgid "Cursor Right" +msgstr "Zeiger nach rechts" + +#: backends/platform/wince/CEActionsPocket.cpp:267 +#: backends/platform/wince/CEActionsSmartphone.cpp:231 +msgid "Do you want to load or save the game?" +msgstr "Möchten Sie ein Spiel laden oder speichern?" + +#: backends/platform/wince/CEActionsPocket.cpp:326 +#: backends/platform/wince/CEActionsSmartphone.cpp:287 +msgid " Are you sure you want to quit ? " +msgstr " Möchten Sie wirklich beenden? " + +#: backends/platform/wince/CEActionsSmartphone.cpp:50 +msgid "Keyboard" +msgstr "Tastatur" + +#: backends/platform/wince/CEActionsSmartphone.cpp:51 +msgid "Rotate" +msgstr "Drehen" + +#: backends/platform/wince/CELauncherDialog.cpp:56 +msgid "Using SDL driver " +msgstr "Verwende SDL-Treiber " + +#: backends/platform/wince/CELauncherDialog.cpp:60 +msgid "Display " +msgstr "Anzeige " + +#: backends/platform/wince/CELauncherDialog.cpp:83 +msgid "Do you want to perform an automatic scan ?" +msgstr "Möchten Sie eine automatische Suche durchführen?" + +#: backends/platform/wince/wince-sdl.cpp:518 +msgid "Map right click action" +msgstr "Aktion \"Rechtsklick\" zuweisen" + +#: backends/platform/wince/wince-sdl.cpp:522 +msgid "You must map a key to the 'Right Click' action to play this game" +msgstr "" +"Sie müssen der Aktion \"Rechtsklick\" eine Taste zuweisen, um dieses Spiel " +"spielen zu können" + +#: backends/platform/wince/wince-sdl.cpp:531 +msgid "Map hide toolbar action" +msgstr "Aktion \"Werkzeugleiste verbergen\" zuweisen" + +#: backends/platform/wince/wince-sdl.cpp:535 +msgid "You must map a key to the 'Hide toolbar' action to play this game" +msgstr "" +"Sie müssen der Aktion \"Werkzeugleiste verbergen\" eine Taste zuweisen, um " +"dieses Spiel spielen zu können" + +#: backends/platform/wince/wince-sdl.cpp:544 +msgid "Map Zoom Up action (optional)" +msgstr "Aktion \"Herauszoomen\" zuweisen (optional)" + +#: backends/platform/wince/wince-sdl.cpp:547 +msgid "Map Zoom Down action (optional)" +msgstr "Aktion \"Hineinzoomen\" zuweisen (optional)" + +#: backends/platform/wince/wince-sdl.cpp:555 +msgid "" +"Don't forget to map a key to 'Hide Toolbar' action to see the whole inventory" +msgstr "" +"Vergessen Sie nicht, der Aktion \"Werkzeugleiste verbergen\" eine Taste " +"zuzuweisen, um das ganze Inventar sehen zu können" + +#: backends/updates/macosx/macosx-updates.mm:79 +msgid "Check for Updates..." +msgstr "Suche nach Aktualisierungen..." + +#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:971 +#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64 +#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131 +#: engines/supernova/supernova.cpp:178 engines/teenagent/resources.cpp:97 +#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4926 +#, c-format +msgid "Unable to locate the '%s' engine data file." +msgstr "Engine-Datendatei '%s' kann nicht gefunden werden." + +#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:985 +#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73 +#: engines/mortevielle/mortevielle.cpp:314 engines/supernova/supernova.cpp:187 +#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4938 +#, c-format +msgid "The '%s' engine data file is corrupt." +msgstr "Die Engine-Datendatei '%s' ist beschädigt." + +#: engines/access/resources.cpp:61 engines/drascula/drascula.cpp:996 +#: engines/hugo/hugo.cpp:458 engines/lure/lure.cpp:76 +#: engines/mortevielle/mortevielle.cpp:324 engines/tony/tony.cpp:221 +#: engines/toon/toon.cpp:4949 +#, c-format +msgid "" +"Incorrect version of the '%s' engine data file found. Expected %d.%d but got " +"%d.%d." +msgstr "" +"Falsche Version der Engine-Datendatei '%s' gefunden. %d.%d erwartet, aber %d." +"%d bekommen." + +#: engines/adl/detection.cpp:49 engines/adl/detection.cpp:59 +msgid "Color mode" +msgstr "Farbmodus einschalten" + +#: engines/adl/detection.cpp:50 engines/adl/detection.cpp:60 +msgid "Use color graphics" +msgstr "Farbgrafik verwenden" + +#: engines/adl/detection.cpp:69 +msgid "Scanlines" +msgstr "Abtastzeilen/Scanlines" + +#: engines/adl/detection.cpp:70 +msgid "Show scanlines" +msgstr "Abtastzeilen (Scanlines) anzeigen" + +#: engines/agi/detection.cpp:147 engines/cine/detection.cpp:70 +#: engines/drascula/detection.cpp:331 engines/dreamweb/detection.cpp:48 +#: engines/neverhood/detection.cpp:177 engines/sci/detection.cpp:458 +#: engines/sherlock/detection.cpp:71 engines/toltecs/detection.cpp:200 +#: engines/zvision/detection_tables.h:51 +msgid "Use original save/load screens" +msgstr "Originale Spielstand-Menüs" + +#: engines/agi/detection.cpp:148 engines/cine/detection.cpp:71 +#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49 +#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:459 +#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201 +#: engines/zvision/detection_tables.h:52 +msgid "Use the original save/load screens instead of the ScummVM ones" +msgstr "" +"Verwende die originalen Speicher- und Lade-Menüs statt der Menüs von ScummVM" + +#: engines/agi/detection.cpp:157 +msgid "Use an alternative palette" +msgstr "Alternative Farbpalette verwenden" + +#: engines/agi/detection.cpp:158 +msgid "" +"Use an alternative palette, common for all Amiga games. This was the old " +"behavior" +msgstr "" +"Verwende eine alternative Farbpalette für alle Amiga-Spiele. Dies war das " +"alte Verhalten" + +#: engines/agi/detection.cpp:167 +msgid "Mouse support" +msgstr "Maus-Unterstützung" + +#: engines/agi/detection.cpp:168 +msgid "" +"Enables mouse support. Allows to use mouse for movement and in game menus." +msgstr "" +"Aktiviere Maus-Unterstützung. Erlaubt die Verwendung der Maus zur Bewegung " +"und in Menüs innerhalb des Spiels." + +#: engines/agi/detection.cpp:177 +msgid "Use Hercules hires font" +msgstr "Verwende hochauflösende Hercules-Schrift" + +#: engines/agi/detection.cpp:178 +msgid "Uses Hercules hires font, when font file is available." +msgstr "" +"Verwende hochauflösende Hercules-Schriftart, wenn die Schriftarten-Datei " +"verfügbar ist." + +#: engines/agi/detection.cpp:187 +msgid "Pause when entering commands" +msgstr "Pausiere, wenn Befehle eingegeben werden" + +#: engines/agi/detection.cpp:188 +msgid "" +"Shows a command prompt window and pauses the game (like in SCI) instead of a " +"real-time prompt." +msgstr "" +"Zeige ein Fenster mit einer Kommandozeile und pausiere das Spiel (wie in " +"SCI) anstelle einer Eingabe in Echtzeit." + +#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888 +#: engines/cge/events.cpp:83 engines/cge2/events.cpp:75 +#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276 +#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396 +#: engines/dreamweb/saveload.cpp:170 engines/glk/streams.cpp:1417 +#: engines/gnap/menu.cpp:473 engines/hugo/file.cpp:400 +#: engines/mads/nebular/dialogs_nebular.cpp:377 +#: engines/neverhood/menumodule.cpp:893 +#: engines/sci/engine/guest_additions.cpp:678 engines/sci/engine/kfile.cpp:1173 +#: engines/sherlock/scalpel/scalpel.cpp:1263 +#: engines/sherlock/tattoo/widget_files.cpp:94 engines/startrek/saveload.cpp:67 +#: engines/toltecs/menu.cpp:266 engines/toon/toon.cpp:3434 +#: engines/zvision/file/save_manager.cpp:62 +msgid "Restore game:" +msgstr "Spiel laden:" + +#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888 +#: engines/cge/events.cpp:83 engines/cge2/events.cpp:75 +#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276 +#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396 +#: engines/dreamweb/saveload.cpp:170 engines/glk/streams.cpp:1417 +#: engines/gnap/menu.cpp:473 engines/hugo/file.cpp:400 +#: engines/mads/nebular/dialogs_nebular.cpp:377 +#: engines/neverhood/menumodule.cpp:893 +#: engines/sci/engine/guest_additions.cpp:679 engines/sci/engine/kfile.cpp:1173 +#: engines/sherlock/scalpel/scalpel.cpp:1263 +#: engines/sherlock/tattoo/widget_files.cpp:94 engines/startrek/saveload.cpp:67 +#: engines/toltecs/menu.cpp:266 engines/toon/toon.cpp:3434 +#: engines/zvision/file/save_manager.cpp:62 +msgid "Restore" +msgstr "Laden" + +#: engines/agos/saveload.cpp:159 engines/scumm/scumm.cpp:2446 +#, c-format +msgid "" +"Failed to load saved game from file:\n" +"\n" +"%s" +msgstr "" +"Konnte Spielstand nicht aus folgender Datei laden:\n" +"\n" +"%s" + +#: engines/agos/saveload.cpp:194 engines/scumm/scumm.cpp:2436 +#, c-format +msgid "" +"Failed to save game to file:\n" +"\n" +"%s" +msgstr "" +"Konnte Spielstand nicht in folgender Datei speichern:\n" +"\n" +"%s" + +#: engines/agos/saveload.cpp:202 engines/scumm/scumm.cpp:2457 +#, c-format +msgid "" +"Successfully saved game in file:\n" +"\n" +"%s" +msgstr "" +"Spielstand erfolgreich in folgender Datei gespeichert:\n" +"\n" +"%s" + +#: engines/agos/animation.cpp:558 +#, c-format +msgid "Cutscene file '%s' not found!" +msgstr "Zwischensequenz \"%s\" nicht gefunden!" + +#: engines/bladerunner/bladerunner.cpp:322 +msgid "Failed to initialize resources" +msgstr "Konnte Ressourcen nicht initialisieren" + +#: engines/bladerunner/bladerunner.cpp:908 +msgid "A required game resource was not found" +msgstr "Eine benötigte Spiel-Ressource konnte nicht gefunden werden" + +#: engines/bladerunner/bladerunner.cpp:2039 +msgid "" +"WARNING: This game was saved in Restored Cut Content mode, but you are " +"playing in Original Content mode. The mode will be adjusted to Restored Cut " +"Content for this session until you completely Quit the game." +msgstr "" +"WARNUNG: Dieses Spiel wurde im \"Entfernte Inhalte wiederherstellen\"-Modus " +"gespeichert. Sie spielen das Spiel jedoch im \"Original-Inhalte\"-Modus. Der " +"Modus wird für diese Spielesitzung auf \"Entfernte Inhalte wiederherstellen" +"\" gesetzt, bis Sie das Spiel komplett beenden." + +#: engines/bladerunner/bladerunner.cpp:2041 +msgid "" +"WARNING: This game was saved in Original Content mode, but you are playing " +"in Restored Cut Content mode. The mode will be adjusted to Original Content " +"mode for this session until you completely Quit the game." +msgstr "" +"WARNUNG: Dieses Spiel wurde im \"Original-Inhalte\"-Modus gespeichert. Sie " +"spielen das Spiel jedoch im \"Entfernte Inhalte wiederherstellen\"-Modus. " +"Der Modus wird für diese Spielesitzung auf \"Original-Inhalte\" gesetzt, bis " +"Sie das Spiel komplett beenden." + +#: engines/bladerunner/bladerunner.cpp:2043 +msgid "Continue" +msgstr "Fortsetzen" + +#: engines/bladerunner/detection.cpp:48 +msgid "Sitcom mode" +msgstr "Sitcom-Modus" + +#: engines/bladerunner/detection.cpp:49 +msgid "Game will add laughter after actor's line or narration" +msgstr "" +"Das Spiel wird Gelächter am Ende eines Dialogs oder einer Erzählung " +"hinzufügen" + +#: engines/bladerunner/detection.cpp:57 +msgid "Shorty mode" +msgstr "Shorty-Modus" + +#: engines/bladerunner/detection.cpp:58 +msgid "Game will shrink the actors and make their voices high pitched" +msgstr "" +"Das Spiel wird die Akteure schrumpfen und ihre Stimmen höher klingen lassen" + +#: engines/cge/detection.cpp:105 engines/cge2/detection.cpp:111 +msgid "Color Blind Mode" +msgstr "Modus für Farbenblinde" + +#: engines/cge/detection.cpp:106 engines/cge2/detection.cpp:112 +msgid "Enable Color Blind Mode by default" +msgstr "Modus für Farbenblinde standardmäßig einschalten" + +#: engines/drascula/saveload.cpp:47 +msgid "" +"ScummVM found that you have old saved games for Drascula that should be " +"converted.\n" +"The old saved game format is no longer supported, so you will not be able to " +"load your games if you don't convert them.\n" +"\n" +"Press OK to convert them now, otherwise you will be asked again the next " +"time you start the game.\n" +msgstr "" +"ScummVM hat erkannt, dass Sie alte Spielstände von Drascula haben, die " +"umgewandelt werden sollten.\n" +"Das alte Speicherformat wird nicht mehr unterstützt, daher können Sie diese " +"Spielstände unkonvertiert nicht laden.\n" +"\n" +"Klicken Sie auf OK, um diese jetzt umzuwandeln, sonst werden Sie erneut " +"gefragt, wenn Sie nächstes Mal dieses Spiel starten.\n" + +#: engines/dreamweb/detection.cpp:58 +msgid "Use bright palette mode" +msgstr "Modus für helle Palette verwenden" + +#: engines/dreamweb/detection.cpp:59 +msgid "Display graphics using the game's bright palette" +msgstr "Zeigt Grafiken über helle Spielpalette an" + +#: engines/glk/glk_api.cpp:63 +msgid "[ press any key to exit ]" +msgstr "[ zum Beenden beliebige Taste drücken ]" + +#: engines/glk/quetzal.cpp:115 engines/glk/quetzal.cpp:124 +msgid "Untitled Savegame" +msgstr "Unbenannter Spielstand" + +#: engines/glk/advsys/advsys.cpp:35 +msgid "Could not start AdvSys game" +msgstr "AdvSys-Spiel konnte nicht gestartet werden" + +#: engines/glk/advsys/advsys.cpp:48 engines/glk/advsys/vm.cpp:319 +msgid "Sorry, the savegame couldn't be restored" +msgstr "" +"Entschuldigung, aber der Spielstand konnte nicht wiederhergestellt werden" + +#: engines/glk/advsys/vm.cpp:314 +msgid "Sorry, the savegame couldn't be created" +msgstr "Entschuldigung, aber der Spielstand konnte nicht erstellt werden" + +#: engines/glk/advsys/vm.cpp:560 +msgid "Speak up! I can't hear you!\n" +msgstr "Sprich lauter! Ich kann dich nicht hören!\n" + +#: engines/glk/advsys/vm.cpp:596 +#, c-format +msgid "I don't know the word \"%s\".\n" +msgstr "Ich kenne das Wort \"%s\" nicht.\n" + +#: engines/glk/advsys/vm.cpp:682 +msgid "I don't understand.\n" +msgstr "Ich verstehe nicht.\n" + +#: engines/glk/alan2/alan2.cpp:78 +msgid "This is too short to be a valid Alan2 file." +msgstr "Das ist zu kurz, um eine gültige Alan2-Datei zu sein." + +#: engines/glk/alan2/alan2.cpp:83 +msgid "This is not a valid Alan2 file." +msgstr "Dies ist keine gültige Alan2-Datei." + +#: engines/glk/frotz/frotz.cpp:126 +msgid "Error reading save file" +msgstr "Fehler beim Lesen der Spielstand-Datei" + +#: engines/glk/frotz/frotz.cpp:144 +msgid "Error writing save file\n" +msgstr "Fehler beim Schreiben der Spielstand-Datei\n" + +#: engines/glk/glulxe/glulxe.cpp:79 engines/glk/magnetic/magnetic.cpp:73 +msgid "This is too short to be a valid Glulx file." +msgstr "Das ist zu kurz, um eine gültige Glulx-Datei zu sein." + +#: engines/glk/glulxe/glulxe.cpp:84 engines/glk/magnetic/magnetic.cpp:78 +msgid "This is not a valid Glulx file." +msgstr "Dies ist keine gültige Glulx-Datei." + +#: engines/glk/glulxe/glulxe.cpp:91 engines/glk/magnetic/magnetic.cpp:85 +msgid "This Glulx file is too old a version to execute." +msgstr "Die Version dieser Glulx-Datei ist zu alt, um sie ausführen zu können." + +#: engines/glk/glulxe/glulxe.cpp:95 engines/glk/magnetic/magnetic.cpp:89 +msgid "This Glulx file is too new a version to execute." +msgstr "Diese Glulx-Datei ist zu neu, um Sie ausführen zu können." + +#: engines/glk/scott/scott.cpp:99 +msgid "I don't understand your command. " +msgstr "Ich verstehe Ihren Befehl nicht. " + +#: engines/glk/scott/scott.cpp:102 +msgid "I can't do that yet. " +msgstr "Ich kann das noch nicht tun. " + +#: engines/glk/scott/scott.cpp:118 +msgid "Light has run out! " +msgstr "Das Licht ist ausgegangen! " + +#: engines/glk/scott/scott.cpp:120 +msgid "Your light has run out. " +msgstr "Ihr Licht ist ausgegangen. " + +#: engines/glk/scott/scott.cpp:129 +msgid "Light runs out in " +msgstr "Licht geht aus in " + +#: engines/glk/scott/scott.cpp:131 +msgid " turns. " +msgstr " Runden. " + +#: engines/glk/scott/scott.cpp:134 +msgid "Your light is growing dim. " +msgstr "Ihr Licht wird schwächer. " + +#: engines/glk/scott/scott.cpp:394 +msgid "North" +msgstr "Norden" + +#: engines/glk/scott/scott.cpp:394 +msgid "South" +msgstr "Süden" + +#: engines/glk/scott/scott.cpp:394 +msgid "East" +msgstr "Osten" + +#: engines/glk/scott/scott.cpp:394 +msgid "West" +msgstr "Westen" + +#: engines/glk/scott/scott.cpp:406 +msgid "You can't see. It is too dark!\n" +msgstr "Sie können nichts sehen. Es ist zu dunkel!\n" + +#: engines/glk/scott/scott.cpp:408 +msgid "I can't see. It is too dark!\n" +msgstr "Ich kann nichts sehen. Es ist zu dunkel!\n" + +#: engines/glk/scott/scott.cpp:418 +#, c-format +msgid "You are in a %s\n" +msgstr "Sie sind in einem %s\n" + +#: engines/glk/scott/scott.cpp:420 +#, c-format +msgid "I'm in a %s\n" +msgstr "Ich bin in einem %s\n" + +#: engines/glk/scott/scott.cpp:425 +msgid "" +"\n" +"Obvious exits: " +msgstr "" +"\n" +"Ausgänge: " + +#: engines/glk/scott/scott.cpp:438 +msgid "none" +msgstr "keine" + +#: engines/glk/scott/scott.cpp:447 +msgid "" +"\n" +"You can also see: " +msgstr "" +"\n" +"Sie sehen auch: " + +#: engines/glk/scott/scott.cpp:450 +msgid "" +"\n" +"I can also see: " +msgstr "" +"\n" +"Ich sehe auch: " + +#: engines/glk/scott/scott.cpp:533 +msgid "Saved.\n" +msgstr "Gespeichert.\n" + +#: engines/glk/scott/scott.cpp:624 +msgid "You use word(s) I don't know! " +msgstr "Sie haben ein Wort verwendet, das ich nicht kenne! " + +#: engines/glk/scott/scott.cpp:752 engines/glk/scott/scott.cpp:1075 +#: engines/glk/scott/scott.cpp:1097 +msgid "You are carrying too much. " +msgstr "Sie tragen zu viel. " + +#: engines/glk/scott/scott.cpp:754 +msgid "I've too much to carry! " +msgstr "Ich habe zu viel zu tragen! " + +#: engines/glk/scott/scott.cpp:785 +msgid "You are dead.\n" +msgstr "Sie sind tot.\n" + +#: engines/glk/scott/scott.cpp:787 +msgid "I am dead.\n" +msgstr "Ich bin tot.\n" + +#: engines/glk/scott/scott.cpp:799 +msgid "The game is now over.\n" +msgstr "Das Spiel ist nun vorbei.\n" + +#: engines/glk/scott/scott.cpp:814 +msgid "You have stored " +msgstr "Du hast aufgenommen " + +#: engines/glk/scott/scott.cpp:816 +msgid "I've stored " +msgstr "Ich habe aufgenommen " + +#: engines/glk/scott/scott.cpp:818 +msgid " treasures. On a scale of 0 to 100, that rates " +msgstr " Schätze. Auf einer Skala von 0 bis 100 bringt das " + +#: engines/glk/scott/scott.cpp:822 +msgid "Well done.\n" +msgstr "Gut gemacht.\n" + +#: engines/glk/scott/scott.cpp:831 +msgid "You are carrying:\n" +msgstr "Sie tragen:\n" + +#: engines/glk/scott/scott.cpp:833 +msgid "I'm carrying:\n" +msgstr "Ich trage:\n" + +#: engines/glk/scott/scott.cpp:848 +msgid "Nothing" +msgstr "Nichts" + +#: engines/glk/scott/scott.cpp:977 +msgid "Give me a direction too." +msgstr "Gib mir auch eine Richtung." + +#: engines/glk/scott/scott.cpp:986 +msgid "Dangerous to move in the dark! " +msgstr "Es ist gefährlich, sich im Dunkeln zu bewegen! " + +#: engines/glk/scott/scott.cpp:994 +msgid "You fell down and broke your neck. " +msgstr "Sie sind gestürzt und haben sich das Genick gebrochen. " + +#: engines/glk/scott/scott.cpp:996 +msgid "I fell down and broke my neck. " +msgstr "Ich bin gestürzt und habe mir das Genick gebrochen. " + +#: engines/glk/scott/scott.cpp:1001 +msgid "You can't go in that direction. " +msgstr "Sie können nicht in diese Richtung gehen. " + +#: engines/glk/scott/scott.cpp:1003 +msgid "I can't go in that direction. " +msgstr "Ich kann nicht in diese Richtung gehen. " + +#: engines/glk/scott/scott.cpp:1061 +msgid "It is dark.\n" +msgstr "Es ist dunkel.\n" + +#: engines/glk/scott/scott.cpp:1077 engines/glk/scott/scott.cpp:1099 +msgid "I've too much to carry. " +msgstr "Ich habe zu viel zu tragen. " + +#: engines/glk/scott/scott.cpp:1082 engines/glk/scott/scott.cpp:1130 +msgid ": O.K.\n" +msgstr ": O.K.\n" + +#: engines/glk/scott/scott.cpp:1088 +msgid "Nothing taken." +msgstr "Nichts mitgenommen." + +#: engines/glk/scott/scott.cpp:1092 engines/glk/scott/scott.cpp:1140 +msgid "What ? " +msgstr "Was ? " + +#: engines/glk/scott/scott.cpp:1105 +msgid "It is beyond your power to do that. " +msgstr "Es liegt nicht in Ihrer Macht, dies zu tun. " + +#: engines/glk/scott/scott.cpp:1107 +msgid "It's beyond my power to do that. " +msgstr "Es liegt nicht in meiner Macht, dies zu tun. " + +#: engines/glk/scott/scott.cpp:1111 +msgid "O.K. " +msgstr "O.K. " + +#: engines/glk/scott/scott.cpp:1136 +msgid "Nothing dropped.\n" +msgstr "Nichts fallengelassen.\n" + +#: engines/glk/scott/scott.cpp:1146 +msgid "It's beyond your power to do that.\n" +msgstr "Es übersteigt Ihre Kraft, dies zu tun.\n" + +#: engines/glk/scott/scott.cpp:1148 +msgid "It's beyond my power to do that.\n" +msgstr "Es übersteigt meine Kraft, dies zu tun.\n" + +#: engines/gob/inter_playtoons.cpp:255 engines/gob/inter_v2.cpp:1467 +#: engines/gob/inter_geisha.cpp:232 engines/tinsel/saveload.cpp:538 +msgid "Failed to load saved game from file." +msgstr "Konnte Spielstand aus Datei nicht laden." + +#: engines/gob/inter_v2.cpp:1537 engines/gob/inter_geisha.cpp:263 +#: engines/tinsel/saveload.cpp:551 +msgid "Failed to save game to file." +msgstr "Konnte Spielstand nicht in Datei speichern." + +#: engines/gob/inter_v5.cpp:107 +msgid "Failed to delete file." +msgstr "Konnte Datei nicht löschen." + +#: engines/groovie/detection.cpp:323 +msgid "Fast movie speed" +msgstr "Schnelles Film-Tempo" + +#: engines/groovie/detection.cpp:324 +msgid "Play movies at an increased speed" +msgstr "Spielt Filme mit erhöhter Geschwindigkeit ab" + +#: engines/groovie/script.cpp:430 +msgid "Failed to save game" +msgstr "Konnte Spielstand nicht speichern" + +#: engines/hopkins/detection.cpp:76 engines/hopkins/detection.cpp:86 +msgid "Gore Mode" +msgstr "Blutmodus" + +#: engines/hopkins/detection.cpp:77 engines/hopkins/detection.cpp:87 +msgid "Enable Gore Mode when available" +msgstr "Blutmodus aktivieren, wenn verfügbar" + +#. I18N: Studio audience adds an applause and cheering sounds whenever +#. Malcolm makes a joke. +#: engines/kyra/detection.cpp:62 +msgid "Studio audience" +msgstr "Studio-Publikum" + +#: engines/kyra/detection.cpp:63 +msgid "Enable studio audience" +msgstr "Aktiviert Studio-Publikum" + +#. I18N: This option allows the user to skip text and cutscenes. +#: engines/kyra/detection.cpp:73 +msgid "Skip support" +msgstr "Erlaube Überspringen" + +#: engines/kyra/detection.cpp:74 +msgid "Allow text and cutscenes to be skipped" +msgstr "Erlaubt das Überspringen von Textteilen und Zwischensequenzen" + +#. I18N: Helium mode makes people sound like they've inhaled Helium. +#: engines/kyra/detection.cpp:84 +msgid "Helium mode" +msgstr "Helium-Modus" + +#: engines/kyra/detection.cpp:85 +msgid "Enable helium mode" +msgstr "Aktiviert Helium-Modus" + +#. I18N: When enabled, this option makes scrolling smoother when +#. changing from one screen to another. +#: engines/kyra/detection.cpp:99 +msgid "Smooth scrolling" +msgstr "Gleichmäßiges Scrollen" + +#: engines/kyra/detection.cpp:100 +msgid "Enable smooth scrolling when walking" +msgstr "Aktiviert gleichmäßiges Scrollen beim Gehen" + +#. I18N: When enabled, this option changes the cursor when it floats to the +#. edge of the screen to a directional arrow. The player can then click to +#. walk towards that direction. +#: engines/kyra/detection.cpp:112 +msgid "Floating cursors" +msgstr "Richtungspfeil-Mauszeiger" + +#: engines/kyra/detection.cpp:113 +msgid "Enable floating cursors" +msgstr "Aktiviert Richtungspfeil-Mauszeiger" + +#. I18N: HP stands for Hit Points +#: engines/kyra/detection.cpp:127 +msgid "HP bar graphs" +msgstr "Trefferpunkte-Balken" + +#: engines/kyra/detection.cpp:128 +msgid "Enable hit point bar graphs" +msgstr "Aktiviert grafische Trefferpunkte-Balken" + +#. I18N: L/R stands for Left/Right +#: engines/kyra/detection.cpp:138 +msgid "Fight Button L/R Swap" +msgstr "Tastenbelegung (Links/Rechts) vertauschen" + +#: engines/kyra/detection.cpp:139 +msgid "Left button to attack, right button to pick up items" +msgstr "Linker Button um anzugreifen, rechter Button, um Items aufzuheben" + +#: engines/kyra/engine/eobcommon.cpp:352 engines/kyra/engine/lol.cpp:481 +msgid "Move Forward" +msgstr "Nach vorn bewegen" + +#: engines/kyra/engine/eobcommon.cpp:353 engines/kyra/engine/lol.cpp:482 +msgid "Move Back" +msgstr "Nach hinten bewegen" + +#: engines/kyra/engine/eobcommon.cpp:354 +msgid "Move Left" +msgstr "Nach links gehen" + +#: engines/kyra/engine/eobcommon.cpp:355 +msgid "Move Right" +msgstr "Nach rechts gehen" + +#: engines/kyra/engine/eobcommon.cpp:356 engines/kyra/engine/lol.cpp:485 +#: engines/pegasus/pegasus.cpp:2514 +msgid "Turn Left" +msgstr "Nach links drehen" + +#: engines/kyra/engine/eobcommon.cpp:357 engines/kyra/engine/lol.cpp:486 +#: engines/pegasus/pegasus.cpp:2515 +msgid "Turn Right" +msgstr "Nach rechts drehen" + +#: engines/kyra/engine/eobcommon.cpp:358 +msgid "Open/Close Inventory" +msgstr "Inventar öffnen/schließen" + +#: engines/kyra/engine/eobcommon.cpp:359 +msgid "Switch Inventory/Character screen" +msgstr "Zwischen Inventar/Figurenbildschirm wechseln" + +#: engines/kyra/engine/eobcommon.cpp:360 +msgid "Camp" +msgstr "Camp" + +#: engines/kyra/engine/eobcommon.cpp:361 +msgid "Cast Spell" +msgstr "Zauber anwenden" + +#: engines/kyra/engine/eobcommon.cpp:364 +msgid "Spell Level 1" +msgstr "Zauberspruch Stufe 1" + +#: engines/kyra/engine/eobcommon.cpp:365 +msgid "Spell Level 2" +msgstr "Zauberspruch Stufe 2" + +#: engines/kyra/engine/eobcommon.cpp:366 +msgid "Spell Level 3" +msgstr "Zauberspruch Stufe 3" + +#: engines/kyra/engine/eobcommon.cpp:367 +msgid "Spell Level 4" +msgstr "Zauberspruch Stufe 4" + +#: engines/kyra/engine/eobcommon.cpp:368 +msgid "Spell Level 5" +msgstr "Zauberspruch Stufe 5" + +#: engines/kyra/engine/eobcommon.cpp:377 +msgid "Spell Level 6" +msgstr "Zauberspruch Stufe 6" + +#: engines/kyra/engine/lol.cpp:478 +msgid "Attack 1" +msgstr "Attacke 1" + +#: engines/kyra/engine/lol.cpp:479 +msgid "Attack 2" +msgstr "Attacke 2" + +#: engines/kyra/engine/lol.cpp:480 +msgid "Attack 3" +msgstr "Attacke 3" + +#: engines/kyra/engine/lol.cpp:483 +msgid "Slide Left" +msgstr "Nach links rutschen" + +#: engines/kyra/engine/lol.cpp:484 +msgid "Slide Right" +msgstr "Nach rechts rutschen" + +#: engines/kyra/engine/lol.cpp:487 +msgid "Rest" +msgstr "Ausruhen" + +#: engines/kyra/engine/lol.cpp:488 +msgid "Options" +msgstr "Optionen" + +#: engines/kyra/engine/lol.cpp:489 +msgid "Choose Spell" +msgstr "Zauberspruch auswählen" + +#: engines/kyra/gui/saveload_eob.cpp:569 +#, c-format +msgid "" +"The following original saved game file has been found in your game path:\n" +"\n" +"%s %s\n" +"\n" +"Do you wish to use this saved game file with ScummVM?\n" +"\n" +msgstr "" +"Die folgende originale Spielstand-Datei wurde in Ihrem Spieleverzeichnis " +"gefunden:\n" +"\n" +"%s %s\n" +"\n" +"Möchten Sie diese Spielstand-Datei in ScummVM verwenden?\n" +"\n" + +#: engines/kyra/gui/saveload_eob.cpp:602 +#, c-format +msgid "" +"A saved game file was found in the specified slot %d. Overwrite?\n" +"\n" +msgstr "" +"Eine Spielstand-Datei wurde im gewählten Speicherplatz %d gefunden. " +"Überschreiben?\n" +"\n" + +#: engines/kyra/gui/saveload_eob.cpp:635 +#, c-format +msgid "" +"%d original saved games have been successfully imported into\n" +"ScummVM. If you want to manually import original saved game later you will\n" +"need to open the ScummVM debug console and use the command " +"'import_savefile'.\n" +"\n" +msgstr "" +"%d originale Spielstand-Dateien wurden erfolgreich in ScummVM\n" +"importiert. Wenn Sie weitere Spielstand-Dateien später manuell importieren " +"wollen,\n" +"müssen Sie die ScummVM-Entwicklerkonsole öffnen und den Befehl " +"\"import_savefile\" verwenden.\n" +"\n" + +#: engines/kyra/graphics/screen_eob.cpp:2254 +msgid "" +"This AMIGA version requires the following font files:\n" +"\n" +"EOBF6.FONT\n" +"EOBF6/6\n" +"EOBF8.FONT\n" +"EOBF8/8\n" +"\n" +"If you used the orginal installer for the installation these files\n" +"should be located in the AmigaDOS system 'Fonts/' folder.\n" +"Please copy them into the EOB game data directory.\n" +msgstr "" +"Diese AMIGA-Version benötigt die folgenden Font-Dateien:\n" +"\n" +"EOBF6.FONT\n" +"EOBF6/6\n" +"EOBF8.FONT\n" +"EOBF8/8\n" +"\n" +"Wenn Sie das originale Installationsprogramm zur Installation\n" +"verwendet haben, sollten sich diese Dateien im Ordner 'Fonts/'\n" +"Ihrer AmigaDOS-Installation befinden. Bitte kopieren Sie diese\n" +"Dateien in das Spieldaten-Verzeichnis von EOB.\n" + +#: engines/kyra/graphics/screen_eob.cpp:2262 +msgid "" +"This AMIGA version requires the following font files:\n" +"\n" +"EOBF6.FONT\n" +"EOBF6/6\n" +"EOBF8.FONT\n" +"EOBF8/8\n" +"\n" +"This is a localized (non-English) version of EOB II which uses language " +"specific characters\n" +"contained only in the specific font files that came with your game. You " +"cannot use the font\n" +"files from the English version or from any EOB I game which seems to be what " +"you are doing.\n" +"\n" +"The game will continue, but the language specific characters will not be " +"displayed.\n" +"Please copy the correct font files into your EOB II game data directory.\n" +"\n" +msgstr "" +"Diese AMIGA-Version benötigt die folgenden Font-Dateien:\n" +"\n" +"EOBF6.FONT\n" +"EOBF6/6\n" +"EOBF8.FONT\n" +"EOBF8/8\n" +"\n" +"Dies ist eine lokalisierte (nicht-englische) Version von EOB II, die " +"sprachspezifische Zeichen\n" +"verwendet, die in speziellen Font-Dateien zusammen mit Ihrem Spiel " +"ausgeliefert wurden.\n" +"Sie können die Font-Dateien der englischen Version oder eines EOB I-Spiels " +"nicht verwenden.\n" +"\n" +"Das Spiel wird fortgesetzt, aber die sprachspezifischen Zeichen werden nicht " +"dargestellt.\n" +"Bitte kopieren Sie die korrenten Font-Dateien in Ihr EOB II-" +"Spielverzeichnis.\n" +"\n" + +#: engines/kyra/sound/sound_midi.cpp:72 +msgid "" +"You appear to be using a General MIDI device,\n" +"but your game only supports Roland MT32 MIDI.\n" +"We try to map the Roland MT32 instruments to\n" +"General MIDI ones. It is still possible that\n" +"some tracks sound incorrect." +msgstr "" +"Sie scheinen ein General MIDI-Gerät zu\n" +"verwenden, aber das Spiel unterstützt nur\n" +"Roland MT32 MIDI. Es wird versucht, die\n" +"Roland MT32-Instrumente denen von\n" +"General MIDI zuzuordnen. Es ist dennoch\n" +"möglich, dass ein paar Musikstücke nicht\n" +"richtig abgespielt werden." + +#: engines/mads/detection.cpp:91 +msgid "Easy mouse interface" +msgstr "Vereinfachte Maussteuerung" + +#: engines/mads/detection.cpp:92 +msgid "Shows object names when hovering the mouse over them" +msgstr "Zeigt Objektnamen an, wenn die Maus darüber bewegt wird" + +#: engines/mads/detection.cpp:101 engines/mads/detection.cpp:102 +msgid "Animated inventory items" +msgstr "Animierte Inventargegenstände" + +#: engines/mads/detection.cpp:111 engines/mads/detection.cpp:112 +msgid "Animated game interface" +msgstr "Animierte Spieloberfläche" + +#: engines/mads/detection.cpp:121 engines/mads/detection.cpp:122 +msgid "Naughty game mode" +msgstr "Unanständiger Spielmodus" + +#: engines/mohawk/detection.cpp:180 +msgid "Play the Myst fly by movie" +msgstr "Video vom Anflug auf Myst abspielen" + +#: engines/mohawk/detection.cpp:181 +msgid "The Myst fly by movie was not played by the original engine." +msgstr "" +"Das Video, welches den Anflug auf Myst zeigt, wurde in der ursprünglichen " +"Engine nicht abgespielt." + +#. I18N: Option for fast scene switching +#: engines/mohawk/dialogs.cpp:145 engines/mohawk/dialogs.cpp:285 +msgid "~Z~ip Mode Activated" +msgstr "~Z~ip-Modus aktiviert" + +#: engines/mohawk/dialogs.cpp:146 +msgid "~T~ransitions Enabled" +msgstr "Über~g~änge aktiviert" + +#. I18N: Drop book page +#: engines/mohawk/dialogs.cpp:148 +msgid "~D~rop Page" +msgstr "Seite ~a~blegen" + +#: engines/mohawk/dialogs.cpp:152 +msgid "Show ~M~ap" +msgstr "~K~arte anzeigen" + +#: engines/mohawk/dialogs.cpp:158 +msgid "Main Men~u~" +msgstr "Haupt~m~enü" + +#: engines/mohawk/dialogs.cpp:286 +msgid "~W~ater Effect Enabled" +msgstr "~W~assereffekt aktiviert" + +#: engines/mohawk/dialogs.cpp:288 +msgid "Transitions:" +msgstr "Übergänge:" + +#: engines/mohawk/dialogs.cpp:290 +msgid "Disabled" +msgstr "Ausgeschaltet" + +#: engines/mohawk/dialogs.cpp:291 +msgid "Fastest" +msgstr "Schnellste" + +#: engines/mohawk/dialogs.cpp:292 +msgid "Normal" +msgstr "Normal" + +#: engines/mohawk/dialogs.cpp:293 +msgid "Best" +msgstr "Beste" + +#: engines/mohawk/mohawk.cpp:55 +msgid "The game is paused. Press any key to continue." +msgstr "Das Spiel ist pausiert. Zum Weiterspielen beliebige Taste drücken." + +#: engines/mohawk/myst_stacks/menu.cpp:283 +#: engines/mohawk/riven_stacks/aspit.cpp:349 +msgid "" +"Are you sure you want to load a saved game? All unsaved progress will be " +"lost." +msgstr "" +"Sind Sie sicher, dass Sie ein gespeichertes Spiel laden möchten? Jeder nicht " +"gespeicherte Fortschritt geht dabei verloren." + +#: engines/mohawk/myst_stacks/menu.cpp:284 +#: engines/mohawk/riven_stacks/aspit.cpp:350 +msgid "Load game" +msgstr "Spiel laden" + +#: engines/mohawk/myst_stacks/menu.cpp:300 +#: engines/mohawk/riven_stacks/aspit.cpp:371 +msgid "" +"Are you sure you want to start a new game? All unsaved progress will be lost." +msgstr "" +"Sind Sie sicher, dass Sie ein neues Spiel starten möchten? Jeder nicht " +"gespeicherte Fortschritt geht dabei verloren." + +#: engines/mohawk/myst_stacks/menu.cpp:301 +#: engines/mohawk/riven_stacks/aspit.cpp:372 +msgid "New game" +msgstr "Neues Spiel" + +#: engines/mohawk/myst_stacks/menu.cpp:318 +#: engines/mohawk/riven_stacks/aspit.cpp:455 +msgid "Are you sure you want to quit? All unsaved progress will be lost." +msgstr "" +"Möchten Sie das Spiel wirklich beenden? Jeder nicht gespeicherte Fortschritt " +"geht dabei verloren." + +#: engines/mohawk/riven.cpp:158 +msgid "" +"You're missing a Riven executable. The Windows executable is 'riven.exe' or " +"'rivendmo.exe'. " +msgstr "" +"Ihnen fehlt eine Programmdatei von Riven. Die Windows-Programmdatei ist " +"'riven.exe' oder 'rivendmo.exe'. " + +#: engines/mohawk/riven.cpp:159 +msgid "" +"Using the 'arcriven.z' installer file also works. In addition, you can use " +"the Mac 'Riven' executable." +msgstr "" +"Die Installationsdatei 'arcriven.z' kann ebenfalls verwendet werden. " +"Zusätzlich können Sie auch die Mac-Programmdatei 'Riven' verwenden." + +#: engines/mohawk/riven.cpp:170 +msgid "" +"You're missing 'extras.mhk'. Using the 'arcriven.z' installer file also " +"works." +msgstr "" +"Die Datei 'extras.mhk' fehlt. Sie können auch die Installationsdatei " +"'arcriven.z verwenden." + +#: engines/mohawk/riven.cpp:515 +msgid "You are missing the following required Riven data files:\n" +msgstr "Ihnen fehlen die folgenden Spieldateien für Riven:\n" + +#: engines/mohawk/riven_stack.cpp:204 +msgid "" +"Exploration beyond this point available only within the full version of\n" +"the game." +msgstr "" +"Die weitere Erkundung über diesen Punkt hinaus ist nur in der Vollversion\n" +"des Spiels möglich." + +#: engines/mohawk/riven_stacks/aspit.cpp:429 +msgid "" +"At this point, the Riven Demo would\n" +"ask if you would like to open a web browser\n" +"to bring you to the Red Orb store to buy\n" +"the game. ScummVM cannot do that and\n" +"the site no longer exists." +msgstr "" +"An dieser Stelle würde die Riven-Demo\n" +"Sie fragen, ob Sie einen Web-Browser\n" +"öffnen möchten, um das Spiel direkt von\n" +"Red Orb zu kaufen. ScummVM kann dies nicht.\n" +"Die Webseite existiert nicht mehr." + +#: engines/neverhood/detection.cpp:184 +msgid "Skip the Hall of Records storyboard scenes" +msgstr "Szenenbuch-Sequenz in der Chronikhalle überspringen" + +#: engines/neverhood/detection.cpp:185 +msgid "Allows the player to skip past the Hall of Records storyboard scenes" +msgstr "" +"Ermöglicht dem Spieler, die Szenenbuch-Sequenz in der Chronikhalle zu " +"überspringen" + +#: engines/neverhood/detection.cpp:191 +msgid "Scale the making of videos to full screen" +msgstr "Making-Of-Videos auf Vollbild skalieren" + +#: engines/neverhood/detection.cpp:192 +msgid "Scale the making of videos, so that they use the whole screen" +msgstr "" +"Skaliert die Making-Of-Videos, sodass sie den gesamten Bildschirm ausfüllen" + +#: engines/parallaction/saveload.cpp:130 +#, c-format +msgid "" +"Can't save game in slot %i\n" +"\n" +msgstr "" +"Kann Spiel nicht auf Speicherplatz %i speichern\n" +"\n" + +#: engines/parallaction/saveload.cpp:194 +msgid "Load file" +msgstr "Datei laden" + +#: engines/parallaction/saveload.cpp:201 +msgid "Loading game..." +msgstr "Spiel wird geladen..." + +#: engines/parallaction/saveload.cpp:209 +msgid "Save file" +msgstr "Datei speichern" + +#: engines/parallaction/saveload.cpp:216 +msgid "Saving game..." +msgstr "Spiel wird gespeichert..." + +#: engines/parallaction/saveload.cpp:269 +msgid "" +"ScummVM found that you have old saved games for Nippon Safes that should be " +"renamed.\n" +"The old names are no longer supported, so you will not be able to load your " +"games if you don't convert them.\n" +"\n" +"Press OK to convert them now, otherwise you will be asked next time.\n" +msgstr "" +"ScummVM hat erkannt, dass Sie alte Spielstände von Nippon Safes haben, die " +"umbenannt werden sollten.\n" +"Die alten Dateinamen werden nicht mehr unterstützt, daher können Sie diese " +"Spielstände unkonvertiert nicht laden.\n" +"\n" +"Klicken Sie auf OK, um diese jetzt umzuwandeln, sonst werden Sie erneut " +"gefragt, wenn Sie nächstes Mal dieses Spiel starten.\n" + +#: engines/parallaction/saveload.cpp:316 +msgid "ScummVM successfully converted all your saved games." +msgstr "ScummVM hat alle Speicherstände erfolgreich umgewandelt." + +#: engines/parallaction/saveload.cpp:318 +msgid "" +"ScummVM printed some warnings in your console window and can't guarantee all " +"your files have been converted.\n" +"\n" +"Please report to the team." +msgstr "" +"ScummVM hat ein paar Warnungen im Konsolenfenster ausgegeben und kann nicht " +"gewährleisten, dass alle Speicherstände umgewandelt wurden.\n" +"\n" +"Bitte berichten Sie dies dem Team auf Englisch." + +#: engines/pegasus/pegasus.cpp:716 +msgid "Invalid file name for saving" +msgstr "Dateiname zum Speichern eingeben" + +#: engines/pegasus/pegasus.cpp:2512 +msgid "Up/Zoom In/Move Forward/Open Doors" +msgstr "Hoch/Hineinzoomen/Nach vorn/Türen öffnen" + +#: engines/pegasus/pegasus.cpp:2513 +msgid "Down/Zoom Out" +msgstr "Runter/Hinauszoomen" + +#: engines/pegasus/pegasus.cpp:2516 +msgid "Display/Hide Inventory Tray" +msgstr "Inventarleiste anzeigen/verbergen" + +#: engines/pegasus/pegasus.cpp:2517 +msgid "Display/Hide Biochip Tray" +msgstr "Biochip-Leiste anzeigen/verbergen" + +#: engines/pegasus/pegasus.cpp:2518 +msgid "Action/Select" +msgstr "Aktion/Auswählen" + +#: engines/pegasus/pegasus.cpp:2519 +msgid "Toggle Center Data Display" +msgstr "Mittige Datenanzeige wechseln" + +#: engines/pegasus/pegasus.cpp:2520 +msgid "Display/Hide Info Screen" +msgstr "Info-Bildschirm anzeigen/verbergen" + +#: engines/pegasus/pegasus.cpp:2521 +msgid "Display/Hide Pause Menu" +msgstr "Pause-Menü anzeigen/verbergen" + +#: engines/queen/detection.cpp:56 +msgid "Alternative intro" +msgstr "Alternativer Vorspann" + +#: engines/queen/detection.cpp:57 +msgid "Use an alternative game intro (CD version only)" +msgstr "Verwendet einen alternativen Vorspann (nur bei CD-Version)" + +#: engines/sci/detection.cpp:396 +msgid "Skip EGA dithering pass (full color backgrounds)" +msgstr "Überspringe EGA-Fehlerdiffusion (Vollfarbige Hintergründe)" + +#: engines/sci/detection.cpp:397 +msgid "Skip dithering pass in EGA games, graphics are shown with full colors" +msgstr "" +"Überspringe Fehlerdiffusion in EGA-Spielen, Grafik wird mit allen Farben " +"gezeigt" + +#: engines/sci/detection.cpp:406 +msgid "Enable high resolution graphics" +msgstr "Aktiviere hochauflösende Grafik" + +#: engines/sci/detection.cpp:407 +msgid "Enable high resolution graphics/content" +msgstr "Aktiviere hochauflösende Grafik/Inhalte" + +#: engines/sci/detection.cpp:416 +msgid "Enable black-lined video" +msgstr "Aktiviere schwarze Linien in Videos" + +#: engines/sci/detection.cpp:417 +msgid "Draw black lines over videos to increase their apparent sharpness" +msgstr "" +"Zeichne schwarze Linien über Videos, um die scheinbare Schärfe zu erhöhen" + +#: engines/sci/detection.cpp:427 +msgid "Use high-quality video scaling" +msgstr "Qualitativ hochwertige Videoskalierung verwenden" + +#: engines/sci/detection.cpp:428 +msgid "Use linear interpolation when upscaling videos, where possible" +msgstr "Verwende bilineare Filterung zur Skalierung von Videos, sofern möglich" + +#: engines/sci/detection.cpp:438 +msgid "Use high-quality \"LarryScale\" cel scaling" +msgstr "Qualitativ hochwertiges \"LarryScale\" cel-scaling verwenden" + +#: engines/sci/detection.cpp:439 +msgid "Use special cartoon scaler for drawing character sprites" +msgstr "" +"Verwendet einen speziellen Cartoon-Scaler, um Character-Sprites darzustellen" + +#: engines/sci/detection.cpp:448 +msgid "Prefer digital sound effects" +msgstr "Digitale Geräusch-Effekte bevorzugen" + +#: engines/sci/detection.cpp:449 +msgid "Prefer digital sound effects instead of synthesized ones" +msgstr "Bevorzugt digitale Geräusch-Effekte statt synthetisierter" + +#: engines/sci/detection.cpp:468 +msgid "Use IMF/Yamaha FB-01 for MIDI output" +msgstr "IMF/Yamaha FB-01 für MIDI-Ausgabe verwenden" + +#: engines/sci/detection.cpp:469 +msgid "" +"Use an IBM Music Feature card or a Yamaha FB-01 FM synth module for MIDI " +"output" +msgstr "" +"Verwendet eine Music Feature-Karte von IBM oder ein Yamaha FB-01 FM-" +"Synthetisierungsmodul für die MIDI-Ausgabe" + +#: engines/sci/detection.cpp:479 +msgid "Use CD audio" +msgstr "CD-Ton verwenden" + +#: engines/sci/detection.cpp:480 +msgid "Use CD audio instead of in-game audio, if available" +msgstr "Verwendet CD-Ton anstatt des Tons im Spiel, sofern verfügbar" + +#: engines/sci/detection.cpp:490 +msgid "Use Windows cursors" +msgstr "Windows-Mauszeiger verwenden" + +#: engines/sci/detection.cpp:491 +msgid "" +"Use the Windows cursors (smaller and monochrome) instead of the DOS ones" +msgstr "" +"Verwendet die Windows-Mauszeiger (kleiner und schwarz-weiß) anstatt der von " +"DOS" + +#: engines/sci/detection.cpp:501 +msgid "Use silver cursors" +msgstr "Silberne Mauszeiger verwenden" + +#: engines/sci/detection.cpp:502 +msgid "" +"Use the alternate set of silver cursors instead of the normal golden ones" +msgstr "" +"Verwendet alternativen Satz silberner Mauszeiger anstatt der normalen " +"goldenen" + +#: engines/sci/detection.cpp:512 +msgid "Enable content censoring" +msgstr "Zensur aktivieren" + +#: engines/sci/detection.cpp:513 +msgid "Enable the game's built-in optional content censoring" +msgstr "Aktiviere die im Spiel eingebaute optionale Zensur des Inhalts" + +#: engines/sci/detection.cpp:523 +msgid "Upscale videos" +msgstr "Videos hochskalieren" + +#: engines/sci/detection.cpp:524 +msgid "Upscale videos to double their size" +msgstr "Videos auf das Doppelte ihrer Größe skalieren" + +#: engines/sci/detection.cpp:854 engines/sci/engine/kfile.cpp:481 +msgid "(Autosave)" +msgstr "(Automatisches Speichern)" + +#: engines/sci/engine/kgraphics.cpp:995 +msgid "" +"Characters saved inside ScummVM are shown automatically. Character files " +"saved in the original interpreter need to be put inside ScummVM's saved " +"games directory and a prefix needs to be added depending on which game it " +"was saved in: 'qfg1-' for Quest for Glory 1, 'qfg2-' for Quest for Glory 2. " +"Example: 'qfg2-thief.sav'." +msgstr "" +"Charaktere, die in ScummVM gespeichert wurden, werden automatisch angezeigt. " +"Charakter-Dateien, die im originalen Interpreter gespeichert wurden, müssen " +"in das Spielstand-Verzeichnis von ScummVM kopiert und mit einem Präfix " +"ergänzt werden, der davon abhängig ist, in welchem Spiel die Charaktere " +"erstellt wurden: 'qfg1-' für Quest for Glory 1, 'qfg2-' für Quest for Glory " +"2. Beispiel: 'qfg2-thief.sav'." + +#: engines/sci/engine/kgraphics32.cpp:348 +#, c-format +msgid "Please use an external viewer to open the game's help file: %s" +msgstr "" +"Bitte verwenden Sie einen externen Betrachter, um die Hilfedatei des Spiels " +"zu öffnen: %s" + +#: engines/sci/engine/savegame.cpp:1300 +msgid "The format of this saved game is obsolete, unable to load it" +msgstr "Das Format dieses Spielstands ist veraltet; laden nicht möglich" + +#: engines/sci/engine/savegame.cpp:1302 +#, c-format +msgid "Savegame version is %d, maximum supported is %0d" +msgstr "Spielstand-Version ist %d, höchste unterstützte Version ist %0d" + +#: engines/sci/engine/savegame.cpp:1313 +msgid "" +"This saved game was created with a different version of the game, unable to " +"load it" +msgstr "" +"Dieser Spielstand wurde mit einer anderen Version des Spiels erstellt; laden " +"nicht möglich" + +#: engines/sci/resource.cpp:827 +msgid "" +"Missing or corrupt game resources have been detected. Some game features may " +"not work properly. Please check the console for more information, and verify " +"that your game files are valid." +msgstr "" +"Fehlende oder defekte Spiel-Ressourcen wurden erkannt. Einige " +"Spielfunktionen funktionieren möglicherweise nicht korrekt. Bitte überprüfen " +"Sie die Konsole auf weitere Informationen und stellen Sie sicher, dass Ihre " +"Spieldateien korrekt sind." + +#: engines/sci/sci.cpp:385 +msgid "" +"Subtitles are enabled, but subtitling in King's Quest 7 was unfinished and " +"disabled in the release version of the game. ScummVM allows the subtitles to " +"be re-enabled, but because they were removed from the original game, they do " +"not always render properly or reflect the actual game speech. This is not a " +"ScummVM bug -- it is a problem with the game's assets." +msgstr "" +"Untertitel sind aktiviert, die Untertitel in King's Quest 7 wurden jedoch " +"nicht fertiggestellt und im veröffentlichten Spiel deaktiviert. ScummVM " +"erlaubt, dass die Untertitel trotzdem aktiviert werden. Da diese jedoch im " +"Originalspiel entfernt wurden, werden sie nicht immer korrekt dargestellt " +"oder weichen von der Sprachausgabe ab. Dies ist kein Fehler in ScummVM -- es " +"ist ein Problem mit den Spieldaten." + +#: engines/sci/sci.cpp:409 +msgid "" +"You have selected General MIDI as a sound device. Sierra has provided after-" +"market support for General MIDI for this game in their \"General MIDI Utility" +"\". Please, apply this patch in order to enjoy MIDI music with this game. " +"Once you have obtained it, you can unpack all of the included *.PAT files in " +"your ScummVM extras folder and ScummVM will add the appropriate patch " +"automatically. Alternatively, you can follow the instructions in the READ.ME " +"file included in the patch and rename the associated *.PAT file to 4.PAT and " +"place it in the game folder. Without this patch, General MIDI music for this " +"game will sound badly distorted." +msgstr "" +"Sie haben General MIDI als Audio-Gerät ausgewählt. Sierra bietet für dieses " +"Spiel Unterstützung von General MIDI über das \"General MIDI Utility\" an, " +"welches separat erhältlich war. Bitte installieren Sie diesen Patch, um MIDI-" +"Musik in diesem Spiel zu erleben. Nachdem Sie den Patch erhalten haben, " +"können Sie alle darin befindlichen *.PAT-Dateien in Ihr ScummVM Extra-" +"Verzeichnis entpacken. ScummVM wird den passenden Patch dann automatisch " +"auswählen. Alternativ können Sie die Anweisungen in der READ.ME-Datei " +"befolgen, die mit dem Patch mitgeliefert wird, und die zugehörige *.PAT-" +"Datei in 4.PAT umbenennen und im Spiele-Verzeichnis ablegen. Ohne diesen " +"Patch wird die General MIDI-Musik erheblich verzerrt sein." + +#: engines/sci/sci.cpp:428 +msgid "" +"Your game is patched with a fan made script patch. Such patches have been " +"reported to cause issues, as they modify game scripts extensively. The " +"issues that these patches fix do not occur in ScummVM, so you are advised to " +"remove this patch from your game folder in order to avoid having unexpected " +"errors and/or issues later on." +msgstr "" +"Ihr Spiel wurde mit einem von Fans erstellten Patch gepatcht. Solche Patches " +"sind dafür bekannt, Fehler zu verursachen, da sie die Spiel-Skripte " +"umfangreich verändern. Die Fehler, die durch solche Patches behoben werden " +"treten nicht in ScummVM auf, weshalb Sie diesen Patch aus Ihrem Spiel-" +"Verzeichnis entfernen sollten, um unerwartete Fehler und/oder Probleme zu " +"verhindern." + +#: engines/scumm/detection.cpp:1123 +msgid "" +"Your game version appears to be unknown. If this is *NOT* a fan-modified\n" +"version (in particular, not a fan-made translation), please, report the\n" +"following data to the ScummVM team along with the name of the game you " +"tried\n" +"to add and its version, language, etc.:\n" +msgstr "" +"Ihre Spiel-Version ist offenbar unbekannt. Wenn es sich *NICHT* um eine\n" +"von Fans modifizierte Version (z.B. eine Fan-Übersetzung) handelt, teilen\n" +"Sie bitte dem ScummVM-Team die folgenden Daten sowie den Namen des Spiels,\n" +"welches Sie hinzufügen wollten, dessen Version, Sprache usw. mit:\n" + +#: engines/scumm/detection.cpp:1141 +msgid "" +"The Lite version of Putt-Putt Saves the Zoo iOS is not supported to avoid " +"piracy.\n" +"The full version is available for purchase from the iTunes Store." +msgstr "" +"Die \"Lite\"-Version von \"Putt-Putt Saves the Zoo iOS\" wird nicht " +"unterstützt,\n" +"um Software-Piraterie zu verhindern. Die Vollversion ist im iTunes Store " +"erhältlich." + +#: engines/scumm/detection.cpp:1352 +msgid "Show Object Line" +msgstr "Objektzeile zeigen" + +#: engines/scumm/detection.cpp:1353 +msgid "Show the names of objects at the bottom of the screen" +msgstr "Objektnamen und Verben am unteren Bildrand anzeigen" + +#: engines/scumm/dialogs.cpp:172 +#, c-format +msgid "Insert Disk %c and Press Button to Continue." +msgstr "Bitte Disk %c einlegen und Taste drücken." + +#: engines/scumm/dialogs.cpp:173 +#, c-format +msgid "Unable to Find %s, (%c%d) Press Button." +msgstr "Kann %s (%c%d) nicht finden, bitte Taste drücken." + +#: engines/scumm/dialogs.cpp:174 +#, c-format +msgid "Error reading disk %c, (%c%d) Press Button." +msgstr "Fehler beim Lesen von Disk %c (%c%d), bitte Taste drücken." + +#: engines/scumm/dialogs.cpp:175 +msgid "Game Paused. Press SPACE to Continue." +msgstr "Spielpause. Zum Weiterspielen Leertaste drücken." + +#. I18N: You may specify 'Yes' symbol at the end of the line, like this: +#. "Moechten Sie wirklich neu starten? (J/N)J" +#. Will react to J as 'Yes' +#: engines/scumm/dialogs.cpp:179 +msgid "Are you sure you want to restart? (Y/N)Y" +msgstr "Möchten Sie wirklich neu starten? (J/N)J" + +#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment +#: engines/scumm/dialogs.cpp:181 +msgid "Are you sure you want to quit? (Y/N)Y" +msgstr "Möchten Sie wirklich beenden? (J/N)J" + +#: engines/scumm/dialogs.cpp:186 +msgid "Play" +msgstr "Spielen" + +#: engines/scumm/dialogs.cpp:190 +msgid "Insert save/load game disk" +msgstr "Legen Sie eine Spielstand-Diskette ein" + +#: engines/scumm/dialogs.cpp:191 +msgid "You must enter a name" +msgstr "Sie müssen eine Bezeichnung eingeben" + +#: engines/scumm/dialogs.cpp:192 +msgid "The game was NOT saved (disk full?)" +msgstr "Spiel wurde NICHT gespeichert (Datenträger voll?)" + +#: engines/scumm/dialogs.cpp:193 +msgid "The game was NOT loaded" +msgstr "Spiel wurde NICHT geladen" + +#: engines/scumm/dialogs.cpp:194 +#, c-format +msgid "Saving '%s'" +msgstr "Speichere \"%s\"" + +#: engines/scumm/dialogs.cpp:195 +#, c-format +msgid "Loading '%s'" +msgstr "Lade \"%s\"" + +#: engines/scumm/dialogs.cpp:196 +msgid "Name your SAVE game" +msgstr "Name für Spielstand eingeben" + +#: engines/scumm/dialogs.cpp:197 +msgid "Select a game to LOAD" +msgstr "Spielstand zum LADEN auswählen" + +#: engines/scumm/dialogs.cpp:198 +msgid "Game title)" +msgstr "Spieltitel)" + +#. I18N: Previous page button +#: engines/scumm/dialogs.cpp:284 +msgid "~P~revious" +msgstr "~Z~urück" + +#. I18N: Next page button +#: engines/scumm/dialogs.cpp:286 +msgid "~N~ext" +msgstr "~W~eiter" + +#: engines/scumm/dialogs.cpp:599 +msgid "Speech Only" +msgstr "Nur Sprache" + +#: engines/scumm/dialogs.cpp:600 +msgid "Speech and Subtitles" +msgstr "Sprachausgabe und Untertitel" + +#: engines/scumm/dialogs.cpp:601 +msgid "Subtitles Only" +msgstr "Nur Untertitel" + +#: engines/scumm/dialogs.cpp:609 +msgctxt "lowres" +msgid "Speech & Subs" +msgstr "Sprache & Text" + +#: engines/scumm/dialogs.cpp:655 +msgid "Select a Proficiency Level." +msgstr "Wähle einen Schwierigkeitsgrad." + +#: engines/scumm/dialogs.cpp:657 +msgid "Refer to your Loom(TM) manual for help." +msgstr "Für Hilfe schauen Sie ins Loom(TM)-Handbuch." + +#: engines/scumm/dialogs.cpp:661 +msgid "Practice" +msgstr "Anfänger" + +#: engines/scumm/dialogs.cpp:662 +msgid "Expert" +msgstr "Experte" + +#: engines/scumm/help.cpp:74 +msgid "Common keyboard commands:" +msgstr "Allgemeine Tastenbefehle:" + +#: engines/scumm/help.cpp:75 +msgid "Save / Load dialog" +msgstr "Menü zum Speichern/Laden" + +#: engines/scumm/help.cpp:77 +msgid "Skip line of text" +msgstr "Textzeile überspringen" + +#: engines/scumm/help.cpp:78 +msgid "Esc" +msgstr "Esc" + +#: engines/scumm/help.cpp:78 +msgid "Skip cutscene" +msgstr "Zwischensequenz überspringen" + +#: engines/scumm/help.cpp:79 +msgid "Space" +msgstr "Leertaste" + +#: engines/scumm/help.cpp:79 +msgid "Pause game" +msgstr "Spielpause" + +#: engines/scumm/help.cpp:80 engines/scumm/help.cpp:85 +#: engines/scumm/help.cpp:96 engines/scumm/help.cpp:97 +#: engines/scumm/help.cpp:98 engines/scumm/help.cpp:99 +#: engines/scumm/help.cpp:100 engines/scumm/help.cpp:101 +#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103 +msgid "Ctrl" +msgstr "Strg" + +#: engines/scumm/help.cpp:80 +msgid "Load saved game 1-10" +msgstr "Spielstand 1-10 laden" + +#: engines/scumm/help.cpp:81 engines/scumm/help.cpp:85 +#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:101 +#: engines/scumm/help.cpp:102 engines/scumm/help.cpp:103 +msgid "Alt" +msgstr "Alt" + +#: engines/scumm/help.cpp:81 +msgid "Save game 1-10" +msgstr "Spielstand 1-10 speichern" + +#: engines/scumm/help.cpp:87 engines/scumm/help.cpp:90 +msgid "Enter" +msgstr "Enter" + +#: engines/scumm/help.cpp:88 +msgid "Music volume up / down" +msgstr "Musiklautstärke höher/niedriger" + +#: engines/scumm/help.cpp:89 +msgid "Text speed slower / faster" +msgstr "Texttempo langsamer/schneller" + +#: engines/scumm/help.cpp:90 +msgid "Simulate left mouse button" +msgstr "Linke Maustaste simulieren" + +#: engines/scumm/help.cpp:91 +msgid "Tab" +msgstr "Tabulator" + +#: engines/scumm/help.cpp:91 +msgid "Simulate right mouse button" +msgstr "Rechte Maustaste simulieren" + +#: engines/scumm/help.cpp:94 +msgid "Special keyboard commands:" +msgstr "Spezielle Tastenbefehle:" + +#: engines/scumm/help.cpp:95 +msgid "Show / Hide console" +msgstr "Konsole zeigen/verbergen" + +#: engines/scumm/help.cpp:96 +msgid "Start the debugger" +msgstr "Debugger starten" + +#: engines/scumm/help.cpp:97 +msgid "Show memory consumption" +msgstr "Speicherverbrauch anzeigen" + +#: engines/scumm/help.cpp:98 +msgid "Run in fast mode (*)" +msgstr "Schneller Modus (*)" + +#: engines/scumm/help.cpp:99 +msgid "Run in really fast mode (*)" +msgstr "Sehr schneller Modus (*)" + +#: engines/scumm/help.cpp:100 +msgid "Toggle mouse capture" +msgstr "Mauseingrenzung in Fenster EIN/AUS" + +#: engines/scumm/help.cpp:101 +msgid "Switch between graphics filters" +msgstr "Zwischen Grafikfiltern wechseln" + +#: engines/scumm/help.cpp:102 +msgid "Increase / Decrease scale factor" +msgstr "Größenverhältnis höher/niedriger" + +#: engines/scumm/help.cpp:103 +msgid "Toggle aspect-ratio correction" +msgstr "Seitenverhältnis anpassen: EIN/AUS" + +#: engines/scumm/help.cpp:108 +msgid "* Note that using ctrl-f and" +msgstr "* Es wird davon abgeraten," + +#: engines/scumm/help.cpp:109 +msgid " ctrl-g are not recommended" +msgstr " Strg+F und Strg+G zu verwenden," + +#: engines/scumm/help.cpp:110 +msgid " since they may cause crashes" +msgstr " da dies Abstürze oder fehlerhaftes" + +#: engines/scumm/help.cpp:111 +msgid " or incorrect game behavior." +msgstr " Spielverhalten verursachen kann." + +#: engines/scumm/help.cpp:115 +msgid "Spinning drafts on the keyboard:" +msgstr "Sprüche mit Tastatur spinnen:" + +#: engines/scumm/help.cpp:117 +msgid "Main game controls:" +msgstr "Hauptspielsteuerung:" + +#: engines/scumm/help.cpp:122 engines/scumm/help.cpp:137 +#: engines/scumm/help.cpp:162 +msgid "Push" +msgstr "Drücke" + +#: engines/scumm/help.cpp:123 engines/scumm/help.cpp:138 +#: engines/scumm/help.cpp:163 +msgid "Pull" +msgstr "Ziehe" + +#: engines/scumm/help.cpp:124 engines/scumm/help.cpp:139 +#: engines/scumm/help.cpp:164 engines/scumm/help.cpp:198 +#: engines/scumm/help.cpp:208 +msgid "Give" +msgstr "Gib" + +#: engines/scumm/help.cpp:125 engines/scumm/help.cpp:140 +#: engines/scumm/help.cpp:165 engines/scumm/help.cpp:191 +#: engines/scumm/help.cpp:209 +msgid "Open" +msgstr "Öffne" + +#: engines/scumm/help.cpp:127 +msgid "Go to" +msgstr "Gehe zu" + +#: engines/scumm/help.cpp:128 +msgid "Get" +msgstr "Nimm" + +#: engines/scumm/help.cpp:129 engines/scumm/help.cpp:153 +#: engines/scumm/help.cpp:171 engines/scumm/help.cpp:199 +#: engines/scumm/help.cpp:214 engines/scumm/help.cpp:225 +#: engines/scumm/help.cpp:251 +msgid "Use" +msgstr "Benutze" + +#: engines/scumm/help.cpp:130 engines/scumm/help.cpp:142 +msgid "Read" +msgstr "Lies" + +#: engines/scumm/help.cpp:131 engines/scumm/help.cpp:148 +msgid "New kid" +msgstr "Person" + +#: engines/scumm/help.cpp:132 engines/scumm/help.cpp:154 +#: engines/scumm/help.cpp:172 +msgid "Turn on" +msgstr "Schalt ein" + +#: engines/scumm/help.cpp:133 engines/scumm/help.cpp:155 +#: engines/scumm/help.cpp:173 +msgid "Turn off" +msgstr "Schalt aus" + +#: engines/scumm/help.cpp:143 engines/scumm/help.cpp:168 +#: engines/scumm/help.cpp:195 +msgid "Walk to" +msgstr "Gehe zu" + +#: engines/scumm/help.cpp:144 engines/scumm/help.cpp:169 +#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:211 +#: engines/scumm/help.cpp:228 +msgid "Pick up" +msgstr "Nimm" + +#: engines/scumm/help.cpp:145 engines/scumm/help.cpp:170 +msgid "What is" +msgstr "Was ist" + +#: engines/scumm/help.cpp:147 +msgid "Unlock" +msgstr "Schließ auf" + +#: engines/scumm/help.cpp:150 +msgid "Put on" +msgstr "Zieh an" + +#: engines/scumm/help.cpp:151 +msgid "Take off" +msgstr "Nimm ab" + +#: engines/scumm/help.cpp:157 +msgid "Fix" +msgstr "Reparier" + +#: engines/scumm/help.cpp:159 +msgid "Switch" +msgstr "Wechsle" + +#: engines/scumm/help.cpp:167 engines/scumm/help.cpp:229 +msgid "Look" +msgstr "Schau" + +#: engines/scumm/help.cpp:174 engines/scumm/help.cpp:224 +msgid "Talk" +msgstr "Rede" + +#: engines/scumm/help.cpp:175 +msgid "Travel" +msgstr "Reise" + +#: engines/scumm/help.cpp:176 +msgid "To Henry / To Indy" +msgstr "Zu Henry/Zu Indy" + +#. I18N: These are different musical notes +#: engines/scumm/help.cpp:180 +msgid "play C minor on distaff" +msgstr "spiele tiefes C auf Stab" + +#: engines/scumm/help.cpp:181 +msgid "play D on distaff" +msgstr "spiele D auf Stab" + +#: engines/scumm/help.cpp:182 +msgid "play E on distaff" +msgstr "spiele E auf Stab" + +#: engines/scumm/help.cpp:183 +msgid "play F on distaff" +msgstr "spiele F auf Stab" + +#: engines/scumm/help.cpp:184 +msgid "play G on distaff" +msgstr "spiele G auf Stab" + +#: engines/scumm/help.cpp:185 +msgid "play A on distaff" +msgstr "spiele A auf Stab" + +#: engines/scumm/help.cpp:186 +msgid "play B on distaff" +msgstr "spiele H auf Stab" + +#: engines/scumm/help.cpp:187 +msgid "play C major on distaff" +msgstr "spiele hohes C auf Stab" + +#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215 +msgid "puSh" +msgstr "Drücke" + +#: engines/scumm/help.cpp:194 engines/scumm/help.cpp:216 +msgid "pull (Yank)" +msgstr "Ziehe" + +#: engines/scumm/help.cpp:197 engines/scumm/help.cpp:213 +#: engines/scumm/help.cpp:249 +msgid "Talk to" +msgstr "Rede mit" + +#: engines/scumm/help.cpp:200 engines/scumm/help.cpp:212 +msgid "Look at" +msgstr "Schau an" + +#: engines/scumm/help.cpp:201 +msgid "turn oN" +msgstr "Mach an" + +#: engines/scumm/help.cpp:202 +msgid "turn oFf" +msgstr "Mach aus" + +#: engines/scumm/help.cpp:218 +msgid "KeyUp" +msgstr "Hoch-Taste" + +#: engines/scumm/help.cpp:218 +msgid "Highlight prev dialogue" +msgstr "Vorige Dialogwahl markieren" + +#: engines/scumm/help.cpp:219 +msgid "KeyDown" +msgstr "Runter-Taste" + +#: engines/scumm/help.cpp:219 +msgid "Highlight next dialogue" +msgstr "Nächste Dialogwahl markieren" + +#: engines/scumm/help.cpp:223 +msgid "Walk" +msgstr "Gehe" + +#: engines/scumm/help.cpp:226 engines/scumm/help.cpp:235 +#: engines/scumm/help.cpp:242 engines/scumm/help.cpp:250 +msgid "Inventory" +msgstr "Inventar" + +#: engines/scumm/help.cpp:227 +msgid "Object" +msgstr "Objekt" + +#: engines/scumm/help.cpp:230 +msgid "Black and White / Color" +msgstr "Graustufen-Modus/Farbe" + +#: engines/scumm/help.cpp:233 +msgid "Eyes" +msgstr "Augen" + +#: engines/scumm/help.cpp:234 +msgid "Tongue" +msgstr "Zunge" + +#: engines/scumm/help.cpp:236 +msgid "Punch" +msgstr "Schlage" + +#: engines/scumm/help.cpp:237 +msgid "Kick" +msgstr "Tritt" + +#: engines/scumm/help.cpp:240 engines/scumm/help.cpp:248 +msgid "Examine" +msgstr "Betrachte" + +#: engines/scumm/help.cpp:241 +msgid "Regular cursor" +msgstr "Normaler Mauszeiger" + +#. I18N: Comm is a communication device +#: engines/scumm/help.cpp:244 +msgid "Comm" +msgstr "Kommunikation" + +#: engines/scumm/help.cpp:247 +msgid "Save / Load / Options" +msgstr "Speichern / Laden / Optionen" + +#: engines/scumm/help.cpp:256 +msgid "Other game controls:" +msgstr "Weitere Steuerung:" + +#: engines/scumm/help.cpp:258 engines/scumm/help.cpp:268 +msgid "Inventory:" +msgstr "Inventar:" + +#: engines/scumm/help.cpp:259 engines/scumm/help.cpp:275 +msgid "Scroll list up" +msgstr "Liste hochblättern" + +#: engines/scumm/help.cpp:260 engines/scumm/help.cpp:276 +msgid "Scroll list down" +msgstr "Liste runterblättern" + +#: engines/scumm/help.cpp:261 engines/scumm/help.cpp:269 +msgid "Upper left item" +msgstr "Oberer linker Gegenstand" + +#: engines/scumm/help.cpp:262 engines/scumm/help.cpp:271 +msgid "Lower left item" +msgstr "Unterer linker Gegenstand" + +#: engines/scumm/help.cpp:263 engines/scumm/help.cpp:272 +msgid "Upper right item" +msgstr "Oberer rechter Gegenstand" + +#: engines/scumm/help.cpp:264 engines/scumm/help.cpp:274 +msgid "Lower right item" +msgstr "Unterer rechter Gegenstand" + +#: engines/scumm/help.cpp:270 +msgid "Middle left item" +msgstr "Mittlerer linker Gegenstand" + +#: engines/scumm/help.cpp:273 +msgid "Middle right item" +msgstr "Mittlerer rechter Gegenstand" + +#: engines/scumm/help.cpp:280 engines/scumm/help.cpp:285 +msgid "Switching characters:" +msgstr "Figuren wechseln:" + +#: engines/scumm/help.cpp:282 +msgid "Second kid" +msgstr "Zweites Kind" + +#: engines/scumm/help.cpp:283 +msgid "Third kid" +msgstr "Drittes Kind" + +#: engines/scumm/help.cpp:292 +msgid "Toggle Inventory/IQ Points display" +msgstr "Inventar-/IQ-Punkt-Anzeige umschalten" + +#: engines/scumm/help.cpp:293 +msgid "Toggle Keyboard/Mouse Fighting (*)" +msgstr "Schalte zwischen Tastatur-/Maus-Kämpfen um (*)" + +#: engines/scumm/help.cpp:295 +msgid "* Keyboard Fighting is always on," +msgstr "* Tastatur-Steuerung der Kämpfe ist immer an," + +#: engines/scumm/help.cpp:296 +msgid " so despite the in-game message this" +msgstr " demnach wird trotz der Meldung im Spiel" + +#: engines/scumm/help.cpp:297 +msgid " actually toggles Mouse Fighting Off/On" +msgstr " die Maus-Steuerung der Kämpfe ein-/ausgeschaltet" + +#: engines/scumm/help.cpp:304 +msgid "Fighting controls (numpad):" +msgstr "Kampfsteuerung (Ziffernblock):" + +#: engines/scumm/help.cpp:305 engines/scumm/help.cpp:306 +#: engines/scumm/help.cpp:307 +msgid "Step back" +msgstr "Schritt zurück" + +#: engines/scumm/help.cpp:308 +msgid "Block high" +msgstr "Deckung oben" + +#: engines/scumm/help.cpp:309 +msgid "Block middle" +msgstr "Deckung Mitte" + +#: engines/scumm/help.cpp:310 +msgid "Block low" +msgstr "Deckung unten" + +#: engines/scumm/help.cpp:311 +msgid "Punch high" +msgstr "Schlag oben" + +#: engines/scumm/help.cpp:312 +msgid "Punch middle" +msgstr "Schlag Mitte" + +#: engines/scumm/help.cpp:313 +msgid "Punch low" +msgstr "Schlag unten" + +#: engines/scumm/help.cpp:315 +msgid "Sucker punch" +msgstr "Unerwarteter Schlag" + +#: engines/scumm/help.cpp:318 +msgid "These are for Indy on left." +msgstr "Dies gilt für Indy links." + +#: engines/scumm/help.cpp:319 +msgid "When Indy is on the right," +msgstr "Wenn Indy rechts steht," + +#: engines/scumm/help.cpp:320 +msgid "7, 4, and 1 are switched with" +msgstr "werden 7, 4 und 1 je mit" + +#: engines/scumm/help.cpp:321 +msgid "9, 6, and 3, respectively." +msgstr "9, 6 und 3 vertauscht." + +#: engines/scumm/help.cpp:328 +msgid "Biplane controls (numpad):" +msgstr "Doppeldecker (Ziffernblock):" + +#: engines/scumm/help.cpp:329 +msgid "Fly to upper left" +msgstr "Nach oben links fliegen" + +#: engines/scumm/help.cpp:330 +msgid "Fly to left" +msgstr "Nach links fliegen" + +#: engines/scumm/help.cpp:331 +msgid "Fly to lower left" +msgstr "Nach unten links fliegen" + +#: engines/scumm/help.cpp:332 +msgid "Fly upwards" +msgstr "Nach oben fliegen" + +#: engines/scumm/help.cpp:333 +msgid "Fly straight" +msgstr "Geradeaus fliegen" + +#: engines/scumm/help.cpp:334 +msgid "Fly down" +msgstr "Nach unten fliegen" + +#: engines/scumm/help.cpp:335 +msgid "Fly to upper right" +msgstr "Nach oben rechts fliegen" + +#: engines/scumm/help.cpp:336 +msgid "Fly to right" +msgstr "Nach rechts fliegen" + +#: engines/scumm/help.cpp:337 +msgid "Fly to lower right" +msgstr "Nach unten rechts fliegen" + +#: engines/scumm/input.cpp:578 +msgid "Snap scroll on" +msgstr "Blättern einschalten" + +#: engines/scumm/input.cpp:580 +msgid "Snap scroll off" +msgstr "Blättern ausschalten" + +#: engines/scumm/input.cpp:593 +msgid "Music volume: " +msgstr "Musiklautstärke: " + +#: engines/scumm/input.cpp:610 +msgid "Subtitle speed: " +msgstr "Untertitel-Tempo: " + +#: engines/scumm/scumm.cpp:1883 +#, c-format +msgid "" +"Native MIDI support requires the Roland Upgrade from LucasArts,\n" +"but %s is missing. Using AdLib instead." +msgstr "" +"Systemeigene MIDI-Ünterstützung erfordert das\n" +"Roland-Upgrade von LucasArts, aber %s\n" +"fehlt. Stattdessen wird AdLib verwendet." + +#: engines/scumm/scumm.cpp:2742 +msgid "" +"Usually, Maniac Mansion would start now. But for that to work, the game " +"files for Maniac Mansion have to be in the 'Maniac' directory inside the " +"Tentacle game directory, and the game has to be added to ScummVM." +msgstr "" +"Normalerweise würde jetzt Maniac Mansion starten. ScummVM kann das jedoch " +"noch nicht. Um dieses Spiel zu spielen, klicken Sie auf \"Spiel hinzufügen\" " +"im Startmenü von ScummVM und wählen das Verzeichnis \"Maniac\" im " +"Verzeichnis dieses Spiels aus." + +#: engines/scumm/players/player_v3m.cpp:129 +msgid "" +"Could not find the 'Loom' Macintosh executable to read the\n" +"instruments from. Music will be disabled." +msgstr "" +"Macintosh-Programmdatei für Instrumente in \"Loom\" nicht\n" +"gefunden. Musik wird abgeschaltet." + +#: engines/scumm/players/player_v5m.cpp:107 +msgid "" +"Could not find the 'Monkey Island' Macintosh executable to read the\n" +"instruments from. Music will be disabled." +msgstr "" +"Macintosh-Programmdatei für Instrumente in \"Monkey Island\" nicht\n" +"gefunden. Musik wird abgeschaltet." + +#: engines/sherlock/detection.cpp:81 +msgid "Pixellated scene transitions" +msgstr "Verpixelte Szenenübergänge" + +#: engines/sherlock/detection.cpp:82 +msgid "When changing scenes, a randomized pixel transition is done" +msgstr "Bei Szenenwechseln wird ein zufälliger Pixelübergang verwendet" + +#: engines/sherlock/detection.cpp:91 +msgid "Don't show hotspots when moving mouse" +msgstr "Bei Mausbewegung keine Hotspots anzeigen" + +#: engines/sherlock/detection.cpp:92 +msgid "" +"Only show hotspot names after you actually click on a hotspot or action " +"button" +msgstr "" +"Zeigt Hotspot-Namen nur nach Klick auf selbigen oder auf einen Aktionspunkt" + +#: engines/sherlock/detection.cpp:101 +msgid "Show character portraits" +msgstr "Figurenportraits zeigen" + +#: engines/sherlock/detection.cpp:102 +msgid "Show portraits for the characters when conversing" +msgstr "Zeigt Portraits der Figuren bei Gesprächen" + +#: engines/sherlock/detection.cpp:111 +msgid "Slide dialogs into view" +msgstr "Menüs in Blickfeld gleiten lassen" + +#: engines/sherlock/detection.cpp:112 +msgid "Slide UI dialogs into view, rather than simply showing them immediately" +msgstr "Lässt Menüs in Blickfeld gleiten anstatt sie einfach sofort anzuzeigen" + +#: engines/sherlock/detection.cpp:121 +msgid "Transparent windows" +msgstr "Transparente Fenster" + +#: engines/sherlock/detection.cpp:122 +msgid "Show windows with a partially transparent background" +msgstr "Zeigt Fenster mit teilweise transparentem Hintergrund" + +#: engines/sky/compact.cpp:141 +msgid "The \"sky.cpt\" engine data file has an incorrect size." +msgstr "Die Engine-Datendatei \"sky.cpt\" hat eine falsche Größe." + +#: engines/sky/detection.cpp:44 +msgid "Floppy intro" +msgstr "Vorspann der Diskettenversion" + +#: engines/sky/detection.cpp:45 +msgid "Use the floppy version's intro (CD version only)" +msgstr "Verwendet den Vorspann der Diskettenversion (nur bei CD-Version)" + +#: engines/supernova/supernova.cpp:194 +#, c-format +msgid "" +"Incorrect version of the '%s' engine data file found. Expected %d but got %d." +msgstr "" +"Falsche Version der Engine-Datendatei '%s' gefunden. %d erwartet, aber %d " +"bekommen." + +#: engines/supernova/supernova.cpp:220 +#, c-format +msgid "Unable to locate the text for %s language in '%s' engine data file." +msgstr "" +"Der Text für die Sprache %s konnte nicht in der Engine-Datendatei '%s' " +"gefunden werden." + +#: engines/supernova/supernova.cpp:441 +#, c-format +msgid "Unable to find '%s' in game folder." +msgstr "'%s' konnte im Spiel-Ordner nicht gefunden werden." + +#: engines/sword1/animation.cpp:524 +#, c-format +msgid "PSX stream cutscene '%s' cannot be played in paletted mode" +msgstr "" +"PSX-Zwischensequenz \"%s\" kann in Palettenmodus nicht wiedergegeben werden" + +#: engines/sword1/animation.cpp:545 engines/sword2/animation.cpp:445 +msgid "DXA cutscenes found but ScummVM has been built without zlib" +msgstr "" +"DXA-Zwischensequenzen gefunden, aber ScummVM wurde ohne Zlib-Unterstützung " +"erstellt" + +#: engines/sword1/animation.cpp:561 engines/sword2/animation.cpp:461 +msgid "" +"MPEG-2 cutscenes found but ScummVM has been built without MPEG-2 support" +msgstr "" +"MPEG-2-Zwischensequenzen gefunden, aber ScummVM wurde ohne Unterstützung für " +"MPEG-2-Videos erstellt" + +#: engines/sword1/animation.cpp:568 engines/sword2/animation.cpp:470 +#, c-format +msgid "Cutscene '%s' not found" +msgstr "Zwischensequenz \"%s\" nicht gefunden" + +#: engines/sword1/control.cpp:885 +msgid "" +"ScummVM found that you have old saved games for Broken Sword 1 that should " +"be converted.\n" +"The old saved game format is no longer supported, so you will not be able to " +"load your games if you don't convert them.\n" +"\n" +"Press OK to convert them now, otherwise you will be asked again the next " +"time you start the game.\n" +msgstr "" +"ScummVM hat erkannt, dass Sie alte Spielstände von Baphomets Fluch 1 haben, " +"die umgewandelt werden sollten.\n" +"Das alte Speicherformat wird nicht mehr unterstützt, daher können Sie diese " +"Spielstände unkonvertiert nicht laden.\n" +"\n" +"Klicken Sie auf OK, um diese jetzt umzuwandeln, sonst werden Sie erneut " +"gefragt, wenn Sie nächstes Mal dieses Spiel starten.\n" + +#: engines/sword1/control.cpp:1259 +#, c-format +msgid "" +"Target new saved game already exists!\n" +"Would you like to keep the old saved game (%s) or the new one (%s)?\n" +msgstr "" +"Die für den neuen Spielstand vorgesehene Datei existiert bereits!\n" +"Möchten Sie den alten Speicherstand (%s) oder den neuen (%s) behalten?\n" + +#: engines/sword1/control.cpp:1262 +msgid "Keep the old one" +msgstr "Den alten behalten" + +#: engines/sword1/control.cpp:1262 +msgid "Keep the new one" +msgstr "Den neuen behalten" + +#: engines/sword1/logic.cpp:1633 +msgid "This is the end of the Broken Sword 1 Demo" +msgstr "Das ist das Ende der Demo von Broken Sword 1 (Baphomets Fluch 1)" + +#: engines/sword2/animation.cpp:425 +msgid "" +"PSX cutscenes found but ScummVM has been built without RGB color support" +msgstr "" +"PSX-Zwischensequenzen gefunden, aber ScummVM wurde ohne Unterstützung für " +"RGB-Farben erstellt" + +#: engines/sword2/sword2.cpp:79 +msgid "Show object labels" +msgstr "Objektnamen zeigen" + +#: engines/sword2/sword2.cpp:80 +msgid "Show labels for objects on mouse hover" +msgstr "Zeigt Objektbeschriftungen bei Mausberührung an" + +#: engines/sword25/detection.cpp:46 +msgid "Use English speech" +msgstr "Verwende englische Sprachausgabe" + +#: engines/sword25/detection.cpp:47 +msgid "" +"Use English speech instead of German for every language other than German" +msgstr "" +"Verwende englische Sprachausgabe anstelle der deutschen, wenn eine andere " +"Sprache als Deutsch verwendet wird" + +#: engines/teenagent/resources.cpp:118 +msgid "" +"The teenagent.dat file is compressed and zlib hasn't been included in this " +"executable. Please decompress it" +msgstr "" +"Die Datei \"teenagent.dat\" ist gepackt und zlib zum Entpacken wurde in " +"dieser ausführbaren Datei nicht miteingebunden. Bitte entpacken Sie die Datei" + +#: engines/tony/tony.cpp:258 +#, c-format +msgid "Font variant not present in '%s' engine data file." +msgstr "Schriftartvariante in Engine-Datendatei '%s' nicht vorhanden." + +#: engines/toon/toon.cpp:222 +#, c-format +msgid "Saved game in slot #%d " +msgstr "Spiel in Speicherplatz #%d gespeichert " + +#: engines/toon/toon.cpp:226 +#, c-format +msgid "Could not quick save into slot #%d" +msgstr "Speichern im Schnellspeicherplatz #%d fehlgeschlagen" + +#: engines/toon/toon.cpp:239 +#, c-format +msgid "Saved game #%d quick loaded" +msgstr "Spielstand #%d geladen" + +#: engines/toon/toon.cpp:243 +#, c-format +msgid "Could not quick load the saved game #%d" +msgstr "Schnellladen des Spielstandes #%d nicht möglich" + +#: engines/wintermute/detection.cpp:59 +msgid "Show FPS-counter" +msgstr "FPS-Zähler anzeigen" + +#: engines/wintermute/detection.cpp:60 +msgid "Show the current number of frames per second in the upper left corner" +msgstr "" +"Zeige die aktuelle Anzahl von Bildern pro Sekunde in der oberen linken Ecke" + +#: engines/wintermute/detection.cpp:69 +msgid "Sprite bilinear filtering (SLOW)" +msgstr "Bilineare Filterung für Sprites (LANGSAM)" + +#: engines/wintermute/detection.cpp:70 +msgid "Apply bilinear filtering to individual sprites" +msgstr "Bilineare Filterung auf einzelne Sprites anwenden" + +#: engines/wintermute/wintermute.cpp:153 +msgid "This game requires PNG, JPEG and Vorbis support." +msgstr "Dieses Spiel benötigt Unterstützung für PNG, JPEG und Vorbis." + +#: engines/wintermute/wintermute.cpp:164 +msgid "" +"This game requires 3D characters support, which is out of ScummVM's scope." +msgstr "" +"Dieses Spiel benötigt die Unterstützung von 3D-Charakteren, welche nicht in " +"ScummVM enthalten ist." + +#: engines/xeen/detection.cpp:89 +msgid "Show item costs in standard inventory mode" +msgstr "Item-Kosten im Standard-Inventarmodus anzeigen" + +#: engines/xeen/detection.cpp:90 +msgid "" +"Shows item costs in standard inventory mode, allowing the value of items to " +"be compared" +msgstr "" +"Zeigt die Gegenstandskosten im Standard-Inventarmodus an, um einen Vergleich " +"der Gegenstände zu ermöglichen" + +#: engines/xeen/detection.cpp:99 +msgid "More durable armor" +msgstr "Widerstandsfähigere Rüstung" + +#: engines/xeen/detection.cpp:100 +msgid "Armor won't break until character is at -80HP, rather than merely -10HP" +msgstr "" +"Rüstung zerbricht erst, wenn der Charakter -80HP besitzt und nicht bereits " +"bei -10HP" + +#: engines/zvision/detection_tables.h:61 +msgid "Double FPS" +msgstr "FPS verdoppeln" + +#: engines/zvision/detection_tables.h:62 +msgid "Increase framerate from 30 to 60 FPS" +msgstr "Bilder pro Sekunde im Spiel von 30 auf 60 erhöhen" + +#: engines/zvision/detection_tables.h:71 +msgid "Enable Venus" +msgstr "Venus aktivieren" + +#: engines/zvision/detection_tables.h:72 +msgid "Enable the Venus help system" +msgstr "Aktiviere das Venus-Hilfesystem" + +#: engines/zvision/detection_tables.h:81 +msgid "Disable animation while turning" +msgstr "Animation während Drehen ausschalten" + +#: engines/zvision/detection_tables.h:82 +msgid "Disable animation while turning in panorama mode" +msgstr "Animation während Drehen im Panorama-Modus ausschalten" + +#: engines/zvision/detection_tables.h:91 +msgid "Use high resolution MPEG video" +msgstr "Verwende hochauflösende MPEG-Filme" + +#: engines/zvision/detection_tables.h:92 +msgid "Use MPEG video from the DVD version instead of lower resolution AVI" +msgstr "" +"Verwende die hochauflösendenden MPEG-Filme der DVD-Version anstelle der " +"niedriger aufgelösten AVI-Filme" + +#: engines/zvision/file/save_manager.cpp:226 +#, c-format +msgid "" +"This saved game uses version %u, but this engine only supports up to version " +"%d. You will need an updated version of the engine to use this saved game." +msgstr "" +"Dieser Spielstand verwendet Version %u, diese Engine unterstützt jedoch nur " +"Spielstände bis zu Version %d. Sie benötigen eine aktualisierte Version der " +"Engine, um diesen Spielstand zu verwenden." + +#~ msgid "Unnamed savegame" +#~ msgstr "Unbenannter Spielstand" + +#~ msgid "Windowed mode" +#~ msgstr "Fenstermodus" + +#~ msgid "" +#~ "A known buggy game script has been detected, which could prevent you from " +#~ "progressing later on in the game, during the sequence with the Green " +#~ "Man's riddles. Please, apply the latest patch for this game by Sierra to " +#~ "avoid possible problems." +#~ msgstr "" +#~ "Ein bekannter Fehler im Spiel-Skript wurde erkannt, der möglicherweise " +#~ "den weiteren Spielfortschritt innerhalb des \"Green Man\"-Rätsels " +#~ "verhindert. Bitte wenden Sie den letzten Patch an, den Sierra für dieses " +#~ "Spiel veröffentlicht hat, um mögliche Probleme zu vermeiden." + +#~ msgctxt "lowres" +#~ msgid "Music Device:" +#~ msgstr "Musikgerät:" + +#~ msgctxt "lowres" +#~ msgid "Text and Speech:" +#~ msgstr "Text u. Sprache:" + +#~ msgid "AdLib Emulator" +#~ msgstr "AdLib-Emulator" + +#~ msgid "Use the original save/load screens instead of the ScummVM interface" +#~ msgstr "" +#~ "Verwendet die originalen Menüs zum Speichern und Laden statt der von " +#~ "ScummVM" + +#~ msgid "(You can always enable it in the options dialog on the Misc tab)" +#~ msgstr "" +#~ "(Sie können diese auch jederzeit im Options-Dialog unter dem Reiter " +#~ "\"Sonstiges\" aktivieren)" + +#~ msgid "Check for updates automatically" +#~ msgstr "Automatisch nach Aktualisierungen suchen" + +#~ msgid "8 kHz" +#~ msgstr "8 kHz" + +#~ msgid "11 kHz" +#~ msgstr "11 kHz" + +#~ msgid "22 kHz" +#~ msgstr "22 kHz" + +#~ msgid "44 kHz" +#~ msgstr "44 kHz" + +#~ msgid "48 kHz" +#~ msgstr "48 kHz" + +#~ msgid "Output rate:" +#~ msgstr "Ausgabefrequenz:" + +#~ msgid "" +#~ "Higher value specifies better sound quality but may be not supported by " +#~ "your soundcard" +#~ msgstr "" +#~ "Höhere Werte bewirken eine bessere Soundqualität, werden aber " +#~ "möglicherweise nicht von jeder Soundkarte unterstützt" + +# Nicht übersetzen, da diese Nachricht nur für nicht-lateinische Sprachen relevant ist. +#~ msgid "" +#~ "The theme you selected does not support your current language. If you " +#~ "want to use this theme you need to switch to another language first." +#~ msgstr "" +#~ "Das ausgewählte Thema unterstützt nicht die aktuelle Sprache. Wenn Sie " +#~ "dieses Thema benutzen wollen, müssen Sie erst zu einer anderen Sprache " +#~ "wechseln." + +#~ msgid "3" +#~ msgstr "3" + +#~ msgid "5" +#~ msgstr "5" + +#~ msgid "8" +#~ msgstr "8" + +#~ msgid "10" +#~ msgstr "10" + +#~ msgid "13" +#~ msgstr "13" + +#~ msgid "15" +#~ msgstr "15" + +#~ msgid "18" +#~ msgstr "18" + +#~ msgid "20" +#~ msgstr "20" + +#, fuzzy +#~ msgid "Speed multiplier for mouse emulation" +#~ msgstr "Geschwindigkeitsfaktor für Maus-Emulation" + +#~ msgctxt "lowres" +#~ msgid "Mouse Speed:" +#~ msgstr "Maus-Geschwindigkeit:" + +#~ msgid "" +#~ "Unable to find \"sky.cpt\" file!\n" +#~ "Please download it from www.scummvm.org" +#~ msgstr "" +#~ "Konnte \"sky.cpt\" nicht finden!\n" +#~ "Bitte laden Sie die Datei von\n" +#~ "www.scummvm.org herunter" + +#~ msgid "" +#~ "The \"sky.cpt\" file has an incorrect size.\n" +#~ "Please (re)download it from www.scummvm.org" +#~ msgstr "" +#~ "Die Datei \"sky.cpt\" hat eine ungültige Größe.\n" +#~ "Bitte laden Sie diese Datei (erneut) von\n" +#~ "www.scummvm.org herunter" + +#~ msgid "" +#~ "You're missing the 'teenagent.dat' file. Get it from the ScummVM website" +#~ msgstr "" +#~ "Ihnen fehlt die Datei \"teenagent.dat\". Laden Sie sich diese von der " +#~ "ScummVM-Website unter https://www.scummvm.org herunter" + +#~ msgid "You're missing the 'toon.dat' file. Get it from the ScummVM website" +#~ msgstr "" +#~ "Ihnen fehlt die Datei \"toon.dat\". Laden Sie sich diese von der ScummVM-" +#~ "Website unter https://www.scummvm.org herunter" + +#~ msgid "File 'toon.dat' is corrupt. Get it from the ScummVM website" +#~ msgstr "" +#~ "Die Datei \"toon.dat\" ist defekt. Laden Sie diese von der ScummVM-" +#~ "Website herunter" + +#~ msgid "" +#~ "File 'toon.dat' is wrong version. Expected %d.%d but got %d.%d. Get it " +#~ "from the ScummVM website" +#~ msgstr "" +#~ "Falsche Version der Datei 'toon.dat'. %d.%d wurde erwartet, aber %d.%d " +#~ "erhalten. Laden Sie die Datei von der ScummVM-Website unter http://www." +#~ "scummvm.org herunter" + +#~ msgid "Invalid save file name" +#~ msgstr "Ungültiger Spielstandname" + +#~ msgid "Use original savegame dialog" +#~ msgstr "Originale Spielstand-Menüs verwenden" + +#~ msgid "" +#~ "Files button in-game shows original savegame dialog rather than the " +#~ "ScummVM menu" +#~ msgstr "" +#~ "Dateien-Schaltfläche im Spiel zeigt originales Spielstand-Menü statt dem " +#~ "von ScummVM." + +#~ msgid "The game in '%s' seems to be unknown." +#~ msgstr "Das Spiel im Verzeichnis \"%s\" scheint nicht bekannt zu sein." + +#~ msgid "" +#~ "Please, report the following data to the ScummVM team along with name" +#~ msgstr "" +#~ "Bitte geben Sie die folgenden Daten auf Englisch an das ScummVM-Team " +#~ "weiter sowie" + +#~ msgid "of the game you tried to add and its version/language/etc.:" +#~ msgstr "" +#~ "den Namen des Spiels, das Sie hinzufügen wollten, als auch die Version/" +#~ "Sprache/usw.:" + +#~ msgid "You have to restart ScummVM before your changes will take effect." +#~ msgstr "" +#~ "Sie müssen ScummVM neu starten, damit die Änderungen wirksam werden." + +#~ msgid "OpenGL (No filtering)" +#~ msgstr "OpenGL (ohne Filter)" + +#~ msgid "Specifies where Files Manager can access to" +#~ msgstr "Legt fest, auf welches Verzeichnis der Dateimanager zugreifen darf." + +#~ msgid "When this storage did saves sync last time" +#~ msgstr "Zeitpunkt der letzten Synchronisierung dieses Cloud-Speichers" + +#~ msgid "EGA undithering" +#~ msgstr "Antifehlerdiffusion für EGA" + +#~ msgid "Enable undithering in EGA games" +#~ msgstr "Aktiviert die Aufhebung der Fehlerdiffusion in EGA-Spielen." + +#~ msgid "MPEG-2 cutscenes found but ScummVM has been built without MPEG-2" +#~ msgstr "" +#~ "MPEG-2-Zwischensequenzen gefunden, aber ScummVM wurde ohne Unterstützung " +#~ "für MPEG-2-Videos erstellt." + +#~ msgctxt "lowres" +#~ msgid "Mass Add..." +#~ msgstr "Durchsuchen" + +#~ msgid "" +#~ "Turns off General MIDI mapping for games with Roland MT-32 soundtrack" +#~ msgstr "" +#~ "Schaltet die General-MIDI-Zuweisung für Spiele mit Roland-MT-32-Audiospur " +#~ "aus." + +#~ msgid "Standard (16bpp)" +#~ msgstr "Standard (16bpp)" + +#~ msgid "MPEG2 cutscenes are no longer supported" +#~ msgstr "MPEG2-Zwischensequenzen werden nicht mehr unterstützt." + +#~ msgid "OpenGL Conserve" +#~ msgstr "OpenGL: beibehalten" + +#~ msgid "OpenGL Original" +#~ msgstr "OpenGL: original" + +#~ msgid "Current display mode" +#~ msgstr "Aktueller Grafikmodus" + +#~ msgid "Current scale" +#~ msgstr "Aktueller Vergrößerungsfaktor" + +#~ msgid "Active filter mode: Linear" +#~ msgstr "Aktiver Filtermodus: linear" + +#~ msgid "Active filter mode: Nearest" +#~ msgstr "Aktiver Filtermodus: nächste Nachbarn" + +#~ msgid "" +#~ "Your game version has been detected using filename matching as a variant " +#~ "of %s." +#~ msgstr "" +#~ "Ihre Spielversion wurde durch Dateinamen-Übereinstimmung als Variante von " +#~ "%s erkannt." + +#~ msgid "Command line argument not processed" +#~ msgstr "Argument in Kommandozeile nicht verarbeitet" diff --git a/po/module.mk b/po/module.mk index e58ff9fa80f..68f7c03ee0c 100644 --- a/po/module.mk +++ b/po/module.mk @@ -46,7 +46,7 @@ updatepot: fi; # ResidualVM specific end <- -translations-dat: devtools/create_translations $(POFILES) $(CPFILES) +translations-dat: devtools/create_translations devtools/create_translations/create_translations $(POFILES) $(CPFILES) mv translations.dat $(srcdir)/gui/themes/ diff --git a/ports.mk b/ports.mk index c2a7569e689..07db5860dac 100644 --- a/ports.mk +++ b/ports.mk @@ -17,7 +17,7 @@ install: $(INSTALL) -d "$(DESTDIR)$(docdir)" $(INSTALL) -c -m 644 $(DIST_FILES_DOCS) "$(DESTDIR)$(docdir)" $(INSTALL) -d "$(DESTDIR)$(datadir)" - $(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_NETWORKING) $(DIST_FILES_ENGINEDATA) "$(DESTDIR)$(datadir)/" + $(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_NETWORKING) $(DIST_FILES_VKEYBD) $(DIST_FILES_ENGINEDATA) "$(DESTDIR)$(datadir)/" $(INSTALL) -d "$(DESTDIR)$(datarootdir)/applications" $(INSTALL) -c -m 644 "$(srcdir)/dists/residualvm.desktop" "$(DESTDIR)$(datarootdir)/applications/residualvm.desktop" $(INSTALL) -d "$(DESTDIR)$(datarootdir)/appdata" @@ -44,7 +44,7 @@ install-strip: $(INSTALL) -d "$(DESTDIR)$(docdir)" $(INSTALL) -c -m 644 $(DIST_FILES_DOCS) "$(DESTDIR)$(docdir)" $(INSTALL) -d "$(DESTDIR)$(datadir)" - $(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_NETWORKING) $(DIST_FILES_ENGINEDATA) "$(DESTDIR)$(datadir)/" + $(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_NETWORKING) $(DIST_FILES_VKEYBD) $(DIST_FILES_ENGINEDATA) "$(DESTDIR)$(datadir)/" $(INSTALL) -d "$(DESTDIR)$(datarootdir)/applications" $(INSTALL) -c -m 644 "$(srcdir)/dists/residualvm.desktop" "$(DESTDIR)$(datarootdir)/applications/residualvm.desktop" $(INSTALL) -d "$(DESTDIR)$(datarootdir)/appdata" @@ -78,6 +78,8 @@ deb: debian/prepare fakeroot debian/rules binary +# Special target to create a application wrapper for Mac OS X + ifdef USE_DOCKTILEPLUGIN # The NsDockTilePlugIn needs to be compiled in both 32 and 64 bits irrespective of how ScummVM itself is compiled. @@ -165,6 +167,9 @@ ifdef DIST_FILES_NETWORKING endif ifdef DIST_FILES_ENGINEDATA cp $(DIST_FILES_ENGINEDATA) $(bundle_name)/ +endif +ifdef DIST_FILES_VKEYBD + cp $(DIST_FILES_VKEYBD) $(bundle_name)/ endif $(STRIP) residualvm ldid -S residualvm @@ -176,8 +181,9 @@ endif # Location of static libs for the iPhone ifneq ($(BACKEND), iphone) -# Static libaries, used for the residualvm-static and iphone targets -OSX_STATIC_LIBS := `$(SDLCONFIG) --static-libs` +ifneq ($(BACKEND), ios7) +# Static libaries, used for the scummvm-static and iphone targets +OSX_STATIC_LIBS := `$(SDLCONFIG) --prefix=$(STATICLIBPATH) --static-libs` ifdef USE_SDL_NET ifdef USE_SDL2 OSX_STATIC_LIBS += $(STATICLIBPATH)/lib/libSDL2_net.a @@ -188,6 +194,7 @@ endif # With sdl2-config we don't always get the OpenGL framework OSX_STATIC_LIBS += -framework OpenGL endif +endif ifdef USE_LIBCURL OSX_STATIC_LIBS += -lcurl @@ -262,11 +269,13 @@ OSX_ZLIB ?= $(STATICLIBPATH)/lib/libz.a endif ifdef USE_SPARKLE +ifdef MACOSX ifneq ($(SPARKLEPATH),) OSX_STATIC_LIBS += -F$(SPARKLEPATH) endif OSX_STATIC_LIBS += -framework Sparkle -Wl,-rpath,@loader_path/../Frameworks endif +endif # ResidualVM specific: ifdef USE_GLEW @@ -350,7 +359,7 @@ endif @echo Creating Code::Blocks project files... @cd $(srcdir)/dists/codeblocks && ../../devtools/create_project/create_project ../.. --codeblocks >/dev/null && git add -f engines/plugins_table.h *.workspace *.cbp @echo Creating MSVC project files... - @cd $(srcdir)/dists/msvc && ../../devtools/create_project/create_project ../.. --msvc >/dev/null && git add -f engines/plugins_table.h *.sln *.vcxproj *.vcxproj.filters *.props + @cd $(srcdir)/dists/msvc && ../../devtools/create_project/create_project ../.. --msvc-version 12 --msvc >/dev/null && git add -f engines/plugins_table.h *.sln *.vcxproj *.vcxproj.filters *.props @echo @echo All is done. @echo Now run