diff options
Diffstat (limited to 'src/common/resources')
-rw-r--r-- | src/common/resources/inputstream.cpp | 61 | ||||
-rw-r--r-- | src/common/resources/inputstream.h | 37 | ||||
-rw-r--r-- | src/common/resources/inputstreambuffer.cpp | 132 | ||||
-rw-r--r-- | src/common/resources/inputstreambuffer.h | 51 | ||||
-rw-r--r-- | src/common/resources/outputstream.cpp | 55 | ||||
-rw-r--r-- | src/common/resources/outputstream.h | 36 | ||||
-rw-r--r-- | src/common/resources/outputstreambuffer.cpp | 89 | ||||
-rw-r--r-- | src/common/resources/outputstreambuffer.h | 46 | ||||
-rw-r--r-- | src/common/resources/resourcemanager.cpp | 280 | ||||
-rw-r--r-- | src/common/resources/resourcemanager.h | 63 | ||||
-rw-r--r-- | src/common/resources/sndfile.cpp | 133 | ||||
-rw-r--r-- | src/common/resources/sndfile.h | 49 |
12 files changed, 1032 insertions, 0 deletions
diff --git a/src/common/resources/inputstream.cpp b/src/common/resources/inputstream.cpp new file mode 100644 index 0000000..57d1305 --- /dev/null +++ b/src/common/resources/inputstream.cpp @@ -0,0 +1,61 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsiteс.ch; http://colobot.info; http://github.com/colobot + * + * 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://gnu.org/licenses + */ + +#include "common/resources/inputstream.h" +#include "common/resources/inputstreambuffer.h" + + +CInputStream::CInputStream() : std::istream(new CInputStreamBuffer()) +{ +} + +CInputStream::CInputStream(const std::string& filename) : std::istream(new CInputStreamBuffer()) +{ + open(filename); +} + + +CInputStream::~CInputStream() +{ + delete rdbuf(); +} + + +void CInputStream::open(const std::string& filename) +{ + static_cast<CInputStreamBuffer *>(rdbuf())->open(filename); +} + + +void CInputStream::close() +{ + static_cast<CInputStreamBuffer *>(rdbuf())->close(); +} + + +bool CInputStream::is_open() +{ + return static_cast<CInputStreamBuffer *>(rdbuf())->is_open(); +} + + +size_t CInputStream::size() +{ + return static_cast<CInputStreamBuffer *>(rdbuf())->size(); +} diff --git a/src/common/resources/inputstream.h b/src/common/resources/inputstream.h new file mode 100644 index 0000000..74e17b2 --- /dev/null +++ b/src/common/resources/inputstream.h @@ -0,0 +1,37 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsiteс.ch; http://colobot.info; http://github.com/colobot + * + * 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://gnu.org/licenses + */ + +#pragma once + +#include <istream> +#include <string> + + +class CInputStream : public std::istream +{ +public: + CInputStream(); + CInputStream(const std::string& filename); + virtual ~CInputStream(); + + void open(const std::string& filename); + void close(); + bool is_open(); + size_t size(); +}; diff --git a/src/common/resources/inputstreambuffer.cpp b/src/common/resources/inputstreambuffer.cpp new file mode 100644 index 0000000..7059d60 --- /dev/null +++ b/src/common/resources/inputstreambuffer.cpp @@ -0,0 +1,132 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsiteс.ch; http://colobot.info; http://github.com/colobot + * + * 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://gnu.org/licenses + */ + +#include "common/resources/inputstreambuffer.h" + +#include <stdexcept> +#include <sstream> + +CInputStreamBuffer::CInputStreamBuffer(size_t buffer_size) : m_buffer_size(buffer_size) +{ + if (buffer_size <= 0) + { + throw std::runtime_error("File buffer must be larger then 0 bytes"); + } + + m_buffer = new char[buffer_size]; + m_file = nullptr; +} + + +CInputStreamBuffer::~CInputStreamBuffer() +{ + close(); + delete m_buffer; +} + + +void CInputStreamBuffer::open(const std::string &filename) +{ + if (PHYSFS_isInit()) + m_file = PHYSFS_openRead(filename.c_str()); +} + + +void CInputStreamBuffer::close() +{ + if (is_open()) + PHYSFS_close(m_file); +} + + +bool CInputStreamBuffer::is_open() +{ + return m_file; +} + + +size_t CInputStreamBuffer::size() +{ + return PHYSFS_fileLength(m_file); +} + + +std::streambuf::int_type CInputStreamBuffer::underflow() +{ + if (gptr() < egptr()) + return traits_type::to_int_type(*gptr()); + + if (PHYSFS_eof(m_file)) + return traits_type::eof(); + + PHYSFS_sint64 read_count = PHYSFS_read(m_file, m_buffer, sizeof(char), m_buffer_size); + if (read_count <= 0) + return traits_type::eof(); + + setg(m_buffer, m_buffer, m_buffer + read_count); + + return traits_type::to_int_type(*gptr()); +} + + +std::streampos CInputStreamBuffer::seekpos(std::streampos sp, std::ios_base::openmode which) +{ + return seekoff(off_type(sp), std::ios_base::beg, which); +} + + +std::streampos CInputStreamBuffer::seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode which) +{ + /* A bit of explanation: + We are reading file by m_buffer_size parts so our 3 internal pointers will be + * eback (not used here) - start of block + * gptr - position of read cursor in block + * egtpr - end of block + off argument is relative to way */ + + std::streamoff new_position; + + switch (way) + { + case std::ios_base::beg: + new_position = off; + break; + + case std::ios_base::cur: + // tell will give cursor at begining of block so we have to add where in block we currently are + new_position = off + static_cast<off_type>(PHYSFS_tell(m_file)) - static_cast<off_type> (egptr() - gptr()); + break; + + case std::ios_base::end: + new_position = off + static_cast<off_type>(PHYSFS_fileLength(m_file)); + break; + + default: + break; + } + + if (PHYSFS_seek(m_file, new_position)) + { + setg(m_buffer, m_buffer, m_buffer); // reset buffer + + return pos_type(new_position); + } + + return pos_type(off_type(-1)); +} diff --git a/src/common/resources/inputstreambuffer.h b/src/common/resources/inputstreambuffer.h new file mode 100644 index 0000000..8c45c22 --- /dev/null +++ b/src/common/resources/inputstreambuffer.h @@ -0,0 +1,51 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsiteс.ch; http://colobot.info; http://github.com/colobot + * + * 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://gnu.org/licenses + */ + +#pragma once + +#include <streambuf> +#include <string> +#include <physfs.h> + +class CInputStreamBuffer : public std::streambuf +{ +public: + CInputStreamBuffer(size_t buffer_size = 512); + virtual ~CInputStreamBuffer(); + + void open(const std::string &filename); + void close(); + bool is_open(); + size_t size(); + +private: + int_type underflow(); + + std::streampos seekpos(std::streampos sp, std::ios_base::openmode which); + std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode which); + + // copy ctor and assignment not implemented; + // copying not allowed + CInputStreamBuffer(const CInputStreamBuffer &); + CInputStreamBuffer &operator= (const CInputStreamBuffer &); + + PHYSFS_File *m_file; + char *m_buffer; + size_t m_buffer_size; +}; diff --git a/src/common/resources/outputstream.cpp b/src/common/resources/outputstream.cpp new file mode 100644 index 0000000..e88520e --- /dev/null +++ b/src/common/resources/outputstream.cpp @@ -0,0 +1,55 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsiteс.ch; http://colobot.info; http://github.com/colobot + * + * 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://gnu.org/licenses + */ + +#include "common/resources/outputstream.h" +#include "common/resources/outputstreambuffer.h" + + +COutputStream::COutputStream() : std::ostream(new COutputStreamBuffer()) +{ +} + +COutputStream::COutputStream(const std::string& filename) : std::ostream(new COutputStreamBuffer()) +{ + open(filename); +} + + +COutputStream::~COutputStream() +{ + delete rdbuf(); +} + + +void COutputStream::open(const std::string& filename) +{ + static_cast<COutputStreamBuffer *>(rdbuf())->open(filename); +} + + +void COutputStream::close() +{ + static_cast<COutputStreamBuffer *>(rdbuf())->close(); +} + + +bool COutputStream::is_open() +{ + return static_cast<COutputStreamBuffer *>(rdbuf())->is_open(); +} diff --git a/src/common/resources/outputstream.h b/src/common/resources/outputstream.h new file mode 100644 index 0000000..30b9429 --- /dev/null +++ b/src/common/resources/outputstream.h @@ -0,0 +1,36 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsiteс.ch; http://colobot.info; http://github.com/colobot + * + * 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://gnu.org/licenses + */ + +#pragma once + +#include <ostream> +#include <string> + + +class COutputStream : public std::ostream +{ +public: + COutputStream(); + COutputStream(const std::string& filename); + virtual ~COutputStream(); + + void open(const std::string& filename); + void close(); + bool is_open(); +}; diff --git a/src/common/resources/outputstreambuffer.cpp b/src/common/resources/outputstreambuffer.cpp new file mode 100644 index 0000000..f8b4100 --- /dev/null +++ b/src/common/resources/outputstreambuffer.cpp @@ -0,0 +1,89 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsiteс.ch; http://colobot.info; http://github.com/colobot + * + * 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://gnu.org/licenses + */ + +#include "common/resources/outputstreambuffer.h" + +#include <stdexcept> +#include <sstream> + +COutputStreamBuffer::COutputStreamBuffer(size_t buffer_size) : m_buffer_size(buffer_size) +{ + m_file = nullptr; + m_buffer = new char[buffer_size]; + setp(m_buffer, m_buffer + buffer_size); +} + + +COutputStreamBuffer::~COutputStreamBuffer() +{ + close(); + delete m_buffer; +} + + +void COutputStreamBuffer::open(const std::string &filename) +{ + if (PHYSFS_isInit()) + m_file = PHYSFS_openWrite(filename.c_str()); +} + + +void COutputStreamBuffer::close() +{ + sync(); + if (is_open()) + PHYSFS_close(m_file); +} + + +bool COutputStreamBuffer::is_open() +{ + return m_file; +} + + +std::streambuf::int_type COutputStreamBuffer::overflow(std::streambuf::int_type ch) +{ + /* This function should be called when pptr() == epptr(). We use it also in sync() + so we also have to write data if buffer is not full. */ + + if (pbase() == pptr()) // no data to write, sync() called with empty buffer + return 0; + + // save buffer + PHYSFS_sint64 bytes_written = PHYSFS_write(m_file, pbase(), 1, pptr() - pbase()); + if (bytes_written <= 0) + return traits_type::eof(); + + pbump(-bytes_written); + // write final char + if (ch != traits_type::eof()) { + bytes_written = PHYSFS_write(m_file, &ch, 1, 1); + if (bytes_written <= 0) + return traits_type::eof(); + } + + return ch; +} + + +int COutputStreamBuffer::sync() +{ + return overflow(traits_type::eof()); +} diff --git a/src/common/resources/outputstreambuffer.h b/src/common/resources/outputstreambuffer.h new file mode 100644 index 0000000..758c4df --- /dev/null +++ b/src/common/resources/outputstreambuffer.h @@ -0,0 +1,46 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsiteс.ch; http://colobot.info; http://github.com/colobot + * + * 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://gnu.org/licenses + */ + +#pragma once + +#include <streambuf> +#include <string> +#include <physfs.h> + +class COutputStreamBuffer : public std::streambuf +{ +public: + COutputStreamBuffer(size_t buffer_size = 512); + virtual ~COutputStreamBuffer(); + void open(const std::string &filename); + void close(); + bool is_open(); + +private: + int_type overflow(int_type ch); + int sync(); + + // copy ctor and assignment not implemented; + // copying not allowed + COutputStreamBuffer(const COutputStreamBuffer &); + COutputStreamBuffer &operator= (const COutputStreamBuffer &); + PHYSFS_File *m_file; + char *m_buffer; + size_t m_buffer_size; +}; diff --git a/src/common/resources/resourcemanager.cpp b/src/common/resources/resourcemanager.cpp new file mode 100644 index 0000000..21aceec --- /dev/null +++ b/src/common/resources/resourcemanager.cpp @@ -0,0 +1,280 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsiteс.ch; http://colobot.info; http://github.com/colobot + * + * 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://gnu.org/licenses + */ + + +#include "common/resources/resourcemanager.h" + +#include "common/config.h" +#include "common/logger.h" + +#include <physfs.h> + +#include <boost/filesystem.hpp> + +namespace fs = boost::filesystem; + +namespace +{ + const Uint32 PHYSFS_RWOPS_TYPE = 0xc010b04f; +} + + +CResourceManager::CResourceManager(const char *argv0) +{ + if (!PHYSFS_init(argv0)) + { + CLogger::GetInstancePointer()->Error("Error while initializing physfs\n"); + } +} + + +CResourceManager::~CResourceManager() +{ + if (PHYSFS_isInit()) + { + if (!PHYSFS_deinit()) + { + CLogger::GetInstancePointer()->Error("Error while deinitializing physfs\n"); + } + } +} + + +bool CResourceManager::AddLocation(const std::string &location, bool prepend) +{ + if (PHYSFS_isInit()) + { + if (!PHYSFS_mount(location.c_str(), nullptr, prepend ? 0 : 1)) + { + CLogger::GetInstancePointer()->Error("Error while mounting \"%s\"\n", location.c_str()); + } + } + + return false; +} + + +bool CResourceManager::RemoveLocation(const std::string &location) +{ + if (PHYSFS_isInit()) + { + if (!PHYSFS_removeFromSearchPath(location.c_str())) + { + CLogger::GetInstancePointer()->Error("Error while unmounting \"%s\"\n", location.c_str()); + } + } + + return false; +} + + +bool CResourceManager::SetSaveLocation(const std::string &location) +{ + if (PHYSFS_isInit()) + { + if (!PHYSFS_setWriteDir(location.c_str())) + { + CLogger::GetInstancePointer()->Error("Error while setting save location to \"%s\"\n", location.c_str()); + } + } + + return false; +} + + +SDL_RWops* CResourceManager::GetSDLFileHandler(const std::string &filename) +{ + SDL_RWops *handler = SDL_AllocRW(); + if (!handler) + { + CLogger::GetInstancePointer()->Error("Unable to allocate SDL_RWops for \"%s\"\n", filename.c_str()); + 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 = PHYSFS_RWOPS_TYPE; + 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()); +} + +bool CResourceManager::DirectoryExists(const std::string& directory) +{ + return PHYSFS_exists(directory.c_str()) && PHYSFS_isDirectory(directory.c_str()); +} + +bool CResourceManager::CreateDirectory(const std::string& directory) +{ + return PHYSFS_mkdir(directory.c_str()); +} + +bool CResourceManager::RemoveDirectory(const std::string& directory) +{ + bool success = true; + std::string writeDir = PHYSFS_getWriteDir(); + try + { + fs::remove_all(writeDir + "/" + directory); + } + catch (std::exception & e) + { + success = false; + } + return success; +} + +std::vector<std::string> CResourceManager::ListFiles(const std::string &directory) +{ + std::vector<std::string> result; + + char **files = PHYSFS_enumerateFiles(directory.c_str()); + + for (char **i = files; *i != nullptr; i++) + { + result.push_back(*i); + } + + PHYSFS_freeList(files); + + return result; +} + +std::vector<std::string> CResourceManager::ListDirectories(const std::string &directory) +{ + std::vector<std::string> result; + + char **files = PHYSFS_enumerateFiles(directory.c_str()); + + for (char **i = files; *i != nullptr; i++) + { + std::string path = directory + "/" + (*i); + if (PHYSFS_isDirectory(path.c_str())) + { + result.push_back(*i); + } + } + + PHYSFS_freeList(files); + + return result; +} + + +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 != PHYSFS_RWOPS_TYPE) + { + SDL_SetError("Wrong kind of RWops"); + return false; + } + + return true; +} diff --git a/src/common/resources/resourcemanager.h b/src/common/resources/resourcemanager.h new file mode 100644 index 0000000..e949746 --- /dev/null +++ b/src/common/resources/resourcemanager.h @@ -0,0 +1,63 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsiteс.ch; http://colobot.info; http://github.com/colobot + * + * 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://gnu.org/licenses + */ + +#pragma once + +#include <vector> +#include <string> +#include <SDL.h> + +#include "common/resources/sndfile.h" + +class CResourceManager +{ +public: + CResourceManager(const char *argv0); + ~CResourceManager(); + + static bool AddLocation(const std::string &location, bool prepend = true); + static bool RemoveLocation(const std::string &location); + + static bool SetSaveLocation(const std::string &location); + + static SDL_RWops* GetSDLFileHandler(const std::string &filename); + static CSNDFile* GetSNDFileHandler(const std::string &filename); + + //! Check if file exists + static bool Exists(const std::string &filename); + //! Check if file exists and is a directory + static bool DirectoryExists(const std::string& directory); + + //! Create directory in write directory + static bool CreateDirectory(const std::string& directory); + //! Remove directory in write directory, recursively + static bool RemoveDirectory(const std::string& directory); + + //! List files contained in directory + static std::vector<std::string> ListFiles(const std::string &directory); + //! List directories contained in directory + static std::vector<std::string> ListDirectories(const std::string &directory); + +private: + static int SDLSeek(SDL_RWops *context, int offset, int whence); + static int SDLRead(SDL_RWops *context, void *ptr, int size, int maxnum); + static int SDLWrite(SDL_RWops *context, const void *ptr, int size, int num); + static int SDLClose(SDL_RWops *context); + static bool CheckSDLContext(SDL_RWops *context); +}; diff --git a/src/common/resources/sndfile.cpp b/src/common/resources/sndfile.cpp new file mode 100644 index 0000000..d2330e1 --- /dev/null +++ b/src/common/resources/sndfile.cpp @@ -0,0 +1,133 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsiteс.ch; http://colobot.info; http://github.com/colobot + * + * 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://gnu.org/licenses + */ + +#include "common/resources/sndfile.h" + +#include <cstring> + + +CSNDFile::CSNDFile(const std::string& filename) + : m_file_info{} + , m_snd_file{nullptr} + , m_file{nullptr} + , m_last_error{} + , m_snd_callbacks{SNDLength, SNDSeek, SNDRead, SNDWrite, SNDTell} +{ + if (PHYSFS_isInit()) + { + m_file = PHYSFS_openRead(filename.c_str()); + } + else + { + m_last_error = "Resource system not started!"; + } + if (m_file) + { + m_snd_file = sf_open_virtual(&m_snd_callbacks, SFM_READ, &m_file_info, m_file); + if (!m_snd_file) + { + m_last_error = "Could not load file"; + } + } + else + { + m_last_error = std::string(PHYSFS_getLastError()); + } +} + + +CSNDFile::~CSNDFile() +{ + if (m_file) + { + PHYSFS_close(m_file); + if (m_snd_file) + { + sf_close(m_snd_file); + } + } +} + + +bool CSNDFile::IsOpen() +{ + return m_file && m_snd_file; +} + + +SF_INFO &CSNDFile::GetFileInfo() +{ + return m_file_info; +} + + +std::string& CSNDFile::GetLastError() +{ + return m_last_error; +} + + +sf_count_t CSNDFile::Read(short int *ptr, sf_count_t items) +{ + return sf_read_short(m_snd_file, ptr, items); +} + + +sf_count_t CSNDFile::SNDLength(void *data) +{ + return PHYSFS_fileLength(static_cast<PHYSFS_File *>(data)); +} + + +sf_count_t CSNDFile::SNDRead(void *ptr, sf_count_t count, void *data) +{ + return PHYSFS_read(static_cast<PHYSFS_File *>(data), ptr, 1, count); +} + + +sf_count_t CSNDFile::SNDSeek(sf_count_t offset, int whence, void *data) +{ + PHYSFS_File *file = static_cast<PHYSFS_File *>(data); + switch(whence) + { + case SEEK_CUR: + PHYSFS_seek(file, PHYSFS_tell(file) + offset); + break; + case SEEK_SET: + PHYSFS_seek(file, offset); + break; + case SEEK_END: + PHYSFS_seek(file, PHYSFS_fileLength(file) + offset); + break; + } + + return PHYSFS_tell(file); +} + + +sf_count_t CSNDFile::SNDTell(void *data) +{ + return PHYSFS_tell(static_cast<PHYSFS_File *>(data)); +} + + +sf_count_t CSNDFile::SNDWrite(const void *ptr, sf_count_t count, void *data) +{ + return PHYSFS_write(static_cast<PHYSFS_File *>(data), ptr, 1, count); +} diff --git a/src/common/resources/sndfile.h b/src/common/resources/sndfile.h new file mode 100644 index 0000000..f083666 --- /dev/null +++ b/src/common/resources/sndfile.h @@ -0,0 +1,49 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsiteс.ch; http://colobot.info; http://github.com/colobot + * + * 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://gnu.org/licenses + */ + +#pragma once + +#include <string> +#include <physfs.h> +#include <sndfile.h> + + +class CSNDFile +{ +public: + CSNDFile(const std::string &filename); + virtual ~CSNDFile(); + + SF_INFO &GetFileInfo(); + bool IsOpen(); + std::string &GetLastError(); + sf_count_t Read(short int *ptr, sf_count_t items); + +private: + static sf_count_t SNDLength(void *data); + static sf_count_t SNDSeek(sf_count_t offset, int whence, void *data); + static sf_count_t SNDRead(void *ptr, sf_count_t count, void *data); + static sf_count_t SNDWrite(const void *ptr, sf_count_t count, void *data); + static sf_count_t SNDTell(void *data); + SF_INFO m_file_info; + SNDFILE *m_snd_file; + PHYSFS_File *m_file; + std::string m_last_error; + SF_VIRTUAL_IO m_snd_callbacks; +}; |