diff options
Diffstat (limited to 'src/common/resources/resourcemanager.cpp')
-rw-r--r-- | src/common/resources/resourcemanager.cpp | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/src/common/resources/resourcemanager.cpp b/src/common/resources/resourcemanager.cpp new file mode 100644 index 0000000..5e8627d --- /dev/null +++ b/src/common/resources/resourcemanager.cpp @@ -0,0 +1,212 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2014 Polish Portal of Colobot (PPC) +// * +// * 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 3 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, see http://www.gnu.org/licenses/. + + +#include "common/resources/resourcemanager.h" + +#include "common/config.h" + +#include <physfs.h> + + +CResourceManager::CResourceManager(const char *argv0) +{ + if (PHYSFS_init(argv0)) + { + // TODO error + } +} + + +CResourceManager::~CResourceManager() +{ + if (PHYSFS_isInit()) + { + if (PHYSFS_deinit()) + { + // TODO error + } + } +} + + +bool CResourceManager::AddLocation(const std::string &location, bool prepend) +{ + if (PHYSFS_isInit()) + { + if (PHYSFS_mount(location.c_str(), nullptr, prepend ? 0 : 1)) + { + // TODO error + } + } + + return false; +} + + +bool CResourceManager::RemoveLocation(const std::string &location) +{ + if (PHYSFS_isInit()) + { + if (PHYSFS_removeFromSearchPath(location.c_str())) + { + // TODO error + } + } + + return false; +} + + +bool CResourceManager::SetSaveLocation(const std::string &location) +{ + if (PHYSFS_isInit()) + { + if (PHYSFS_setWriteDir(location.c_str())) + { + // TODO error + } + } + + return false; +} + + +std::string CResourceManager::GetLanguageLocation() +{ + return COLOBOT_I18N_DIR; +} + + +SDL_RWops* CResourceManager::GetSDLFileHandler(const std::string &filename) +{ + SDL_RWops *handler = SDL_AllocRW(); + if (!handler) + { + // TODO error + return nullptr; + } + + if (!PHYSFS_isInit()) + { + SDL_FreeRW(handler); + return nullptr; + } + + PHYSFS_File *file = PHYSFS_openRead(filename.c_str()); + if (!file) + { + SDL_FreeRW(handler); + return nullptr; + } + + handler->seek = SDLSeek; + handler->read = SDLRead; + handler->write = SDLWrite; + handler->close = SDLClose; + handler->type = 0xc010b04f; + handler->hidden.unknown.data1 = file; + + return handler; +} + + +CSNDFile* CResourceManager::GetSNDFileHandler(const std::string &filename) +{ + return new CSNDFile(filename); +} + + +bool CResourceManager::Exists(const std::string &filename) +{ + return PHYSFS_exists(filename.c_str()); +} + + +int CResourceManager::SDLClose(SDL_RWops *context) +{ + if (CheckSDLContext(context)) + { + PHYSFS_close(static_cast<PHYSFS_File *>(context->hidden.unknown.data1)); + SDL_FreeRW(context); + + return 0; + } + + return 1; +} + + +int CResourceManager::SDLRead(SDL_RWops *context, void *ptr, int size, int maxnum) +{ + if (CheckSDLContext(context)) + { + PHYSFS_File *file = static_cast<PHYSFS_File *>(context->hidden.unknown.data1); + SDL_memset(ptr, 0, size * maxnum); + + return PHYSFS_read(file, ptr, size, maxnum); + } + + return 0; +} + + +int CResourceManager::SDLWrite(SDL_RWops *context, const void *ptr, int size, int num) +{ + return 0; +} + + +int CResourceManager::SDLSeek(SDL_RWops *context, int offset, int whence) +{ + if (CheckSDLContext(context)) + { + PHYSFS_File *file = static_cast<PHYSFS_File *>(context->hidden.unknown.data1); + int position, result; + + switch (whence) + { + default: + case RW_SEEK_SET: + result = PHYSFS_seek(file, offset); + return result > 0 ? offset : -1; + + case RW_SEEK_CUR: + position = offset + PHYSFS_tell(file); + result = PHYSFS_seek(file, position); + return result > 0 ? position : -1; + + case RW_SEEK_END: + position = PHYSFS_fileLength(file) - offset; + result = PHYSFS_seek(file, position); + return result > 0 ? position : -1; + } + } + + return -1; +} + + +bool CResourceManager::CheckSDLContext(SDL_RWops *context) +{ + if (context->type != 0xc010b04f) + { + SDL_SetError("Wrong kind of RWops"); + return false; + } + + return true; +} |