diff options
Diffstat (limited to 'backends/platform/tizen/system.cpp')
-rw-r--r-- | backends/platform/tizen/system.cpp | 547 |
1 files changed, 547 insertions, 0 deletions
diff --git a/backends/platform/tizen/system.cpp b/backends/platform/tizen/system.cpp new file mode 100644 index 0000000000..54d92146e5 --- /dev/null +++ b/backends/platform/tizen/system.cpp @@ -0,0 +1,547 @@ +/* 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. + * + */ + +#include <FUiCtrlMessageBox.h> +#include <FLocales.h> + +#include "common/config-manager.h" +#include "common/file.h" +#include "engines/engine.h" +#include "graphics/font.h" +#include "graphics/fontman.h" +#include "graphics/fonts/bdf.h" +#include "backends/saves/default/default-saves.h" +#include "backends/events/default/default-events.h" +#include "backends/audiocd/default/default-audiocd.h" +#include "backends/mutex/mutex.h" +#include "backends/fs/fs-factory.h" +#include "backends/timer/tizen/timer.h" + +#include "backends/platform/tizen/form.h" +#include "backends/platform/tizen/system.h" +#include "backends/platform/tizen/graphics.h" +#include "backends/platform/tizen/audio.h" + +using namespace Tizen::Base; +using namespace Tizen::Base::Runtime; +using namespace Tizen::Locales; +using namespace Tizen::Ui; +using namespace Tizen::Ui::Controls; +using namespace Tizen::System; + +#define DEFAULT_CONFIG_FILE "scummvm.ini" +#define MUTEX_BUFFER_SIZE 5 + +// +// TizenFilesystemFactory +// +class TizenFilesystemFactory : public FilesystemFactory { + AbstractFSNode *makeRootFileNode() const; + AbstractFSNode *makeCurrentDirectoryFileNode() const; + AbstractFSNode *makeFileNodePath(const Common::String &path) const; +}; + +AbstractFSNode *TizenFilesystemFactory::makeRootFileNode() const { + return new TizenFilesystemNode("/"); +} + +AbstractFSNode *TizenFilesystemFactory::makeCurrentDirectoryFileNode() const { + return new TizenFilesystemNode("/"); +} + +AbstractFSNode *TizenFilesystemFactory::makeFileNodePath(const Common::String &path) const { + AppAssert(!path.empty()); + return new TizenFilesystemNode(path); +} + +// +// TizenSaveFileManager +// +struct TizenSaveFileManager : public DefaultSaveFileManager { + bool removeSavefile(const Common::String &filename); +}; + +bool TizenSaveFileManager::removeSavefile(const Common::String &filename) { + Common::String savePathName = getSavePath(); + + checkPath(Common::FSNode(savePathName)); + if (getError().getCode() != Common::kNoError) { + return false; + } + + // recreate FSNode since checkPath may have changed/created the directory + Common::FSNode savePath(savePathName); + Common::FSNode file = savePath.getChild(filename); + + String unicodeFileName; + StringUtil::Utf8ToString(file.getPath().c_str(), unicodeFileName); + + switch (Tizen::Io::File::Remove(unicodeFileName)) { + case E_SUCCESS: + return true; + + case E_ILLEGAL_ACCESS: + setError(Common::kWritePermissionDenied, "Search or write permission denied: " + + file.getName()); + break; + + default: + setError(Common::kPathDoesNotExist, "removeSavefile: '" + file.getName() + + "' does not exist or path is invalid"); + break; + } + + return false; +} + +// +// TizenMutexManager +// +struct TizenMutexManager : public MutexManager { + TizenMutexManager(); + ~TizenMutexManager(); + OSystem::MutexRef createMutex(); + void lockMutex(OSystem::MutexRef mutex); + void unlockMutex(OSystem::MutexRef mutex); + void deleteMutex(OSystem::MutexRef mutex); +private: + Mutex *_buffer[MUTEX_BUFFER_SIZE]; +}; + +TizenMutexManager::TizenMutexManager() { + for (int i = 0; i < MUTEX_BUFFER_SIZE; i++) { + _buffer[i] = NULL; + } +} + +TizenMutexManager::~TizenMutexManager() { + for (int i = 0; i < MUTEX_BUFFER_SIZE; i++) { + if (_buffer[i] != NULL) { + delete _buffer[i]; + } + } +} + +OSystem::MutexRef TizenMutexManager::createMutex() { + Mutex *mutex = new Mutex(); + mutex->Create(); + + for (int i = 0; i < MUTEX_BUFFER_SIZE; i++) { + if (_buffer[i] == NULL) { + _buffer[i] = mutex; + break; + } + } + + return (OSystem::MutexRef) mutex; +} + +void TizenMutexManager::lockMutex(OSystem::MutexRef mutex) { + Mutex *m = (Mutex *)mutex; + m->Acquire(); +} + +void TizenMutexManager::unlockMutex(OSystem::MutexRef mutex) { + Mutex *m = (Mutex *)mutex; + m->Release(); +} + +void TizenMutexManager::deleteMutex(OSystem::MutexRef mutex) { + Mutex *m = (Mutex *)mutex; + + for (int i = 0; i < MUTEX_BUFFER_SIZE; i++) { + if (_buffer[i] == m) { + _buffer[i] = NULL; + } + } + + delete m; +} + +// +// TizenEventManager +// +struct TizenEventManager : public DefaultEventManager { + TizenEventManager(Common::EventSource *boss); + void init(); + int shouldQuit() const; +}; + +TizenEventManager::TizenEventManager(Common::EventSource *boss) : + DefaultEventManager(boss) { +} + +void TizenEventManager::init() { + DefaultEventManager::init(); + + // theme and vkbd should have now loaded - clear the splash screen + TizenSystem *system = (TizenSystem *)g_system; + TizenGraphicsManager *graphics = system->getGraphics(); + if (graphics) { + graphics->setReady(); + } +} + +int TizenEventManager::shouldQuit() const { + TizenSystem *system = (TizenSystem *)g_system; + return DefaultEventManager::shouldQuit() || system->isClosing(); +} + +// +// TizenAppFrame - avoid drawing the misplaced UiTheme at startup +// +struct TizenAppFrame : Frame { + result OnDraw(void) { + logEntered(); + TizenAppForm *form = (TizenAppForm *)GetCurrentForm(); + if (form->isStarting()) { + Canvas *canvas = GetCanvasN(); + canvas->SetBackgroundColor(Color::GetColor(COLOR_ID_BLACK)); + canvas->Clear(); + delete canvas; + } + return E_SUCCESS; + } +}; + +// +// TizenSystem +// +TizenSystem::TizenSystem(TizenAppForm *appForm) : + _appForm(appForm), + _audioThread(0), + _epoch(0) { +} + +result TizenSystem::Construct(void) { + logEntered(); + + _fsFactory = new TizenFilesystemFactory(); + if (!_fsFactory) { + return E_OUT_OF_MEMORY; + } + + _resourcePath = fromString(App::GetInstance()->GetAppResourcePath()); + return E_SUCCESS; +} + +TizenSystem::~TizenSystem() { + logEntered(); +} + +result TizenSystem::initModules() { + logEntered(); + + _mutexManager = new TizenMutexManager(); + if (!_mutexManager) { + return E_OUT_OF_MEMORY; + } + + _timerManager = new TizenTimerManager(); + if (!_timerManager) { + return E_OUT_OF_MEMORY; + } + + _savefileManager = new TizenSaveFileManager(); + if (!_savefileManager) { + return E_OUT_OF_MEMORY; + } + + _graphicsManager = (GraphicsManager *)new TizenGraphicsManager(_appForm); + if (!_graphicsManager) { + return E_OUT_OF_MEMORY; + } + + // depends on _graphicsManager when ENABLE_VKEYBD enabled + _eventManager = new TizenEventManager(this); + if (!_eventManager) { + return E_OUT_OF_MEMORY; + } + + _audioThread = new AudioThread(); + if (!_audioThread) { + return E_OUT_OF_MEMORY; + } + + _mixer = _audioThread->Construct(this); + if (!_mixer) { + return E_OUT_OF_MEMORY; + } + + _audiocdManager = (AudioCDManager *)new DefaultAudioCDManager(); + if (!_audiocdManager) { + return E_OUT_OF_MEMORY; + } + + if (IsFailed(_audioThread->Start())) { + AppLog("Failed to start audio thread"); + return E_OUT_OF_MEMORY; + } + + logLeaving(); + return E_SUCCESS; +} + +void TizenSystem::initBackend() { + logEntered(); + + Common::String dataPath = fromString(App::GetInstance()->GetAppDataPath()); + + // use the mobile device theme + ConfMan.set("gui_theme", _resourcePath + "scummmodern"); + + // allow tizen virtual keypad pack to be found + ConfMan.set("vkeybdpath", _resourcePath + "vkeybd_bada"); + ConfMan.set("vkeybd_pack_name", "vkeybd_bada"); + + // set default save path to writable area + if (!ConfMan.hasKey("savepath")) { + ConfMan.set("savepath", dataPath); + } + + // default to no auto-save + if (!ConfMan.hasKey("autosave_period")) { + ConfMan.setInt("autosave_period", 0); + } + + ConfMan.registerDefault("fullscreen", true); + ConfMan.registerDefault("aspect_ratio", false); + ConfMan.setBool("confirm_exit", false); + + SystemTime::GetTicks(_epoch); + + if (E_SUCCESS != initModules()) { + AppLog("initModules failed"); + } else { + OSystem::initBackend(); + + // replace kBigGUIFont for the vkbd and on-screen messages + Common::String fontCacheFile = dataPath + "helvR24.fcc"; + TizenFilesystemNode file(fontCacheFile); + if (!file.exists()) { + Common::String bdfFile = _resourcePath + "fonts/helvR24.bdf"; + TizenFilesystemNode file(bdfFile); + if (file.exists()) { + Common::SeekableReadStream *stream = file.createReadStream(); + Common::File fontFile; + if (stream && fontFile.open(stream, bdfFile)) { + Graphics::BdfFont *font = Graphics::BdfFont::loadFont(fontFile); + Graphics::BdfFont::cacheFontData(*font, fontCacheFile); + FontMan.setFont(Graphics::FontManager::kBigGUIFont, font); + } + } + } else { + Common::SeekableReadStream *stream = file.createReadStream(); + Common::File fontFile; + if (stream && fontFile.open(stream, fontCacheFile)) { + Graphics::BdfFont *font = Graphics::BdfFont::loadFromCache(fontFile); + if (font) { + FontMan.setFont(Graphics::FontManager::kBigGUIFont, font); + } + } + } + } + logLeaving(); +} + +void TizenSystem::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) { + // allow translations.dat and game .DAT files to be found + s.addDirectory(_resourcePath, _resourcePath, priority); +} + +void TizenSystem::destroyBackend() { + closeAudio(); + + delete _graphicsManager; + _graphicsManager = NULL; + + delete _savefileManager; + _savefileManager = NULL; + + delete _fsFactory; + _fsFactory = NULL; + + delete _mixer; + _mixer = NULL; + + delete _audiocdManager; + _audiocdManager = NULL; + + delete _timerManager; + _timerManager = NULL; + + delete _eventManager; + _eventManager = NULL; + + delete _mutexManager; + _mutexManager = NULL; +} + +bool TizenSystem::pollEvent(Common::Event &event) { + return _appForm->pollEvent(event); +} + +uint32 TizenSystem::getMillis(bool skipRecord) { + long long result, ticks = 0; + SystemTime::GetTicks(ticks); + result = ticks - _epoch; + return result; +} + +void TizenSystem::delayMillis(uint msecs) { + if (!_appForm->isClosing()) { + Thread::Sleep(msecs); + } +} + +void TizenSystem::updateScreen() { + if (_graphicsManager != NULL) { + _graphicsManager->updateScreen(); + } +} + +void TizenSystem::getTimeAndDate(TimeDate &td) const { + DateTime currentTime; + + if (E_SUCCESS == SystemTime::GetCurrentTime(WALL_TIME, currentTime)) { + td.tm_sec = currentTime.GetSecond(); + td.tm_min = currentTime.GetMinute(); + td.tm_hour = currentTime.GetHour(); + td.tm_mday = currentTime.GetDay(); + td.tm_mon = currentTime.GetMonth(); + td.tm_year = currentTime.GetYear(); + + Calendar *calendar = Calendar::CreateInstanceN(CALENDAR_GREGORIAN); + calendar->SetTime(currentTime); + td.tm_wday = calendar->GetTimeField(TIME_FIELD_DAY_OF_WEEK) - 1; + delete calendar; + } +} + +void TizenSystem::fatalError() { + systemError("ScummVM: Fatal internal error."); +} + +void TizenSystem::exitSystem() { + if (_appForm) { + closeAudio(); + closeGraphics(); + _appForm->exitSystem(); + } +} + +void TizenSystem::logMessage(LogMessageType::Type type, const char *message) { + if (type == LogMessageType::kError) { + systemError(message); + } else { + AppLog(message); + } +} + +Common::SeekableReadStream *TizenSystem::createConfigReadStream() { + TizenFilesystemNode file(fromString(App::GetInstance()->GetAppDataPath()) + DEFAULT_CONFIG_FILE); + return file.createReadStream(); +} + +Common::WriteStream *TizenSystem::createConfigWriteStream() { + TizenFilesystemNode file(fromString(App::GetInstance()->GetAppDataPath()) + DEFAULT_CONFIG_FILE); + return file.createWriteStream(); +} + +void TizenSystem::closeAudio() { + if (_audioThread) { + _audioThread->Quit(); + _audioThread->Join(); + delete _audioThread; + _audioThread = NULL; + } +} + +void TizenSystem::closeGraphics() { + if (_graphicsManager) { + delete _graphicsManager; + _graphicsManager = NULL; + } +} + +void TizenSystem::setMute(bool on) { + // only change mute after eventManager init() has completed + if (_audioThread) { + TizenGraphicsManager *graphics = getGraphics(); + if (graphics && graphics->isReady()) { + _audioThread->setMute(on); + } + } +} + +// +// create the ScummVM system +// +TizenAppForm *systemStart(Tizen::App::Application *app) { + logEntered(); + + Frame *appFrame = new (std::nothrow) TizenAppFrame(); + if (!appFrame || appFrame->Construct() == E_FAILURE) { + AppLog("Failed to create appFrame"); + return NULL; + } + app->AddFrame(*appFrame); + + TizenAppForm *appForm = new TizenAppForm(); + if (!appForm) { + AppLog("Failed to create appForm"); + return NULL; + } + + if (E_SUCCESS != appForm->Construct() || + E_SUCCESS != appFrame->AddControl(*appForm)) { + delete appForm; + AppLog("Failed to construct appForm"); + return NULL; + } + + appFrame->SetCurrentForm(appForm); + logLeaving(); + return appForm; +} + +// +// display a fatal error notification +// +void systemError(const char *message) { + AppLog("Fatal system error: %s", message); + + if (strspn(message, "Config file buggy:") > 0) { + Tizen::Io::File::Remove(DEFAULT_CONFIG_FILE); + Application::GetInstance()->SendUserEvent(USER_MESSAGE_EXIT_ERR_CONFIG, NULL); + } else { + ArrayList *args = new ArrayList(); + args->Construct(); + args->Add(*(new String(message))); + Application::GetInstance()->SendUserEvent(USER_MESSAGE_EXIT_ERR, args); + } + + if (g_system) { + TizenSystem *system = (TizenSystem *)g_system; + system->exitSystem(); + } +} |