From ab60fa7990462911923b94afa70334ea4a894f7a Mon Sep 17 00:00:00 2001 From: Herwig Birke Date: Tue, 28 Mar 2023 10:35:45 +0200 Subject: [PATCH] migrate --- .gitignore | 103 +++--- cbasicfile.cpp | 161 +++++++++ cbasicfile.h | 34 ++ cconfigdata.h | 20 ++ cconfigfile.cpp | 32 ++ cconfigfile.h | 21 ++ cdirectories.cpp | 118 ++++++ cdirectories.h | 40 +++ cexception.cpp | 146 ++++++++ cexception.h | 106 ++++++ cfilebuffer.cpp | 835 +++++++++++++++++++++++++++++++++++++++++++ cfilebuffer.h | 86 +++++ cfilemanager.cpp | 444 +++++++++++++++++++++++ cfilemanager.h | 52 +++ cfont.cpp | 74 ++++ cfont.h | 41 +++ cfontresource.cpp | 107 ++++++ cfontresource.h | 23 ++ cgameapplication.cpp | 266 ++++++++++++++ cgameapplication.h | 84 +++++ cmainwindow.cpp | 26 ++ cmainwindow.h | 21 ++ cmainwindow.ui | 22 ++ cmediatoolkit.cpp | 129 +++++++ cmediatoolkit.h | 58 +++ cresourcearchive.cpp | 26 ++ cresourcearchive.h | 19 + cresourcedata.h | 18 + cresourcefile.cpp | 32 ++ cresourcefile.h | 19 + cresourceindex.cpp | 159 ++++++++ cresourceindex.h | 38 ++ csdl_toolkit.cpp | 500 ++++++++++++++++++++++++++ csdl_toolkit.h | 43 +++ ctaggedresource.cpp | 92 +++++ ctaggedresource.h | 45 +++ defines.h | 143 ++++++++ main.cpp | 11 + xBAK.pro | 64 ++++ 39 files changed, 4217 insertions(+), 41 deletions(-) create mode 100644 cbasicfile.cpp create mode 100644 cbasicfile.h create mode 100644 cconfigdata.h create mode 100644 cconfigfile.cpp create mode 100644 cconfigfile.h create mode 100644 cdirectories.cpp create mode 100644 cdirectories.h create mode 100644 cexception.cpp create mode 100644 cexception.h create mode 100644 cfilebuffer.cpp create mode 100644 cfilebuffer.h create mode 100644 cfilemanager.cpp create mode 100644 cfilemanager.h create mode 100644 cfont.cpp create mode 100644 cfont.h create mode 100644 cfontresource.cpp create mode 100644 cfontresource.h create mode 100644 cgameapplication.cpp create mode 100644 cgameapplication.h create mode 100644 cmainwindow.cpp create mode 100644 cmainwindow.h create mode 100644 cmainwindow.ui create mode 100644 cmediatoolkit.cpp create mode 100644 cmediatoolkit.h create mode 100644 cresourcearchive.cpp create mode 100644 cresourcearchive.h create mode 100644 cresourcedata.h create mode 100644 cresourcefile.cpp create mode 100644 cresourcefile.h create mode 100644 cresourceindex.cpp create mode 100644 cresourceindex.h create mode 100644 csdl_toolkit.cpp create mode 100644 csdl_toolkit.h create mode 100644 ctaggedresource.cpp create mode 100644 ctaggedresource.h create mode 100644 defines.h create mode 100644 main.cpp create mode 100644 xBAK.pro diff --git a/.gitignore b/.gitignore index f147edf..fab7372 100644 --- a/.gitignore +++ b/.gitignore @@ -1,52 +1,73 @@ -# C++ objects and libs -*.slo -*.lo -*.o +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave *.a -*.la -*.lai +*.core +*.moc +*.o +*.obj +*.orig +*.rej *.so *.so.* -*.dll -*.dylib - -# Qt-es -object_script.*.Release -object_script.*.Debug -*_plugin_import.cpp +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc /.qmake.cache /.qmake.stash -*.pro.user -*.pro.user.* -*.qbs.user -*.qbs.user.* -*.moc -moc_*.cpp -moc_*.h -qrc_*.cpp -ui_*.h -*.qmlc -*.jsc -Makefile* -*build-* -*.qm -*.prl -# Qt unit tests -target_wrapper.* +# qtcreator generated files +*.pro.user* -# QtCreator -*.autosave +# xemacs temporary files +*.flc -# QtCreator Qml -*.qmlproject.user -*.qmlproject.user.* +# Vim temporary files +.*.swp -# QtCreator CMake -CMakeLists.txt.user* +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* -# QtCreator 4.8< compilation database -compile_commands.json +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe -# QtCreator local machine specific files for imported projects -*creator.user* diff --git a/cbasicfile.cpp b/cbasicfile.cpp new file mode 100644 index 0000000..845669e --- /dev/null +++ b/cbasicfile.cpp @@ -0,0 +1,161 @@ +#include "cdirectories.h" +#include "cexception.h" +#include "cbasicfile.h" + + +cBasicFile::cBasicFile() +{ +} + +cBasicFile::~cBasicFile() +{ +} + +QString cBasicFile::getDefaultPath() const +{ + return(QString("")); +} + +QString cBasicFile::getAlternatePath() const +{ + return(QString("")); +} + +QString cBasicFile::getLastResortPath() const +{ + return(QString("")); +} + +QString cBasicFile::getStoragePath() const +{ + return(QString("")); +} + +void cBasicFile::open(const QString& name, const bool writable) +{ + if(writable) + { + QString filename = getStoragePath() + name; + ofs.open(filename.toStdString().c_str(), std::ios::out | std::ios::binary); + if(ofs.fail()) + throw cOpenError(__FILE__, __LINE__, "(" + filename + ")"); + } + else + { + QString filename = getDefaultPath() + name; + ifs.open(filename.toStdString().c_str(), std::ios::in | std::ios::binary); + if(ifs.fail()) + { + ifs.clear(); + filename = getAlternatePath() + name; + ifs.open(filename.toStdString().c_str(), std::ios::in | std::ios::binary); + if(ifs.fail()) + { + ifs.clear(); + filename = getLastResortPath() + name; + ifs.open(filename.toStdString().c_str(), std::ios::in | std::ios::binary); + if(ifs.fail()) + throw cOpenError(__FILE__, __LINE__, "(" + filename + ")"); + } + } + } +} + +void cBasicFile::close() +{ + if(ifs.is_open()) + ifs.close(); + if(ofs.is_open()) + ofs.close(); +} + +void cBasicFile::seek(const std::streamoff offset) +{ + if(ifs.is_open()) + { + ifs.seekg(offset, std::ios::beg); + if(ifs.fail()) + throw cIOError(__FILE__, __LINE__); + } + + if(ofs.is_open()) + { + ofs.seekp(offset, std::ios::beg); + if(ofs.fail()) + throw cIOError(__FILE__, __LINE__); + } +} + +void cBasicFile::seekEnd(const std::streamoff offset) +{ + if(ifs.is_open()) + { + ifs.seekg(offset, std::ios::end); + if(ifs.fail()) + throw cIOError(__FILE__, __LINE__); + } + if(ofs.is_open()) + { + ofs.seekp(offset, std::ios::end); + if(ofs.fail()) + throw cIOError(__FILE__, __LINE__); + } +} + +std::streamsize cBasicFile::size() +{ + if(ifs.is_open()) + { + ifs.seekg(0, std::ios::end); + if(ifs.fail()) + throw cIOError(__FILE__, __LINE__); + return(ifs.tellg()); + } + if(ofs.is_open()) + { + ofs.seekp(0, std::ios::end); + if(ofs.fail()) + throw cIOError(__FILE__, __LINE__); + return(ofs.tellp()); + } + return(0); +} + +void cBasicFile::load(cFileBuffer &buffer) +{ + try + { + buffer.load(ifs); + } + catch (cException &e) + { + e.print("BasicFile::Load"); + throw; + } +} + +void cBasicFile::save(cFileBuffer &buffer) +{ + try + { + buffer.save(ofs); + } + catch (cException &e) + { + e.print("BasicFile::Save"); + throw; + } +} + +void cBasicFile::save(cFileBuffer &buffer, const unsigned int n) +{ + try + { + buffer.save(ofs, n); + } + catch (cException &e) + { + e.print("BasicFile::Save"); + throw; + } +} diff --git a/cbasicfile.h b/cbasicfile.h new file mode 100644 index 0000000..2cd296a --- /dev/null +++ b/cbasicfile.h @@ -0,0 +1,34 @@ +#ifndef CBASICFILE_H +#define CBASICFILE_H + + +#include "cfilebuffer.h" +#include + + +class cBasicFile +{ +public: + cBasicFile(); + virtual ~cBasicFile(); + + virtual QString getDefaultPath() const; + virtual QString getAlternatePath() const; + virtual QString getLastResortPath() const; + virtual QString getStoragePath() const; + + void open(const QString& name, const bool writable); + void close(); + void seek(const std::streamoff offset); + void seekEnd(const std::streamoff offset); + std::streamsize size(); + void load(cFileBuffer& buffer); + void save(cFileBuffer& buffer); + void save(cFileBuffer &buffer, const unsigned int n); + +private: + std::ifstream ifs; + std::ofstream ofs; +}; + +#endif // CBASICFILE_H diff --git a/cconfigdata.h b/cconfigdata.h new file mode 100644 index 0000000..8c1eef2 --- /dev/null +++ b/cconfigdata.h @@ -0,0 +1,20 @@ +#ifndef CCONFIGDATA_H +#define CCONFIGDATA_H + + +#include "cfilebuffer.h" + + +class cConfigData +{ +public: + cConfigData() + {}; + virtual ~cConfigData() + {}; + virtual void load(cFileBuffer* buffer ) = 0; + virtual unsigned int save(cFileBuffer* buffer ) = 0; +}; + + +#endif // CCONFIGDATA_H diff --git a/cconfigfile.cpp b/cconfigfile.cpp new file mode 100644 index 0000000..976bc6a --- /dev/null +++ b/cconfigfile.cpp @@ -0,0 +1,32 @@ +#include "cexception.h" +#include "cconfigfile.h" +#include "cdirectories.h" + + +cConfigFile::cConfigFile() +{ +} + +cConfigFile::~cConfigFile() +{ +} + +QString cConfigFile::getDefaultPath() const +{ + return(cDirectories::getInstance()->getUserPath()); +} + +QString cConfigFile::getAlternatePath() const +{ + return(cDirectories::getInstance()->getSharedPath()); +} + +QString cConfigFile::getLastResortPath() const +{ + return(cDirectories::getInstance()->getResourcePath()); +} + +QString cConfigFile::getStoragePath() const +{ + return(cDirectories::getInstance()->getUserPath()); +} diff --git a/cconfigfile.h b/cconfigfile.h new file mode 100644 index 0000000..560781b --- /dev/null +++ b/cconfigfile.h @@ -0,0 +1,21 @@ +#ifndef CCONFIGFILE_H +#define CCONFIGFILE_H + + +#include "cbasicfile.h" + +#include + + +class cConfigFile : public cBasicFile +{ +public: + cConfigFile(); + virtual ~cConfigFile(); + QString getDefaultPath() const; + QString getAlternatePath() const; + QString getLastResortPath() const; + QString getStoragePath() const; +}; + +#endif // CCONFIGFILE_H diff --git a/cdirectories.cpp b/cdirectories.cpp new file mode 100644 index 0000000..d6160fd --- /dev/null +++ b/cdirectories.cpp @@ -0,0 +1,118 @@ +#include "cdirectories.h" +#include "cexception.h" + +#include +#include + +#include + + +cDirectories* cDirectories::m_instance = nullptr; + +cDirectories::cDirectories() : + m_resourcePath(""), + m_sharedPath(""), + m_userPath(""), + m_gamesPath(""), + m_capturePath(""), + m_dataPath("") +{ + m_resourcePath = searchResources(); + m_sharedPath = ""; + m_userPath = QDir::homePath() + "/xBAK/"; + m_gamesPath = m_userPath + "games/"; + m_capturePath = m_userPath + "capture/"; + m_dataPath = m_userPath + "data/"; + + createPath(m_userPath); + createPath(m_gamesPath); + createPath(m_capturePath); + createPath(m_dataPath); +} + +cDirectories::~cDirectories() +{ +} + +void cDirectories::cleanUp() +{ + if(m_instance) + { + delete m_instance; + m_instance = 0; + } +} + +cDirectories* cDirectories::getInstance() +{ + if(!m_instance) + m_instance = new cDirectories(); + + return(m_instance); +} + +void cDirectories::createPath(const QString& path) +{ + QDir dir; + dir.mkpath(path); +} + +const QString SEARCH_RESOURCE_FILE = "krondor.001"; +const QStringList SEARCH_RESOURCE_PATH = QStringList() << + "./" << + "/krondor/" << + "./krondor/" << + "../krondor/" << + "/opt/krondor/" << + "/bakcd/" << + "./bakcd/" << + "../bakcd/" << + "/opt/bakcd/"; + +QString cDirectories::searchResources() const +{ + for(int i = 0;i < SEARCH_RESOURCE_PATH.count();i++) + { + QFile f(SEARCH_RESOURCE_PATH[i] + SEARCH_RESOURCE_FILE); + if(f.exists()) + return(SEARCH_RESOURCE_PATH[i]); + } + + throw cFileNotFound(__FILE__, __LINE__, SEARCH_RESOURCE_FILE); + return ""; +} + +void cDirectories::setResourcePath(const QString& path) +{ + m_resourcePath = path; +} + +QString cDirectories::getResourcePath() const +{ + return(m_resourcePath); +} + +QString cDirectories::getSharedPath() const +{ + return(m_sharedPath); +} + +QString cDirectories::getUserPath() const +{ + return(m_userPath); +} + +QString cDirectories::getGamesPath() const +{ + return(m_gamesPath); +} + +QString cDirectories::getCapturePath() const +{ + return(m_capturePath); +} + +QString cDirectories::getDataPath() const +{ + return(m_dataPath); +} diff --git a/cdirectories.h b/cdirectories.h new file mode 100644 index 0000000..2d23fed --- /dev/null +++ b/cdirectories.h @@ -0,0 +1,40 @@ +#ifndef CDIRECTORIES_H +#define CDIRECTORIES_H + +#include + + +class cDirectories +{ +public: + ~cDirectories(); + + static cDirectories* getInstance(); + static void cleanUp(); + + QString getResourcePath() const; + QString getSharedPath() const; + QString getUserPath() const; + QString getGamesPath() const; + QString getCapturePath() const; + QString getDataPath() const; + void setResourcePath(const QString& path); + +private: + QString m_resourcePath; + QString m_sharedPath; + QString m_userPath; + QString m_gamesPath; + QString m_capturePath; + QString m_dataPath; + + static cDirectories* m_instance; + + void createPath(const QString& path); + QString searchResources() const; + +protected: + cDirectories(); +}; + +#endif // CDIRECTORIES_H diff --git a/cexception.cpp b/cexception.cpp new file mode 100644 index 0000000..e58dd90 --- /dev/null +++ b/cexception.cpp @@ -0,0 +1,146 @@ +#include "cexception.h" + +#include +#include + + +const QString BUFFER_EMPTY = "Buffer is empty"; +const QString BUFFER_FULL = "Buffer is full"; +const QString COMPRESSION_ERROR = "Unknown compression method"; +const QString DATA_CORRUPTION = "Data corruption"; +const QString FILE_NOT_FOUND = "File not found"; +const QString INDEX_OUT_OF_RANGE = "Index out of range"; +const QString IO_ERROR = "Read/write error"; +const QString MEMORY_ERROR = "Out of memory"; +const QString NULL_POINTER = "Null pointer"; +const QString OPEN_ERROR = "File not open"; +const QString SDL_EXCEPTION = "SDL error"; +const QString UNEXPECTED_VALUE = "Unexpected value"; + + +cException::cException(const QString& file, const quint32 line, const QString& msg) : + m_filename(file), + m_linenr(line), + m_message(msg) +{ +} + +cException::cException(const QString& file, const quint32 line, const QString& msg, const quint32 val) : + m_filename(file), + m_linenr(line) +{ + QTextStream s(&m_message); + + s << msg << ": " << val; +} + +cException::~cException() throw() +{ +} + +void cException::print(const QString& handler) const throw() +{ + qDebug() << handler << " >> " << m_filename << ":" << m_linenr << " " << m_message; +} + +QString cException::what() const throw() +{ + QString str; + QTextStream s(&str); + + s << m_filename << ":" << m_linenr << " " << m_message; + return(str); +} + +cBufferEmpty::cBufferEmpty(const QString& file, const quint32 line, const QString& msg) + : cException(file, line, BUFFER_EMPTY + " " + msg) +{} + +cBufferEmpty::~cBufferEmpty() throw() +{} + +cBufferFull::cBufferFull(const QString& file, const quint32 line, const QString& msg) + : cException(file, line, BUFFER_FULL + " " + msg) +{} + +cBufferFull::~cBufferFull() throw() +{} + +cCompressionError::cCompressionError(const QString& file, const quint32 line, const QString& msg) + : cException(file, line, COMPRESSION_ERROR + " " + msg) +{} + +cCompressionError::cCompressionError(const QString& file, const quint32 line, const QString& msg, const unsigned int value) + : cException(file, line, COMPRESSION_ERROR + " " + msg, value) +{} + +cCompressionError::~cCompressionError() throw() +{} + +cDataCorruption::cDataCorruption(const QString& file, const quint32 line, const QString& msg) + : cException(file, line, DATA_CORRUPTION + " " + msg) +{} + +cDataCorruption::cDataCorruption(const QString& file, const quint32 line, const QString& msg, const unsigned int value) + : cException(file, line, DATA_CORRUPTION + " " + msg, value) +{} + +cDataCorruption::~cDataCorruption() throw() +{} + +cFileNotFound::cFileNotFound(const QString& file, const quint32 line, const QString& msg) : + cException(file, line, FILE_NOT_FOUND + " (" + msg + ")") +{} + +cFileNotFound::~cFileNotFound() throw() +{} + +cIndexOutOfRange::cIndexOutOfRange(const QString& file, const quint32 line, const QString& msg) + : cException(file, line, INDEX_OUT_OF_RANGE + " " + msg) +{} + +cIndexOutOfRange::cIndexOutOfRange(const QString& file, const quint32 line, const QString& msg, const unsigned int value) + : cException(file, line, INDEX_OUT_OF_RANGE + " " + msg, value) +{} + +cIndexOutOfRange::~cIndexOutOfRange() throw() +{} + +cIOError::cIOError(const QString& file, const quint32 line, const QString& msg) + : cException(file, line, IO_ERROR + " " + msg) +{} + +cIOError::~cIOError() throw() +{} + +cNullPointer::cNullPointer(const QString& file, const quint32 line, const QString& msg) + : cException(file, line, NULL_POINTER + " " + msg) +{} + +cNullPointer::~cNullPointer() throw() +{} + +cOpenError::cOpenError(const QString& file, const quint32 line, const QString& msg) + : cException(file, line, OPEN_ERROR + " " + msg) +{} + +cOpenError::~cOpenError() throw() +{} + +cSDL_Exception::cSDL_Exception(const QString& file, const quint32 line, const QString& msg) + : cException(file, line, SDL_EXCEPTION + " " + msg) +{} + +cSDL_Exception::~cSDL_Exception() throw() +{} + +cUnexpectedValue::cUnexpectedValue(const QString& file, const quint32 line, const QString& value) + : cException(file, line, UNEXPECTED_VALUE + " " + value) +{} + +cUnexpectedValue::cUnexpectedValue(const QString& file, const quint32 line, const unsigned int value) + : cException(file, line, UNEXPECTED_VALUE, value) +{} + +cUnexpectedValue::~cUnexpectedValue() throw() +{} diff --git a/cexception.h b/cexception.h new file mode 100644 index 0000000..892ff9b --- /dev/null +++ b/cexception.h @@ -0,0 +1,106 @@ +#ifndef CEXCEPTION_H +#define CEXCEPTION_H + + +#include + +class cException +{ +public: + cException(const QString& file, const quint32 line, const QString& msg); + cException(const QString& file, const quint32 line, const QString& msg, const quint32 val); + + virtual ~cException() throw(); + + void print(const QString& handler) const throw(); + QString what() const throw(); + +private: + QString m_filename; + unsigned int m_linenr; + QString m_message; +public: +}; + +class cBufferEmpty: public cException +{ +public: + cBufferEmpty(const QString& file, const unsigned int line, const QString& msg = ""); + virtual ~cBufferEmpty() throw(); +}; + +class cBufferFull: public cException +{ +public: + cBufferFull(const QString& file, const unsigned int line, const QString& msg = ""); + virtual ~cBufferFull() throw(); +}; + +class cCompressionError: public cException +{ +public: + cCompressionError(const QString& file, const unsigned int line, const QString& msg = ""); + cCompressionError(const QString& file, const unsigned int line, const QString& msg, const unsigned int value); + virtual ~cCompressionError() throw (); +}; + +class cDataCorruption: public cException +{ +public: + cDataCorruption(const QString& file, const unsigned int line, const QString& msg = ""); + cDataCorruption(const QString& file, const unsigned int line, const QString& msg, const unsigned int value); + virtual ~cDataCorruption() throw (); +}; + +class cFileNotFound: public cException +{ +public: + cFileNotFound(const QString& file, const unsigned int line, const QString& msg); + virtual ~cFileNotFound() throw (); +}; + +class cIndexOutOfRange: public cException +{ +public: + cIndexOutOfRange(const QString& file, const unsigned int line, const QString& msg = ""); + cIndexOutOfRange(const QString& file, const unsigned int line, const QString& msg, const unsigned int value); + virtual ~cIndexOutOfRange() throw (); +}; + +class cIOError: public cException +{ +public: + cIOError(const QString& file, const unsigned int line, const QString& msg = ""); + virtual ~cIOError() throw (); +}; + +class cNullPointer: public cException +{ +public: + cNullPointer(const QString& file, const unsigned int line, const QString& msg = ""); + virtual ~cNullPointer() throw (); +}; + +class cOpenError: public cException +{ +public: + cOpenError(const QString& file, const unsigned int line, const QString& msg = ""); + virtual ~cOpenError() throw (); +}; + +class cSDL_Exception: public cException +{ +public: + cSDL_Exception(const QString& file, const unsigned int line, const QString& msg = ""); + virtual ~cSDL_Exception() throw (); +}; + +class cUnexpectedValue: public cException +{ +public: + cUnexpectedValue(const QString& file, const unsigned int line, const QString& value); + cUnexpectedValue(const QString& file, const unsigned int line, const unsigned int value); + virtual ~cUnexpectedValue() throw (); +}; + +#endif // CEXCEPTION_H diff --git a/cfilebuffer.cpp b/cfilebuffer.cpp new file mode 100644 index 0000000..179aefd --- /dev/null +++ b/cfilebuffer.cpp @@ -0,0 +1,835 @@ +#include +#include +#include + +#include "defines.h" +#include "cexception.h" +#include "cfilebuffer.h" + +cFileBuffer::cFileBuffer(const unsigned int n) +{ + m_buffer = new uint8_t[n]; + memset(m_buffer, 0, n); + m_current = m_buffer; + m_size = n; + m_nextbit = 0; +} + +cFileBuffer::~cFileBuffer() +{ + if(m_buffer) + delete[] m_buffer; +} + +void cFileBuffer::copyFrom(cFileBuffer* buf, const unsigned int n) +{ + if(m_buffer && n && (m_current + n <= m_buffer + m_size)) + { + buf->getData(m_current, n); + m_current += n; + } +} + +void cFileBuffer::copyTo(cFileBuffer *buf, const unsigned int n) +{ + if(m_buffer && n && (m_current + n <= m_buffer + m_size)) + { + buf->putData(m_current, n); + m_current += n; + } +} + +void cFileBuffer::fill(cFileBuffer *buf) +{ + if(m_buffer) + { + m_current = m_buffer; + buf->getData(m_buffer, MIN(m_size, buf->getSize())); + } +} + +void cFileBuffer::load(std::ifstream &ifs) +{ + if(ifs.is_open()) + { + m_current = m_buffer; + ifs.read((char *)m_buffer, m_size); + if(ifs.fail()) + throw cIOError(__FILE__, __LINE__); + } + else + throw cOpenError(__FILE__, __LINE__); +} + +void cFileBuffer::save(std::ofstream &ofs) +{ + if(ofs.is_open()) + { + m_current = m_buffer; + ofs.write((char *)m_buffer, m_size); + if(ofs.fail()) + throw cIOError(__FILE__, __LINE__); + } + else + throw cOpenError(__FILE__, __LINE__); +} + +void cFileBuffer::save(std::ofstream &ofs, const unsigned int n) +{ + if (ofs.is_open()) + { + if(n <= m_size) + { + m_current = m_buffer; + ofs.write((char *)m_buffer, n); + if(ofs.fail()) + throw cIOError(__FILE__, __LINE__); + } + else + throw cBufferEmpty(__FILE__, __LINE__); + } + else + throw cOpenError(__FILE__, __LINE__); +} + +void cFileBuffer::dump(const unsigned int n) +{ + uint8_t* tmp = m_current; + unsigned int count = 0; + + std::cout << std::setbase(16) << std::setfill('0') << std::setw(8) << count << ": "; + while((tmp < (m_buffer + m_size)) && ((tmp < (m_current + n)) || (n == 0))) + { + std::cout << std::setw(2) << (unsigned int)*tmp++ << " "; + if((++count & 0x1f) == 0) + std::cout << std::endl << std::setw(8) << count << ": "; + else if ((count & 0x07) == 0) + std::cout << "| "; + } + std::cout << std::setbase(10) << std::setfill(' ') << std::endl; +} + +void cFileBuffer::seek(const unsigned int n) +{ + if((m_current) && (n <= m_size)) + m_current = m_buffer + n; +} + +void cFileBuffer::skip(const int n) +{ + if((m_current) && (m_current + n <= m_buffer + m_size)) + m_current += n; +} + +void cFileBuffer::skipBits() +{ + if(m_nextbit) + { + skip(1); + m_nextbit = 0; + } +} + +typedef union _HashTableEntry +{ + uint32_t code; + struct + { + uint16_t prefix; + uint8_t append; + } + entry; +} HashTableEntry; + +unsigned int cFileBuffer::compressLZW(cFileBuffer *result) +{ + try + { + std::map hashtable; + unsigned int n_bits = 9; + unsigned int free_entry = 257; + unsigned int bitpos = 0; + HashTableEntry hte; + + hte.entry.prefix = getUint8(); + + while(!atEnd() && !result->atEnd()) + { + hte.entry.append = getUint8(); + std::map::iterator it = hashtable.find(hte.code); + if(it == hashtable.end()) + { + result->putBits(hte.entry.prefix, n_bits); + bitpos += n_bits; + hashtable.insert(std::pair(hte.code, free_entry)); + hte.entry.prefix = hte.entry.append; + free_entry++; + if(free_entry >= (unsigned int)(1 << n_bits)) + { + if(n_bits < 12) + n_bits++; + else + { + hashtable.clear(); + free_entry = 256; + result->putBits(free_entry, n_bits); + result->skipBits(); + result->skip((((bitpos-1)+((n_bits<<3)-(bitpos-1+(n_bits<<3))%(n_bits<<3)))-bitpos)>>3); + n_bits = 9; + bitpos = 0; + } + } + } + else + hte.entry.prefix = it->second; + } + hashtable.clear(); + unsigned int res = result->getBytesDone(); + result->rewind(); + return res; + } + catch (cException &e) + { + e.print("FileBuffer::CompressLZW"); + throw; + } + return 0; +} + +unsigned int cFileBuffer::compressLZSS(cFileBuffer *result) +{ + try + { + uint8_t* data = getCurrent(); + uint8_t* curr = getCurrent(); + uint8_t* codeptr = result->getCurrent(); + uint8_t byte = getUint8(); + uint8_t code = 0; + uint8_t mask = 0; + + while(!atEnd() && !result->atEnd()) + { + if(!mask) + { + *codeptr = code; + codeptr = result->getCurrent(); + result->skip(1); + code = 0; + mask = 0x01; + } + unsigned int off = 0; + unsigned int len = 0; + uint8_t* ptr = curr; + + while(ptr > data) + { + ptr--; + if(*ptr == byte) + { + off = ptr - data; + len = 1; + while((curr + len < m_buffer + m_size) && (ptr[len] == curr[len])) + len++; + } + } + if(len < 5) + { + code |= mask; + result->putUint8(byte); + } + else + { + result->putUint16LE(off); + result->putUint8(len - 5); + skip(len - 1); + } + curr = getCurrent(); + byte = getUint8(); + mask <<= 1; + } + *codeptr = code; + unsigned int res = result->getBytesDone(); + result->rewind(); + return res; + } + catch (cException &e) + { + e.print("FileBuffer::CompressLZSS"); + throw; + } + return 0; +} + +unsigned int cFileBuffer::compressRLE(cFileBuffer *result) +{ + try + { + uint8_t* skipptr = getCurrent(); + uint8_t byte = 0; + uint8_t next = getUint8(); + unsigned int count; + unsigned int skipped = 0; + + while(!atEnd() && !result->atEnd()) + { + count = 1; + do + { + byte = next; + next = getUint8(); + count++; + } + while(!atEnd() && (next == byte)); + + if(next != byte) + count--; + + if(count > 3) + { + if(skipped > 0) + { + while(skipped > 0) + { + unsigned int n; + if(skipped > 127) + n = 127; + else + n = skipped & 0x7f; + + result->putUint8(n); + result->putData(skipptr, n); + skipped -= n; + skipptr += n; + } + } + while(count > 3) + { + unsigned int n; + if(count > 127) + n = 127; + else + n = count & 0x7f; + result->putUint8(n | 0x80); + result->putUint8(byte); + count -= n; + } + skipped = count; + skipptr = getCurrent() - skipped - 1; + } + else + skipped += count; + } + + if(next != byte) + skipped++; + + if(skipped > 0) + { + skip(-skipped); + while(skipped > 0) + { + unsigned int n = skipped & 0x7f; + result->putUint8(n); + result->copyFrom(this, n); + skipped -= n; + } + } + + unsigned int res = result->getBytesDone(); + result->rewind(); + return res; + } + catch (cException &e) + { + e.print("FileBuffer::CompressRLE"); + throw; + } + return 0; +} + +unsigned int cFileBuffer::compress(cFileBuffer *result, const unsigned int method) +{ + switch (method) + { + case COMPRESSION_LZW: + return(compressLZW(result)); + break; + case COMPRESSION_LZSS: + return(compressLZSS(result)); + break; + case COMPRESSION_RLE: + return(compressRLE(result)); + break; + default: + throw cCompressionError(__FILE__, __LINE__); + break; + } +} + +typedef struct _CodeTableEntry +{ + uint16_t prefix; + uint8_t append; +} CodeTableEntry; + +unsigned int cFileBuffer::decompressLZW(cFileBuffer *result) +{ + try + { + CodeTableEntry* codetable = new CodeTableEntry[4096]; + uint8_t* decodestack = new uint8_t[4096]; + uint8_t* stackptr = decodestack; + unsigned int n_bits = 9; + unsigned int free_entry = 257; + unsigned int oldcode = getBits(n_bits); + unsigned int lastbyte = oldcode; + unsigned int bitpos = 0; + + result->putUint8(oldcode); + + while (!atEnd() && !result->atEnd()) + { + unsigned int newcode = getBits(n_bits); + bitpos += n_bits; + + if(newcode == 256) + { + skipBits(); + skip((((bitpos-1)+((n_bits<<3)-(bitpos-1+(n_bits<<3))%(n_bits<<3)))-bitpos)>>3); + n_bits = 9; + free_entry = 256; + bitpos = 0; + } + else + { + unsigned int code = newcode; + if(code >= free_entry) + { + *stackptr++ = lastbyte; + code = oldcode; + } + + while(code >= 256) + { + *stackptr++ = codetable[code].append; + code = codetable[code].prefix; + } + + *stackptr++ = code; + lastbyte = code; + + while(stackptr > decodestack) + result->putUint8(*--stackptr); + + if(free_entry < 4096) + { + codetable[free_entry].prefix = oldcode; + codetable[free_entry].append = lastbyte; + free_entry++; + + if((free_entry >= (unsigned int)(1 << n_bits)) && (n_bits < 12)) + { + n_bits++; + bitpos = 0; + } + } + oldcode = newcode; + } + } + delete[] decodestack; + delete[] codetable; + unsigned int res = result->getBytesDone(); + result->rewind(); + return res; + } + catch (cException &e) + { + e.print("FileBuffer::DecompressLZW"); + throw; + } + return 0; +} + +unsigned int cFileBuffer::decompressLZSS(cFileBuffer *result) +{ + try + { + uint8_t* data = result->getCurrent(); + uint8_t code = 0; + uint8_t mask = 0; + + while(!atEnd() && !result->atEnd()) + { + if(!mask) + { + code = getUint8(); + mask = 0x01; + } + + if(code & mask) + result->putUint8(getUint8()); + else + { + unsigned int off = getUint16LE(); + unsigned int len = getUint8() + 5; + result->putData(data + off, len); + } + mask <<= 1; + } + + unsigned int res = result->getBytesDone(); + result->rewind(); + return res; + } + catch (cException &e) + { + e.print("FileBuffer::DecompressLZSS"); + throw; + } + return 0; +} + +unsigned int cFileBuffer::decompressRLE(cFileBuffer *result) +{ + try + { + while(!atEnd() && !result->atEnd()) + { + uint8_t control = getUint8(); + + if(control & 0x80) + result->putData(getUint8(), control & 0x7f); + else + result->copyFrom(this, control); + } + + unsigned int res = result->getBytesDone(); + result->rewind(); + return res; + } + catch (cException &e) + { + e.print("FileBuffer::DecompressRLE"); + throw; + } + return 0; +} + +unsigned int cFileBuffer::decompress(cFileBuffer *result, const unsigned int method) +{ + switch(method) + { + case COMPRESSION_LZW: + if((getUint8() != 0x02) || (getUint32LE() != result->getSize())) + throw cDataCorruption(__FILE__, __LINE__); + + return(decompressLZW(result)); + break; + case COMPRESSION_LZSS: + return(decompressLZSS(result)); + break; + case COMPRESSION_RLE: + return(decompressRLE(result)); + break; + default: + throw cCompressionError(__FILE__, __LINE__); + break; + } +} + +bool cFileBuffer::atEnd() const +{ + return(m_current >= m_buffer + m_size); +} + +unsigned int cFileBuffer::getSize() const +{ + return(m_size); +} + +unsigned int cFileBuffer::getBytesDone() const +{ + return(m_current - m_buffer); +} + +unsigned int cFileBuffer::getBytesLeft() const +{ + return(m_buffer + m_size - m_current); +} + +uint8_t* cFileBuffer::getCurrent() const +{ + return(m_current); +} + +unsigned int cFileBuffer::getNextBit() const +{ + return(m_nextbit); +} + +void cFileBuffer::rewind() +{ + m_current = m_buffer; +} + +uint8_t cFileBuffer::getUint8() +{ + uint8_t n; + getData(&n, 1); + return(n); +} + +uint16_t cFileBuffer::getUint16LE() +{ + uint16_t n; + getData(&n, 2); + return(SDL_SwapLE16(n)); +} + +uint16_t cFileBuffer::getUint16BE() +{ + uint16_t n; + getData(&n, 2); + return(SDL_SwapBE16(n)); +} + +uint32_t cFileBuffer::getUint32LE() +{ + uint32_t n; + getData(&n, 4); + return(SDL_SwapLE32(n)); +} + +uint32_t cFileBuffer::getUint32BE() +{ + uint32_t n; + getData(&n, 4); + return(SDL_SwapBE32(n)); +} + +int8_t cFileBuffer::getSint8() +{ + int8_t n; + getData(&n, 1); + return(n); +} + +int16_t cFileBuffer::getSint16LE() +{ + int16_t n; + getData(&n, 2); + return(SDL_SwapLE16(n)); +} + +int16_t cFileBuffer::getSint16BE() +{ + int16_t n; + getData(&n, 2); + return(SDL_SwapBE16(n)); +} + +int32_t cFileBuffer::getSint32LE() +{ + int32_t n; + getData(&n, 4); + return(SDL_SwapLE32(n)); +} + +int32_t cFileBuffer::getSint32BE() +{ + int32_t n; + getData(&n, 4); + return(SDL_SwapBE32(n)); +} + +std::string cFileBuffer::getString() +{ + if(m_current) + { + std::string s((char *)m_current); + if((m_current + s.length() + 1) <= (m_buffer + m_size)) + { + m_current += s.length() + 1; + return(s); + } + else + throw cBufferEmpty(__FILE__, __LINE__); + } + return ""; +} + +std::string cFileBuffer::getString(const unsigned int len) +{ + if((m_current) && (m_current + len <= m_buffer + m_size)) + { + std::string s((char *)m_current); + m_current += len; + return(s); + } + else + throw cBufferEmpty(__FILE__, __LINE__); + return ""; +} + +void cFileBuffer::getData(void *data, const unsigned int n) +{ + if(m_current + n <= m_buffer + m_size) + { + memcpy(data, m_current, n); + m_current += n; + } + else + throw cBufferEmpty(__FILE__, __LINE__); +} + +unsigned int cFileBuffer::getBits(const unsigned int n) +{ + if(m_current + ((m_nextbit + n + 7)/8) <= m_buffer + m_size) + { + unsigned int x = 0; + + for(unsigned int i = 0; i < n; i++) + { + if(*m_current & (1 << m_nextbit)) + x += (1 << i); + + m_nextbit++; + if(m_nextbit > 7) + { + m_current++; + m_nextbit = 0; + } + } + return(x); + } + else + throw cBufferEmpty(__FILE__, __LINE__); +} + +void cFileBuffer::putUint8(const uint8_t x) +{ + uint8_t xx = x; + putData(&xx, 1); +} + +void cFileBuffer::putUint16LE(const uint16_t x) +{ + uint16_t xx = SDL_SwapLE16(x); + putData(&xx, 2); +} + +void cFileBuffer::putUint16BE(const uint16_t x) +{ + uint16_t xx = SDL_SwapBE16(x); + putData(&xx, 2); +} + +void cFileBuffer::putUint32LE(const uint32_t x) +{ + uint32_t xx = SDL_SwapLE32(x); + putData(&xx, 4); +} + +void cFileBuffer::putUint32BE(const uint32_t x) +{ + uint32_t xx = SDL_SwapBE32(x); + putData(&xx, 4); +} + +void cFileBuffer::putSint8(const int8_t x) +{ + int8_t xx = x; + putData(&xx, 1); +} + +void cFileBuffer::putSint16LE(const int16_t x) +{ + int16_t xx = SDL_SwapLE16(x); + putData(&xx, 2); +} + +void cFileBuffer::putSint16BE(const int16_t x) +{ + int16_t xx = SDL_SwapBE16(x); + putData(&xx, 2); +} + +void cFileBuffer::putSint32LE(const int32_t x) +{ + int32_t xx = SDL_SwapLE32(x); + putData(&xx, 4); +} + +void cFileBuffer::putSint32BE(const int32_t x) +{ + int32_t xx = SDL_SwapBE32(x); + putData(&xx, 4); +} + +void cFileBuffer::putString(const std::string s) +{ + if((m_current) && (m_current + s.length() + 1 <= m_buffer + m_size)) + { + strncpy((char *)m_current, s.c_str(), s.length() + 1); + m_current += s.length() + 1; + } + else + throw cBufferFull(__FILE__, __LINE__); +} + +void cFileBuffer::putString(const std::string s, const unsigned int len) +{ + if((m_current) && (m_current + len <= m_buffer + m_size)) + { + memset(m_current, 0, len); + strncpy((char *)m_current, s.c_str(), len); + m_current += len; + } + else + throw cBufferFull(__FILE__, __LINE__); +} + +void cFileBuffer::putData(void *data, const unsigned int n) +{ + if(m_current + n <= m_buffer + m_size) + { + memcpy(m_current, data, n); + m_current += n; + } + else + throw cBufferFull(__FILE__, __LINE__); +} + +void cFileBuffer::putData(const uint8_t x, const unsigned int n) +{ + if(m_current + n <= m_buffer + m_size) + { + memset(m_current, x, n); + m_current += n; + } + else + throw cBufferFull(__FILE__, __LINE__); +} + +void cFileBuffer::putBits(const unsigned int x, const unsigned int n) +{ + if(m_current + ((m_nextbit + n + 7)/8) <= m_buffer + m_size) + { + for(unsigned int i = 0; i < n; i++) + { + if(x & (1 << i)) + *m_current |= (1 << m_nextbit); + else + *m_current &= ~(1 << m_nextbit); + + m_nextbit++; + if(m_nextbit > 7) + { + m_current++; + m_nextbit = 0; + } + } + } + else + throw cBufferFull(__FILE__, __LINE__); +} diff --git a/cfilebuffer.h b/cfilebuffer.h new file mode 100644 index 0000000..b3b0bf2 --- /dev/null +++ b/cfilebuffer.h @@ -0,0 +1,86 @@ +#ifndef CFILEBUFFER_H +#define CFILEBUFFER_H + + +#include +#include + + +const unsigned int COMPRESSION_LZW = 0; +const unsigned int COMPRESSION_LZSS = 1; +const unsigned int COMPRESSION_RLE = 2; + + +class cFileBuffer +{ +public: + cFileBuffer(const unsigned int n); + virtual ~cFileBuffer(); + + void load(std::ifstream &ifs); + void save(std::ofstream &ofs); + void save(std::ofstream &ofs, const unsigned int n); + void dump(const unsigned int n = 0); + void copyFrom(cFileBuffer *buf, const unsigned int n); + void copyTo(cFileBuffer* buf, const unsigned int n); + void fill(cFileBuffer* buf); + void rewind(); + void seek(const unsigned int n); + void skip(const int n); + + void skipBits(); + unsigned int compressLZW(cFileBuffer* result); + unsigned int compressLZSS(cFileBuffer* result); + unsigned int compressRLE(cFileBuffer* result); + unsigned int compress(cFileBuffer* result, const unsigned int method); + unsigned int decompressLZW(cFileBuffer* result); + unsigned int decompressLZSS(cFileBuffer* result); + unsigned int decompressRLE(cFileBuffer* result); + unsigned int decompress(cFileBuffer* result, const unsigned int method); + + bool atEnd() const; + unsigned int getSize() const; + unsigned int getBytesDone() const; + unsigned int getBytesLeft() const; + uint8_t* getCurrent() const; + unsigned int getNextBit() const; + + uint8_t getUint8(); + uint16_t getUint16LE(); + uint16_t getUint16BE(); + uint32_t getUint32LE(); + uint32_t getUint32BE(); + int8_t getSint8(); + int16_t getSint16LE(); + int16_t getSint16BE(); + int32_t getSint32LE(); + int32_t getSint32BE(); + std::string getString(); + std::string getString(const unsigned int len); + void getData(void* data, const unsigned int n); + unsigned int getBits(const unsigned int n); + + void putUint8(const uint8_t x); + void putUint16LE(const uint16_t x); + void putUint16BE(const uint16_t x); + void putUint32LE(const uint32_t x); + void putUint32BE(const uint32_t x); + void putSint8(const int8_t x); + void putSint16LE(const int16_t x); + void putSint16BE(const int16_t x); + void putSint32LE(const int32_t x); + void putSint32BE(const int32_t x); + void putString(const std::string s); + void putString(const std::string s, const unsigned int len); + void putData(void * data, const unsigned int n); + void putData(const uint8_t x, const unsigned int n); + void putBits(const unsigned int x, const unsigned int n); + +private: + uint8_t* m_buffer; + uint8_t* m_current; + unsigned int m_size; + unsigned int m_nextbit; +}; + +#endif // CFILEBUFFER_H diff --git a/cfilemanager.cpp b/cfilemanager.cpp new file mode 100644 index 0000000..8b3d5d5 --- /dev/null +++ b/cfilemanager.cpp @@ -0,0 +1,444 @@ +#include "cfilemanager.h" + + +#include "cconfigfile.h" +#include "cexception.h" +#include "cfilemanager.h" +//#include "GameFile.h" +#include "cresourcefile.h" + + +cFileManager* cFileManager::m_instance = nullptr; + +cFileManager::cFileManager() +{ + m_resIndex.load("krondor.rmf"); + m_resArchive.open(m_resIndex.getResourceFilename(), false); +} + +cFileManager::~cFileManager() +{ +// resArchive.Close(); +} + +cFileManager* cFileManager::getInstance() +{ + if(!m_instance) + m_instance = new cFileManager(); + + return(m_instance); +} + +void cFileManager::cleanUp() +{ + if(m_instance) + { + delete m_instance; + m_instance = 0; + } +} + +cFileBuffer* cFileManager::loadConfig(const QString &name) +{ + try + { + cConfigFile cfgfile; + cfgfile.open(name, false); + cFileBuffer *buffer = new cFileBuffer(cfgfile.size()); + cfgfile.seek(0); + cfgfile.load(*buffer); + cfgfile.close(); + return buffer; + } + catch(cException &e) + { + e.print("FileManager::LoadConfig"); + throw; + } + return 0; +} + +//void +//FileManager::SaveConfig(const std::string &name, FileBuffer* buffer) +//{ +// try +// { +// ConfigFile cfgfile; +// cfgfile.Open(name, true); +// cfgfile.Save(*buffer); +// cfgfile.Close(); +// } +// catch (Exception &e) +// { +// e.Print("FileManager::SaveConfig"); +// throw; +// } +//} + +//void +//FileManager::SaveConfig(const std::string &name, FileBuffer* buffer, const unsigned int n) +//{ +// try +// { +// ConfigFile cfgfile; +// cfgfile.Open(name, true); +// cfgfile.Save(*buffer, n); +// cfgfile.Close(); +// } +// catch (Exception &e) +// { +// e.Print("FileManager::SaveConfig"); +// throw; +// } +//} + +//FileBuffer* +//FileManager::LoadGame(const std::string &name) +//{ +// try +// { +// GameFile gamfile; +// gamfile.Open(name, false); +// FileBuffer *buffer = new FileBuffer(gamfile.Size()); +// gamfile.Seek(0); +// gamfile.Load(*buffer); +// gamfile.Close(); +// return buffer; +// } +// catch (Exception &e) +// { +// e.Print("FileManager::LoadGame"); +// throw; +// } +// return 0; +//} + +//void +//FileManager::SaveGame(const std::string &name, FileBuffer* buffer) +//{ +// try +// { +// GameFile gamfile; +// gamfile.Open(name, true); +// gamfile.Save(*buffer); +// gamfile.Close(); +// } +// catch (Exception &e) +// { +// e.Print("FileManager::SaveGame"); +// throw; +// } +//} + +//void +//FileManager::SaveGame(const std::string &name, FileBuffer* buffer, const unsigned int n) +//{ +// try +// { +// GameFile gamfile; +// gamfile.Open(name, true); +// gamfile.Save(*buffer, n); +// gamfile.Close(); +// } +// catch (Exception &e) +// { +// e.Print("FileManager::SaveGame"); +// throw; +// } +//} + +cFileBuffer* cFileManager::loadResource(const QString& name) +{ + try + { + cResourceFile resfile; + resfile.open(name, false); + cFileBuffer* buffer = new cFileBuffer(resfile.size()); + resfile.seek(0); + resfile.load(*buffer); + resfile.close(); + return(buffer); + } + catch(cException &e1) + { + cResourceIndexData resIdxData = {0, 0, 0}; + if(m_resIndex.find(name, resIdxData) && (resIdxData.m_size != 0)) + { + try + { + cFileBuffer* buffer = new cFileBuffer(resIdxData.m_size); + m_resArchive.loadResource(*buffer, resIdxData.m_offset); + return(buffer); + } + catch(cException &e2) + { + e2.print("FileManager::LoadResource"); + throw; + } + } + else + throw cFileNotFound(__FILE__, __LINE__, name); + } + return(0); +} + +//void +//FileManager::SaveResource(const std::string &name, FileBuffer* buffer) +//{ +// try +// { +// ResourceFile resfile; +// resfile.Open(name, true); +// resfile.Save(*buffer); +// resfile.Close(); +// } +// catch (Exception &e) +// { +// e.Print("FileManager::SaveResource"); +// throw; +// } +//} + +//void +//FileManager::SaveResource(const std::string &name, FileBuffer* buffer, const unsigned int n) +//{ +// try +// { +// ResourceFile resfile; +// resfile.Open(name, true); +// resfile.Save(*buffer, n); +// resfile.Close(); +// } +// catch (Exception &e) +// { +// e.Print("FileManager::SaveResource"); +// throw; +// } +//} + +//bool +//FileManager::ConfigExists(const std::string &name) +//{ +// try +// { +// ConfigFile cfgfile; +// cfgfile.Open(name, false); +// cfgfile.Close(); +// return true; +// } +// catch (Exception &e) +// { +// return false; +// } +// return false; +//} + +void cFileManager::load(cConfigData* cfg, const QString& name) +{ + try + { + cFileBuffer* buffer; + buffer = loadConfig(name); + cfg->load(buffer); + delete buffer; + } + catch(cException &e) + { + e.print("cFileManager::load"); + throw; + } +} + +//void +//FileManager::Save(ConfigData *cfg, const std::string &name) +//{ +// try +// { +// FileBuffer *buffer = new FileBuffer(16); +// unsigned int size = cfg->Save(buffer); +// SaveConfig(name, buffer, size); +// delete buffer; +// } +// catch (Exception &e) +// { +// e.Print("FileManager::Save"); +// throw; +// } +//} + +//bool +//FileManager::GameExists(const std::string &name) +//{ +// try +// { +// GameFile gamfile; +// gamfile.Open(name, false); +// gamfile.Close(); +// return true; +// } +// catch (Exception &e) +// { +// return false; +// } +// return false; +//} + +//void +//FileManager::Load(GameData *gam, const std::string &name) +//{ +// try +// { +// FileBuffer *buffer; +// buffer = LoadGame(name); +// gam->Load(buffer); +// delete buffer; +// } +// catch (Exception &e) +// { +// e.Print("FileManager::Load"); +// throw; +// } +//} + +//void +//FileManager::Save(GameData *gam, const std::string &name) +//{ +// try +// { +// FileBuffer *buffer = new FileBuffer(400000); +// unsigned int size = gam->Save(buffer); +// SaveGame(name, buffer, size); +// delete buffer; +// } +// catch (Exception &e) +// { +// e.Print("FileManager::Save"); +// throw; +// } +//} + +//bool +//FileManager::ResourceExists(const std::string &name) +//{ +// try +// { +// ResourceFile resfile; +// resfile.Open(name, false); +// resfile.Close(); +// return true; +// } +// catch (Exception &e1) +// { +// ResourceIndexData resIdxData = {0, 0, 0}; +// return (resIndex.Find(name, resIdxData) && (resIdxData.size != 0)); +// } +// return false; +//} + +void cFileManager::load(cResourceData *res, const QString& name) +{ + try + { + cFileBuffer *buffer; + buffer = loadResource(name); + res->load(buffer); + delete buffer; + } + catch (cException &e) + { + e.print("FileManager::Load"); + throw; + } +} + +//void +//FileManager::Save(ResourceData *res, const std::string &name) +//{ +// try +// { +// FileBuffer *buffer = new FileBuffer(0x20000); +// unsigned int size = res->Save(buffer); +// SaveResource(name, buffer, size); +// delete buffer; +// } +// catch (Exception &e) +// { +// e.Print("FileManager::Save"); +// throw; +// } +//} + +//void +//FileManager::ExtractResource(const std::string &name) +//{ +// try +// { +// FileBuffer *buffer; +// buffer = LoadResource(name); +// SaveResource(name, buffer); +// delete buffer; +// } +// catch (Exception &e) +// { +// e.Print("FileManager::ExtractResource"); +// throw; +// } +//} + +//void +//FileManager::ExtractAllResources() +//{ +// try +// { +// std::string resName; +// ResourceIndexData resIdxData = {0, 0, 0}; +// if (resIndex.GetFirst(resName, resIdxData)) +// { +// do +// { +// FileBuffer *buffer = new FileBuffer(resIdxData.size); +// resArchive.LoadResource(*buffer, resIdxData.offset); +// SaveResource(resName, buffer); +// delete buffer; +// } +// while (resIndex.GetNext(resName, resIdxData)); +// } +// } +// catch (Exception &e) +// { +// e.Print("FileManager::ExtractAllResources"); +// throw; +// } +//} + +//void +//FileManager::ArchiveAllResources() +//{ +// try +// { +// std::string resName; +// ResourceIndexData resIdxData = {0, 0, 0}; +// FileBuffer *archiveBuffer = new FileBuffer(0x1000000); +// if (resIndex.GetFirst(resName, resIdxData)) +// { +// do +// { +// FileBuffer *buffer = new FileBuffer(resIdxData.size); +// resArchive.LoadResource(*buffer, resIdxData.offset); +// archiveBuffer->PutString(resName, RES_FILENAME_LEN); +// archiveBuffer->PutUint32LE(resIdxData.size); +// archiveBuffer->CopyFrom(buffer, resIdxData.size); +// delete buffer; +// } +// while (resIndex.GetNext(resName, resIdxData)); +// } +// SaveResource(resIndex.GetResourceFilename(), archiveBuffer, archiveBuffer->GetBytesDone()); +// resIndex.Save("krondor.rmf"); +// delete archiveBuffer; +// } +// catch (Exception &e) +// { +// e.Print("FileManager::ArchiveAllResources"); +// throw; +// } +//} diff --git a/cfilemanager.h b/cfilemanager.h new file mode 100644 index 0000000..8af84fc --- /dev/null +++ b/cfilemanager.h @@ -0,0 +1,52 @@ +#ifndef CFILEMANAGER_H +#define CFILEMANAGER_H + + +#include "cconfigdata.h" +//#include "GameData.h" +#include "cresourcearchive.h" +#include "cresourcedata.h" +#include "cresourceindex.h" + +#include + + +class cFileManager +{ +public: + ~cFileManager(); + static cFileManager* getInstance(); + static void cleanUp(); +// bool ConfigExists ( const std::string &name ); + void load(cConfigData* cfg, const QString& name); +// void Save ( ConfigData *cfg, const std::string &name ); +// bool GameExists ( const std::string &name ); +// void Load ( GameData *gam, const std::string &name ); +// void Save ( GameData *gam, const std::string &name ); +// bool ResourceExists ( const std::string &name ); + void load(cResourceData *res, const QString& name); +// void Save ( ResourceData *res, const std::string &name ); +// void ExtractResource ( const std::string &name ); +// void ExtractAllResources(); +// void ArchiveAllResources(); + +//private: + cResourceIndex m_resIndex; + cResourceArchive m_resArchive; + cFileBuffer* loadConfig(const QString& name); +// void SaveConfig ( const std::string &name, FileBuffer* buffer ); +// void SaveConfig ( const std::string &name, FileBuffer* buffer, const unsigned int n ); +// FileBuffer* LoadGame ( const std::string &name ); +// void SaveGame ( const std::string &name, FileBuffer* buffer ); +// void SaveGame ( const std::string &name, FileBuffer* buffer, const unsigned int n ); + cFileBuffer* loadResource(const QString& name); +// void SaveResource ( const std::string &name, FileBuffer* buffer ); +// void SaveResource ( const std::string &name, FileBuffer* buffer, const unsigned int n ); + static cFileManager* m_instance; + +protected: + cFileManager(); + +}; + +#endif // CFILEMANAGER_H diff --git a/cfont.cpp b/cfont.cpp new file mode 100644 index 0000000..d7548d1 --- /dev/null +++ b/cfont.cpp @@ -0,0 +1,74 @@ +#include "cexception.h" +#include "cfont.h" +#include "cmediatoolkit.h" + + +cFont::cFont() : + m_first(0), + m_height(0) +{ +} + +cFont::~cFont() +{ + m_fontGlyphs.clear(); +} + +unsigned int cFont::getFirst() const +{ + return(m_first); +} + +void cFont::setFirst(unsigned int n) +{ + m_first = n; +} + +int cFont::getHeight() const +{ + return(m_height); +} + +void cFont::setHeight(int h) +{ + m_height = h; +} + +int cFont::getWidth(unsigned int n) const +{ + if(n < m_fontGlyphs.size()) + return(m_fontGlyphs[n].width); + else + throw cIndexOutOfRange(__FILE__, __LINE__); +} + +unsigned int cFont::getSize() const +{ + return(m_fontGlyphs.size()); +} + +FontGlyph& cFont::getGlyph(unsigned int n) +{ + if(n < m_fontGlyphs.size()) + return(m_fontGlyphs[n]); + else + throw cIndexOutOfRange(__FILE__, __LINE__); +} + +void cFont::addGlyph(FontGlyph& glyph) +{ + m_fontGlyphs.push_back(glyph); +} + +void cFont::drawChar(int x, int y, int ch, int color, bool italic) +{ +// Video *video = cMediaToolkit::getInstance()->getVideo(); + +// if((int)(ch - m_first) >= 0) +// { +// if(italic) +// video->drawGlyphItalic(x, y, fontGlyphs[ch - first].width, height, color, fontGlyphs[ch - first].data); +// else +// video->drawGlyph (x, y, fontGlyphs[ch - first].width, height, color, fontGlyphs[ch - first].data); +// } +} diff --git a/cfont.h b/cfont.h new file mode 100644 index 0000000..e7549b0 --- /dev/null +++ b/cfont.h @@ -0,0 +1,41 @@ +#ifndef CFONT_H +#define CFONT_H + + +#include + + +const unsigned int MAX_FONT_HEIGHT = 16; + +typedef uint16_t glyphData[MAX_FONT_HEIGHT]; + + +struct FontGlyph +{ + unsigned int width; + glyphData data; +}; + +class cFont +{ +public: + cFont(); + virtual ~cFont(); + unsigned int getFirst() const; + void setFirst(unsigned int n); + int getHeight() const; + void setHeight(int h); + int getWidth(unsigned int n) const; + unsigned int getSize() const; + FontGlyph& getGlyph(unsigned int n); + void addGlyph(FontGlyph& glyph); + void drawChar(int x, int y, int ch, int color, bool italic); + +private: + unsigned int m_first; + int m_height; + std::vector m_fontGlyphs; +}; + + +#endif // CFONT_H diff --git a/cfontresource.cpp b/cfontresource.cpp new file mode 100644 index 0000000..f13ddc9 --- /dev/null +++ b/cfontresource.cpp @@ -0,0 +1,107 @@ +#include "cexception.h" +#include "cfontresource.h" +#include "cmediatoolkit.h" + + +cFontResource::cFontResource() : + cTaggedResource(), + m_font(0) +{ +} + +cFontResource::~cFontResource() +{ + clear(); +} + +cFont* cFontResource::getFont() const +{ + return(m_font); +} + +void cFontResource::clear() +{ + delete(m_font); +} + +void cFontResource::load(cFileBuffer *buffer) +{ + try + { + clear(); + split(buffer); + cFileBuffer *fntbuf; + + if(!find(TAG_FNT, fntbuf)) + { + clearTags(); + throw cDataCorruption(__FILE__, __LINE__); + } + + m_font = new cFont; + fntbuf->skip(2); + m_font->setHeight((unsigned int)fntbuf->getUint8()); + fntbuf->skip(1); + m_font->setFirst((unsigned int)fntbuf->getUint8()); + + unsigned int numChars = (unsigned int)fntbuf->getUint8(); + fntbuf->skip(2); + + if(fntbuf->getUint8() != 0x01) + { + clearTags(); + throw cCompressionError(__FILE__, __LINE__); + } + + unsigned int size = (unsigned int)fntbuf->getUint32LE(); + cFileBuffer* glyphbuf = new cFileBuffer(size); + fntbuf->decompressRLE(glyphbuf); + + unsigned int* glyphOffset = new unsigned int [numChars]; + + for(unsigned int i = 0; i < numChars; i++) + glyphOffset[i] = glyphbuf->getUint16LE(); + + unsigned int glyphDataStart = glyphbuf->getBytesDone(); + for(unsigned int i = 0; i < numChars; i++) + { + FontGlyph glyph; + glyphbuf->seek(glyphDataStart + i); + glyph.width = (unsigned int)glyphbuf->getUint8(); + glyphbuf->seek(glyphDataStart + numChars + glyphOffset[i]); + + for(int j = 0; j < m_font->getHeight(); j++) + { + glyph.data[j] = (uint16_t)glyphbuf->getUint8() << 8; + + if(glyph.width > 8) + glyph.data[j] += (uint16_t)glyphbuf->getUint8(); + } + m_font->addGlyph(glyph); + } + delete[] glyphOffset; + delete glyphbuf; + clearTags(); + } + catch (cException &e) + { + e.print("FontResource::Load"); + clearTags(); + throw; + } +} + +unsigned int cFontResource::save(cFileBuffer *buffer) +{ + try + { + // TODO + buffer = buffer; + return 0; + } + catch (cException &e) + { + e.print("FontResource::Save"); + throw; + } +} diff --git a/cfontresource.h b/cfontresource.h new file mode 100644 index 0000000..4f7ea52 --- /dev/null +++ b/cfontresource.h @@ -0,0 +1,23 @@ +#ifndef CFONTRESOURCE_H +#define CFONTRESOURCE_H + + +#include "cfont.h" +#include "ctaggedresource.h" + + +class cFontResource : public cTaggedResource +{ +public: + cFontResource(); + virtual ~cFontResource(); + cFont* getFont() const; + void clear(); + void load(cFileBuffer *buffer); + unsigned int save(cFileBuffer *buffer); + +private: + cFont* m_font; +}; + +#endif // CFONTRESOURCE_H diff --git a/cgameapplication.cpp b/cgameapplication.cpp new file mode 100644 index 0000000..554957c --- /dev/null +++ b/cgameapplication.cpp @@ -0,0 +1,266 @@ +//#include "AnimationResource.h" +//#include "Directories.h" +//#include "Exception.h" +#include "cfilemanager.h" +#include "cfontresource.h" +#include "cgameapplication.h" +//#include "MoviePlayer.h" +//#include "ObjectResource.h" +//#include "PointerManager.h" +#include "csdl_toolkit.h" +//#include "Text.h" + + +cGameApplication* cGameApplication::m_instance = nullptr; + +cGameApplication::cGameApplication() +// : done ( false ) +// , inputGrabbed ( false ) +// , game() +// , state ( 0 ) +// , screenSaveCount ( 0 ) +{ +// MediaToolkit* media = MediaToolkit::GetInstance(); +// media->GetVideo()->CreateWindow ( 1 ); +// media->GetVideo()->SetMode ( LORES_HICOL ); +// media->GetVideo()->Clear(); + +// PaletteResource pal; +// pal.GetPalette()->Fill(); +// pal.GetPalette()->Activate ( 0, WINDOW_COLORS ); + + cFontResource fnt; + cFileManager::getInstance()->load(&fnt, "GAME.FNT"); +// TextBlock txt ( "xBaK: Betrayal at Krondor A fan-made remake", 15, 0, 0, 0, false ); +// txt.Draw ( 16, 16, 240, 16, fnt.GetFont() ); +// media->GetVideo()->Refresh(); + +// config = new ConfigResource; +// if ( FileManager::GetInstance()->ConfigExists ( "krondor.cfg" ) ) +// { +// FileManager::GetInstance()->Load ( config, "krondor.cfg" ); +// } +// else +// { +// Preferences *prefs = new Preferences(); +// prefs->SetDefaults(); +// config->SetPreferences ( prefs ); +// FileManager::GetInstance()->Save ( config, "krondor.cfg" ); +// } +// game = new GameResource; +// PointerManager::GetInstance()->AddPointer ( "POINTER.BMX" ); +// PointerManager::GetInstance()->AddPointer ( "POINTERG.BMX" ); + +// media->GetClock()->Delay ( 500 ); +} + +cGameApplication::~cGameApplication() +{ +// if ( config ) +// { +// delete config; +// } +// if ( game ) +// { +// delete game; +// } +// PointerManager::CleanUp(); +// MediaToolkit::CleanUp(); +// ObjectResource::CleanUp(); +// SoundResource::CleanUp(); +// FileManager::CleanUp(); +} + +cGameApplication* cGameApplication::getInstance() +{ + if(!m_instance) + m_instance = new cGameApplication(); + + return(m_instance); +} + +void cGameApplication::cleanUp() +{ +// GameStateCast::CleanUp(); +// GameStateCamp::CleanUp(); +// GameStateChapter::CleanUp(); +// GameStateCombat::CleanUp(); +// GameStateContents::CleanUp(); +// GameStateFullMap::CleanUp(); +// GameStateInfo::CleanUp(); +// GameStateInitialOptions::CleanUp(); +// GameStateIntro::CleanUp(); +// GameStateInventory::CleanUp(); +// GameStateLoad::CleanUp(); +// GameStateMap::CleanUp(); +// GameStateOptions::CleanUp(); +// GameStatePreferences::CleanUp(); +// GameStateSave::CleanUp(); +// GameStateWorld::CleanUp(); + + if(m_instance) + { + delete m_instance; + m_instance = 0; + } +} + +//Preferences * GameApplication::GetPreferences() +//{ +// return config->GetPreferences(); +//} + +//Game * GameApplication::GetGame() +//{ +// return game->GetGame(); +//} + +//void GameApplication::SetState ( GameState *st ) +//{ +// state = st; +//} + +//void GameApplication::PlayIntro() +//{ +// try +// { +// AnimationResource anim; +// FileManager::GetInstance()->Load ( &anim, "INTRO.ADS" ); +// MovieResource ttm; +// FileManager::GetInstance()->Load ( &ttm, anim.GetAnimationData ( 1 ).resource ); +// MoviePlayer moviePlayer; +// moviePlayer.Play ( &ttm.GetMovieChunks(), true ); +// } +// catch ( Exception &e ) +// { +// e.Print ( "GameApplication::Intro" ); +// } +//} + +//void GameApplication::StartNewGame() +//{ +// FileManager::GetInstance()->Load ( game, "startup.gam" ); +// game->GetGame()->GetParty()->ActivateMember ( 0, 0 ); +// game->GetGame()->GetParty()->ActivateMember ( 1, 2 ); +// game->GetGame()->GetParty()->ActivateMember ( 2, 1 ); +// game->GetGame()->GetCamera()->SetPosition ( Vector2D ( 669600, 1064800 ) ); +// game->GetGame()->GetCamera()->SetHeading ( SOUTH ); +//} + +//void GameApplication::QuitGame() +//{ +// done = true; +//} + +//void GameApplication::SaveConfig() +//{ +// FileManager::GetInstance()->Save ( config, "krondor.cfg" ); +//} + +void cGameApplication::run() +{ +// try +// { +// state = GameStateIntro::GetInstance(); +// MediaToolkit::GetInstance()->AddKeyboardListener ( this ); +// MediaToolkit::GetInstance()->AddPointerButtonListener ( this ); +// MediaToolkit::GetInstance()->AddTimerListener ( this ); +// state->Enter(); +// GameState *savedState = state; +// done = false; +// while ( !done ) +// { +// if ( state != savedState ) +// { +// savedState->Leave(); +// state->Enter(); +// savedState = state; +// } +// state->Execute(); +// } +// savedState->Leave(); +// MediaToolkit::GetInstance()->RemoveKeyboardListener ( this ); +// MediaToolkit::GetInstance()->RemovePointerButtonListener ( this ); +// MediaToolkit::GetInstance()->RemoveTimerListener ( this ); +// } +// catch ( Exception &e ) +// { +// e.Print ( "GameApplication::Run" ); +// } +} + +//void GameApplication::KeyPressed ( const KeyboardEvent& kbe ) +//{ +// switch ( kbe.GetKey() ) +// { +// case KEY_F11: +// { +// screenSaveCount++; +// std::stringstream filenameStream; +// filenameStream << Directories::GetInstance()->GetCapturePath(); +// filenameStream << "xbak_" << std::setw ( 3 ) << std::setfill ( '0' ) << screenSaveCount << ".bmp"; +// MediaToolkit::GetInstance()->GetVideo()->SaveScreenShot ( filenameStream.str() ); +// } +// break; +// case KEY_F12: +// inputGrabbed = !inputGrabbed; +// MediaToolkit::GetInstance()->GetVideo()->GrabInput ( inputGrabbed ); +// break; +// default: +// break; +// } +//} + +//void GameApplication::KeyReleased ( const KeyboardEvent& kbe ) +//{ +// switch ( kbe.GetKey() ) +// { +// default: +// break; +// } +//} + +//void GameApplication::PointerButtonPressed ( const PointerButtonEvent& pbe ) +//{ +// switch ( pbe.GetButton() ) +// { +// case PB_PRIMARY: +// case PB_SECONDARY: +// if ( !inputGrabbed ) +// { +// inputGrabbed = true; +// MediaToolkit::GetInstance()->GetVideo()->GrabInput ( true ); +// } +// break; +// case PB_TERTIARY: +// if ( inputGrabbed ) +// { +// inputGrabbed = false; +// MediaToolkit::GetInstance()->GetVideo()->GrabInput ( false ); +// } +// break; +// default: +// break; +// } +//} + +//void GameApplication::PointerButtonReleased ( const PointerButtonEvent& pbe ) +//{ +// switch ( pbe.GetButton() ) +// { +// default: +// break; +// } +//} + +//void GameApplication::TimerExpired ( const TimerEvent& te ) +//{ +// if ( te.GetID() == TMR_MOVING ) +// { +// state->Move(); +// } +// if ( te.GetID() == TMR_TURNING ) +// { +// state->Turn(); +// } +//} diff --git a/cgameapplication.h b/cgameapplication.h new file mode 100644 index 0000000..cd1a34f --- /dev/null +++ b/cgameapplication.h @@ -0,0 +1,84 @@ +#ifndef CGAMEAPPLICATION_H +#define CGAMEAPPLICATION_H + + +//#include "ConfigResource.h" +//#include "GameResource.h" +//#include "GameState.h" + + +class cGameApplication +// : public KeyboardEventListener +// , public PointerButtonEventListener +// , public TimerEventListener +{ +public: + ~cGameApplication(); + static cGameApplication* getInstance(); + static void cleanUp(); +// Preferences* GetPreferences(); +// Game* GetGame(); +// void PlayIntro(); +// void StartNewGame(); +// void QuitGame(); +// void SaveConfig(); + void run(); +// void KeyPressed ( const KeyboardEvent& kbe ); +// void KeyReleased ( const KeyboardEvent& kbe ); +// void PointerButtonPressed ( const PointerButtonEvent& pbe ); +// void PointerButtonReleased ( const PointerButtonEvent& pbe ); +// void TimerExpired ( const TimerEvent& te ); + +private: +// friend class GameState; +// bool done; +// bool inputGrabbed; +// ConfigResource *config; +// GameResource *game; +// GameState *state; +// int screenSaveCount; + static cGameApplication* m_instance; +// void SetState ( GameState *st ); + +protected: + cGameApplication(); +}; + +/* +class GameApplication +: public KeyboardEventListener +, public PointerButtonEventListener +, public TimerEventListener +{ + private: + friend class GameState; + bool done; + bool inputGrabbed; + ConfigResource *config; + GameResource *game; + GameState *state; + int screenSaveCount; + static GameApplication *instance; + void SetState ( GameState *st ); + protected: + GameApplication(); + public: + ~GameApplication(); + static GameApplication* GetInstance(); + static void CleanUp(); + Preferences* GetPreferences(); + Game* GetGame(); + void PlayIntro(); + void StartNewGame(); + void QuitGame(); + void SaveConfig(); + void Run(); + void KeyPressed ( const KeyboardEvent& kbe ); + void KeyReleased ( const KeyboardEvent& kbe ); + void PointerButtonPressed ( const PointerButtonEvent& pbe ); + void PointerButtonReleased ( const PointerButtonEvent& pbe ); + void TimerExpired ( const TimerEvent& te ); +}; +*/ + +#endif // CGAMEAPPLICATION_H diff --git a/cmainwindow.cpp b/cmainwindow.cpp new file mode 100644 index 0000000..646a9b7 --- /dev/null +++ b/cmainwindow.cpp @@ -0,0 +1,26 @@ +#include "cmainwindow.h" +#include "ui_cmainwindow.h" + +#include "cdirectories.h" +#include "cgameapplication.h" + +#include + + +cMainWindow::cMainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::cMainWindow) +{ + cGameApplication::getInstance()->run(); + cGameApplication::cleanUp(); + + ui->setupUi(this); +} + +cMainWindow::~cMainWindow() +{ + cDirectories::cleanUp(); + + delete ui; +} + diff --git a/cmainwindow.h b/cmainwindow.h new file mode 100644 index 0000000..65f0642 --- /dev/null +++ b/cmainwindow.h @@ -0,0 +1,21 @@ +#ifndef CMAINWINDOW_H +#define CMAINWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class cMainWindow; } +QT_END_NAMESPACE + +class cMainWindow : public QMainWindow +{ + Q_OBJECT + +public: + cMainWindow(QWidget *parent = nullptr); + ~cMainWindow(); + +private: + Ui::cMainWindow *ui; +}; +#endif // CMAINWINDOW_H diff --git a/cmainwindow.ui b/cmainwindow.ui new file mode 100644 index 0000000..7dddbe4 --- /dev/null +++ b/cmainwindow.ui @@ -0,0 +1,22 @@ + + + cMainWindow + + + + 0 + 0 + 800 + 600 + + + + cMainWindow + + + + + + + + diff --git a/cmediatoolkit.cpp b/cmediatoolkit.cpp new file mode 100644 index 0000000..b107789 --- /dev/null +++ b/cmediatoolkit.cpp @@ -0,0 +1,129 @@ +#include "cexception.h" +#include "cmediatoolkit.h" +#include "csdl_toolkit.h" + + +cMediaToolkit* cMediaToolkit::m_instance = 0; + + +cMediaToolkit::cMediaToolkit() +// : audio(0) +// , clock(0) +// , video(0) +// , eventLoopRunning(false) +// , keyboardListeners() +// , pointerButtonListeners() +// , pointerMotionListeners() +// , timerListeners() +// , loopListeners() +{ +} + +cMediaToolkit::~cMediaToolkit() +{ +// keyboardListeners.clear(); +// pointerButtonListeners.clear(); +// pointerMotionListeners.clear(); +// timerListeners.clear(); +// loopListeners.clear(); +} + +cMediaToolkit* cMediaToolkit::getInstance() +{ + if(!m_instance) + m_instance = new cSDL_Toolkit(); + return m_instance; +} + +void cMediaToolkit::cleanUp() +{ + if(m_instance) + { + delete(m_instance); + m_instance = 0; + } +} + +//Audio* +//MediaToolkit::GetAudio() const +//{ +// return audio; +//} + +//Clock* +//MediaToolkit::GetClock() const +//{ +// return clock; +//} + +//Video* +//MediaToolkit::GetVideo() const +//{ +// return video; +//} + +//void +//MediaToolkit::AddKeyboardListener(KeyboardEventListener *kel) +//{ +// keyboardListeners.push_back(kel); +//} + +//void +//MediaToolkit::RemoveKeyboardListener(KeyboardEventListener *kel) +//{ +// keyboardListeners.remove(kel); +//} + +//void +//MediaToolkit::AddPointerButtonListener(PointerButtonEventListener *pbel) +//{ +// pointerButtonListeners.push_back(pbel); +//} + +//void +//MediaToolkit::RemovePointerButtonListener(PointerButtonEventListener *pbel) +//{ +// pointerButtonListeners.remove(pbel); +//} + +//void +//MediaToolkit::AddPointerMotionListener(PointerMotionEventListener *pmel) +//{ +// pointerMotionListeners.push_back(pmel); +//} + +//void +//MediaToolkit::RemovePointerMotionListener(PointerMotionEventListener *pmel) +//{ +// pointerMotionListeners.remove(pmel); +//} + +//void +//MediaToolkit::AddTimerListener(TimerEventListener *tel) +//{ +// timerListeners.push_back(tel); +//} + +//void +//MediaToolkit::RemoveTimerListener(TimerEventListener *tel) +//{ +// timerListeners.remove(tel); +//} + +//void +//MediaToolkit::AddUpdateListener(LoopEventListener *lel) +//{ +// loopListeners.push_back(lel); +//} + +//void +//MediaToolkit::RemoveUpdateListener(LoopEventListener *lel) +//{ +// loopListeners.remove(lel); +//} + +//void +//MediaToolkit::TerminateEventLoop() +//{ +// eventLoopRunning = false; +//} diff --git a/cmediatoolkit.h b/cmediatoolkit.h new file mode 100644 index 0000000..06edc4f --- /dev/null +++ b/cmediatoolkit.h @@ -0,0 +1,58 @@ +#ifndef CMEDIATOOLKIT_H +#define CMEDIATOOLKIT_H + + +#include + +//#include "Audio.h" +//#include "Clock.h" +//#include "EventListener.h" +//#include "Video.h" + + +class cMediaToolkit +{ +public: + cMediaToolkit(); + virtual ~cMediaToolkit(); + static cMediaToolkit* getInstance(); + static void cleanUp(); +// Audio* GetAudio() const; +// Clock* GetClock() const; +// Video* GetVideo() const; +// void AddKeyboardListener ( KeyboardEventListener *kel ); +// void RemoveKeyboardListener ( KeyboardEventListener *kel ); +// void AddPointerButtonListener ( PointerButtonEventListener *pbel ); +// void RemovePointerButtonListener ( PointerButtonEventListener *pbel ); +// void AddPointerMotionListener ( PointerMotionEventListener *pmel ); +// void RemovePointerMotionListener ( PointerMotionEventListener *pmel ); +// void AddTimerListener ( TimerEventListener *tel ); +// void RemoveTimerListener ( TimerEventListener *tel ); +// void AddUpdateListener ( LoopEventListener *lel ); +// void RemoveUpdateListener ( LoopEventListener *lel ); +// void TerminateEventLoop(); +// virtual void PollEvents() = 0; +// virtual void PollEventLoop() = 0; +// virtual void WaitEvents() = 0; +// virtual void WaitEventLoop() = 0; +// virtual void ClearEvents() = 0; +// virtual void GetPointerPosition ( int *x, int *y ) = 0; +// virtual void SetPointerPosition ( int x, int y ) = 0; + +private: + static cMediaToolkit* m_instance; + +protected: +// Audio *audio; +// Clock *clock; +// Video *video; +// bool eventLoopRunning; +// std::list keyboardListeners; +// std::list pointerButtonListeners; +// std::list pointerMotionListeners; +// std::list timerListeners; +// std::list loopListeners; +}; + + +#endif // CMEDIATOOLKIT_H diff --git a/cresourcearchive.cpp b/cresourcearchive.cpp new file mode 100644 index 0000000..b364fe6 --- /dev/null +++ b/cresourcearchive.cpp @@ -0,0 +1,26 @@ +#include "cexception.h" +#include "cresourcearchive.h" + + +cResourceArchive::cResourceArchive() + : cResourceFile() +{ +} + +cResourceArchive::~cResourceArchive() +{ +} + +void cResourceArchive::loadResource(cFileBuffer &buffer, const std::streamoff offset) +{ + try + { + seek(offset); + load(buffer); + } + catch (cException &e) + { + e.print("ResourceArchive::LoadResource"); + throw; + } +} diff --git a/cresourcearchive.h b/cresourcearchive.h new file mode 100644 index 0000000..d3583ac --- /dev/null +++ b/cresourcearchive.h @@ -0,0 +1,19 @@ +#ifndef CRESOURCEARCHIVE_H +#define CRESOURCEARCHIVE_H + + +#include "cresourcefile.h" + + +#define RES_FILENAME_LEN 13 + + +class cResourceArchive : public cResourceFile +{ +public: + cResourceArchive(); + virtual ~cResourceArchive(); + void loadResource(cFileBuffer& buffer, const std::streamoff offset); +}; + +#endif // CRESOURCEARCHIVE_H diff --git a/cresourcedata.h b/cresourcedata.h new file mode 100644 index 0000000..5d71476 --- /dev/null +++ b/cresourcedata.h @@ -0,0 +1,18 @@ +#ifndef CRESOURCEDATA_H +#define CRESOURCEDATA_H + + +#include "cfilebuffer.h" + +class cResourceData +{ + public: + cResourceData() {}; + virtual ~cResourceData() {}; + virtual void clear() = 0; + virtual void load(cFileBuffer *buffer ) = 0; + virtual unsigned int save(cFileBuffer *buffer ) = 0; +}; + + +#endif // CRESOURCEDATA_H diff --git a/cresourcefile.cpp b/cresourcefile.cpp new file mode 100644 index 0000000..2927b67 --- /dev/null +++ b/cresourcefile.cpp @@ -0,0 +1,32 @@ +#include "cdirectories.h" +#include "cexception.h" +#include "cresourcefile.h" + + +cResourceFile::cResourceFile() +{ +} + +cResourceFile::~cResourceFile() +{ +} + +QString cResourceFile::getDefaultPath() const +{ + return(cDirectories::getInstance()->getDataPath()); +} + +QString cResourceFile::getAlternatePath() const +{ + return(cDirectories::getInstance()->getSharedPath()); +} + +QString cResourceFile::getLastResortPath() const +{ + return(cDirectories::getInstance()->getResourcePath()); +} + +QString cResourceFile::getStoragePath() const +{ + return(cDirectories::getInstance()->getDataPath()); +} diff --git a/cresourcefile.h b/cresourcefile.h new file mode 100644 index 0000000..e50e5a9 --- /dev/null +++ b/cresourcefile.h @@ -0,0 +1,19 @@ +#ifndef CRESOURCEFILE_H +#define CRESOURCEFILE_H + + +#include "cbasicfile.h" + + +class cResourceFile : public cBasicFile +{ +public: + cResourceFile(); + virtual ~cResourceFile(); + QString getDefaultPath() const; + QString getAlternatePath() const; + QString getLastResortPath() const; + QString getStoragePath() const; +}; + +#endif // CRESOURCEFILE_H diff --git a/cresourceindex.cpp b/cresourceindex.cpp new file mode 100644 index 0000000..9065930 --- /dev/null +++ b/cresourceindex.cpp @@ -0,0 +1,159 @@ +#include "cexception.h" +#include "cresourcearchive.h" +#include "cresourceindex.h" + + +cResourceIndex::cResourceIndex() + : m_resourceFilename("") + , m_numResources(0) + , m_resIdxMap() + , m_resIdxIterator(m_resIdxMap.begin()) +{ +} + +cResourceIndex::~cResourceIndex() +{ + m_resIdxMap.clear(); +} + +void cResourceIndex::load(const QString& filename) +{ + try + { + cResourceFile rmf; + rmf.open(filename, false); + + cFileBuffer rmfBuffer(rmf.size()); + rmf.seek(0); + rmf.load(rmfBuffer); + rmf.close(); + + if((rmfBuffer.getUint32LE() != 1) || (rmfBuffer.getUint16LE() != 4)) + throw cDataCorruption(__FILE__, __LINE__); + + m_resourceFilename = QString::fromStdString(rmfBuffer.getString(RES_FILENAME_LEN)); + m_numResources = rmfBuffer.getUint16LE(); + + cResourceFile res; + res.open(m_resourceFilename, false); + + cFileBuffer resBuffer(RES_FILENAME_LEN + 4); + + for(unsigned int i = 0; i < m_numResources; i++) + { + unsigned int hashkey = rmfBuffer.getUint32LE(); + std::streamoff offset = rmfBuffer.getUint32LE(); + + res.seek(offset); + res.load(resBuffer); + + std::string resIdxName = resBuffer.getString(RES_FILENAME_LEN); + + cResourceIndexData resIdxData; + resIdxData.m_hashkey = hashkey; + resIdxData.m_offset = offset + RES_FILENAME_LEN + 4; + resIdxData.m_size = resBuffer.getUint32LE(); + m_resIdxMap.insert(std::pair(QString::fromStdString(resIdxName), resIdxData)); + } + res.close(); + } + catch (cException &e) + { + e.print("ResourceIndex::Load"); + throw; + } +} + +void cResourceIndex::save(const QString& filename) +{ + try + { + cFileBuffer rmfBuffer(4 + 2 + RES_FILENAME_LEN + 2 + m_numResources * (4 + 4)); + rmfBuffer.putUint32LE(1); + rmfBuffer.putUint16LE(4); + rmfBuffer.putString(m_resourceFilename.toStdString(), RES_FILENAME_LEN); + rmfBuffer.putUint16LE(m_numResources); + + cResourceFile res; + res.open(m_resourceFilename, false); + cFileBuffer resBuffer(RES_FILENAME_LEN + 4); + unsigned int offset = 0; + + for(unsigned int i = 0; i < m_numResources; i++) + { + res.seek(offset); + res.load(resBuffer); + std::string resIdxName = resBuffer.getString(RES_FILENAME_LEN); + cResourceIndexData resIdxData; + + find(QString::fromStdString(resIdxName), resIdxData); + rmfBuffer.putUint32LE(resIdxData.m_hashkey); + rmfBuffer.putUint32LE(offset); + + offset += RES_FILENAME_LEN + 4 + resIdxData.m_size; + } + res.close(); + + cResourceFile rmf; + rmf.open(filename, true); + rmf.save(rmfBuffer); + rmf.close(); + } + catch (cException &e) + { + e.print("ResourceIndex::Save"); + throw; + } +} + +QString cResourceIndex::getResourceFilename() const +{ + return(m_resourceFilename); +} + +unsigned int cResourceIndex::getNumResources() const +{ + return(m_numResources); +} + +bool cResourceIndex::find(const QString& name, cResourceIndexData &data) +{ + std::map::iterator it = m_resIdxMap.find(name); + + if(it != m_resIdxMap.end()) + { + data = it->second; + return(true); + } + return(false); +} + +bool cResourceIndex::getFirst(QString& name, cResourceIndexData &data) +{ + m_resIdxIterator = m_resIdxMap.begin(); + + if(m_resIdxIterator != m_resIdxMap.end()) + { + name = m_resIdxIterator->first; + data = m_resIdxIterator->second; + return(true); + } + return(false); +} + + +bool cResourceIndex::getNext(QString& name, cResourceIndexData &data) +{ + if(m_resIdxIterator == m_resIdxMap.end()) + return(false); + + m_resIdxIterator++; + + if(m_resIdxIterator != m_resIdxMap.end()) + { + name = m_resIdxIterator->first; + data = m_resIdxIterator->second; + return(true); + } + return(false); +} diff --git a/cresourceindex.h b/cresourceindex.h new file mode 100644 index 0000000..b964ddb --- /dev/null +++ b/cresourceindex.h @@ -0,0 +1,38 @@ +#ifndef CRESOURCEINDEX_H +#define CRESOURCEINDEX_H + + +#include +#include + +#include "cfilebuffer.h" + + +struct cResourceIndexData +{ + unsigned int m_hashkey; + std::streamoff m_offset; + unsigned int m_size; +}; + +class cResourceIndex +{ +public: + cResourceIndex(); + virtual ~cResourceIndex(); + void load(const QString& filename); + void save(const QString& filename); + QString getResourceFilename() const; + unsigned int getNumResources() const; + bool find(const QString& name, cResourceIndexData& data); + bool getFirst(QString& name, cResourceIndexData& data); + bool getNext(QString& name, cResourceIndexData& data); + +private: + QString m_resourceFilename; + unsigned int m_numResources; + std::map m_resIdxMap; + std::map::iterator m_resIdxIterator; +}; + +#endif // CRESOURCEINDEX_H diff --git a/csdl_toolkit.cpp b/csdl_toolkit.cpp new file mode 100644 index 0000000..3d041d0 --- /dev/null +++ b/csdl_toolkit.cpp @@ -0,0 +1,500 @@ +#include "cexception.h" +//#include "Null_Audio.h" +//#include "SDL_Audio.h" +//#include "SDL_Clock.h" +#include "csdl_toolkit.h" +//#include "SDL_Video.h" + + +#define GP2X_BUTTON_UP (0) +#define GP2X_BUTTON_UPLEFT (1) +#define GP2X_BUTTON_LEFT (2) +#define GP2X_BUTTON_DOWNLEFT (3) +#define GP2X_BUTTON_DOWN (4) +#define GP2X_BUTTON_DOWNRIGHT (5) +#define GP2X_BUTTON_RIGHT (6) +#define GP2X_BUTTON_UPRIGHT (7) +#define GP2X_BUTTON_START (8) +#define GP2X_BUTTON_SELECT (9) +#define GP2X_BUTTON_R (10) +#define GP2X_BUTTON_L (11) +#define GP2X_BUTTON_A (12) +#define GP2X_BUTTON_B (13) +#define GP2X_BUTTON_Y (14) +#define GP2X_BUTTON_X (15) +#define GP2X_BUTTON_VOLUP (16) +#define GP2X_BUTTON_VOLDOWN (17) +#define GP2X_BUTTON_CLICK (18) + +#define GP2X_AXIS_FACTOR (20000) +#define GP2X_SPEED (3) + +// for now assume GP2X mapping ... +const int JOYSTICK_BUTTON_UP = GP2X_BUTTON_UP; +const int JOYSTICK_BUTTON_UPLEFT = GP2X_BUTTON_UPLEFT; +const int JOYSTICK_BUTTON_LEFT = GP2X_BUTTON_LEFT; +const int JOYSTICK_BUTTON_DOWNLEFT = GP2X_BUTTON_DOWNLEFT; +const int JOYSTICK_BUTTON_DOWN = GP2X_BUTTON_DOWN; +const int JOYSTICK_BUTTON_DOWNRIGHT = GP2X_BUTTON_DOWNRIGHT; +const int JOYSTICK_BUTTON_RIGHT = GP2X_BUTTON_RIGHT; +const int JOYSTICK_BUTTON_UPRIGHT = GP2X_BUTTON_UPRIGHT; +const int JOYSTICK_BUTTON_PRIMARY = GP2X_BUTTON_R; +const int JOYSTICK_BUTTON_SECONDARY = GP2X_BUTTON_L; +const int JOYSTICK_BUTTON_TERTIARY = GP2X_BUTTON_CLICK; +const int JOYSTICK_AXIS_FACTOR = GP2X_AXIS_FACTOR; +const int JOYSTICK_SPEED = GP2X_SPEED; + + +cSDL_Toolkit::cSDL_Toolkit() + : cMediaToolkit() +// , xPos(0) +// , yPos(0) +// , xMove(0) +// , yMove(0) +// , joystick(0) +{ +// if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) +// { +// throw SDL_Exception(__FILE__, __LINE__, SDL_GetError()); +// } +//#if defined(HAVE_LIBSDL_MIXER) && defined(HAVE_LIBSDL_SOUND) +// audio = new SDL_Audio(); +//#else +// audio = new Null_Audio(); +//#endif +// clock = new SDL_Clock(); +// video = new SDL_Video(); + +// if (SDL_NumJoysticks() > 0) +// { +// joystick = SDL_JoystickOpen(0); +// if (!joystick) +// { +// throw SDL_Exception(__FILE__, __LINE__, SDL_GetError()); +// } +// } +} + +cSDL_Toolkit::~cSDL_Toolkit() +{ +// SDL_WM_GrabInput(SDL_GRAB_OFF); +// if (joystick) +// { +// SDL_JoystickClose(joystick); +// } +// delete audio; +// delete clock; +// delete video; +// SDL_Quit(); +} + +//void +//SDL_Toolkit::HandleEvent(SDL_Event *event) +//{ +// switch (event->type) +// { +// case SDL_KEYDOWN: +// { +// KeyboardEvent kbe((Key)event->key.keysym.sym); +// for (std::list::iterator it = keyboardListeners.begin(); it != keyboardListeners.end(); ++it) +// { +// (*it)->KeyPressed(kbe); +// } +// } +// break; +// case SDL_KEYUP: +// { +// KeyboardEvent kbe((Key)event->key.keysym.sym); +// for (std::list::iterator it = keyboardListeners.begin(); it != keyboardListeners.end(); ++it) +// { +// (*it)->KeyReleased(kbe); +// } +// } +// break; +// case SDL_MOUSEBUTTONDOWN: +// { +// PointerButton pb; +// switch (event->button.button) +// { +// case SDL_BUTTON_LEFT: +// pb = PB_PRIMARY; +// break; +// case SDL_BUTTON_MIDDLE: +// pb = PB_TERTIARY; +// break; +// case SDL_BUTTON_RIGHT: +// pb = PB_SECONDARY; +// break; +// default: +// return; +// } +// xPos = event->button.x / video->GetScaling(); +// yPos = event->button.y / video->GetScaling(); +// PointerButtonEvent pbe(pb, xPos, yPos); +// for (std::list::iterator it = pointerButtonListeners.begin(); it != pointerButtonListeners.end(); ++it) +// { +// (*it)->PointerButtonPressed(pbe); +// } +// } +// break; +// case SDL_MOUSEBUTTONUP: +// { +// PointerButton pb; +// switch (event->button.button) +// { +// case SDL_BUTTON_LEFT: +// pb = PB_PRIMARY; +// break; +// case SDL_BUTTON_MIDDLE: +// pb = PB_TERTIARY; +// break; +// case SDL_BUTTON_RIGHT: +// pb = PB_SECONDARY; +// break; +// default: +// return; +// } +// xPos = event->button.x / video->GetScaling(); +// yPos = event->button.y / video->GetScaling(); +// PointerButtonEvent pbe(pb, xPos, yPos); +// for (std::list::iterator it = pointerButtonListeners.begin(); it != pointerButtonListeners.end(); ++it) +// { +// (*it)->PointerButtonReleased(pbe); +// } +// } +// break; +// case SDL_MOUSEMOTION: +// { +// xPos = event->button.x / video->GetScaling(); +// yPos = event->button.y / video->GetScaling(); +// PointerMotionEvent pme(xPos, yPos); +// for (std::list::iterator it = pointerMotionListeners.begin(); it != pointerMotionListeners.end(); ++it) +// { +// (*it)->PointerMoved(pme); +// } +// } +// break; +// case SDL_JOYAXISMOTION: +// if (event->jaxis.which == 0) +// { +// if (event->jaxis.axis == 0) +// { +// xMove = event->jaxis.value / JOYSTICK_AXIS_FACTOR; +// } +// else if (event->jaxis.axis == 1) +// { +// yMove = event->jaxis.value / JOYSTICK_AXIS_FACTOR; +// } +// } +// break; +// case SDL_JOYBUTTONDOWN: +// if (event->jbutton.which == 0) +// { +// switch (event->jbutton.button) +// { +// case JOYSTICK_BUTTON_UP: +// jsState = JS_UP; +// yMove = -1; +// break; +// case JOYSTICK_BUTTON_UPLEFT: +// jsState = JS_UP_LEFT; +// xMove = -1; +// yMove = -1; +// break; +// case JOYSTICK_BUTTON_LEFT: +// jsState = JS_LEFT; +// xMove = -1; +// break; +// case JOYSTICK_BUTTON_DOWNLEFT: +// jsState = JS_DOWN_LEFT; +// xMove = -1; +// yMove = 1; +// break; +// case JOYSTICK_BUTTON_DOWN: +// jsState = JS_DOWN; +// yMove = 1; +// break; +// case JOYSTICK_BUTTON_DOWNRIGHT: +// jsState = JS_DOWN_RIGHT; +// xMove = 1; +// yMove = 1; +// break; +// case JOYSTICK_BUTTON_RIGHT: +// jsState = JS_RIGHT; +// xMove = 1; +// break; +// case JOYSTICK_BUTTON_UPRIGHT: +// jsState = JS_UP_RIGHT; +// xMove = 1; +// yMove = -1; +// break; +// case JOYSTICK_BUTTON_PRIMARY: +// { +// PointerButtonEvent pbe(PB_PRIMARY, xPos, yPos); +// for (std::list::iterator it = pointerButtonListeners.begin(); it != pointerButtonListeners.end(); ++it) +// { +// (*it)->PointerButtonPressed(pbe); +// } +// } +// break; +// case JOYSTICK_BUTTON_SECONDARY: +// { +// PointerButtonEvent pbe(PB_SECONDARY, xPos, yPos); +// for (std::list::iterator it = pointerButtonListeners.begin(); it != pointerButtonListeners.end(); ++it) +// { +// (*it)->PointerButtonPressed(pbe); +// } +// } +// break; +// case JOYSTICK_BUTTON_TERTIARY: +// { +// PointerButtonEvent pbe(PB_TERTIARY, xPos, yPos); +// for (std::list::iterator it = pointerButtonListeners.begin(); it != pointerButtonListeners.end(); ++it) +// { +// (*it)->PointerButtonPressed(pbe); +// } +// } +// break; +// default: +// break; +// } +// } +// break; +// case SDL_JOYBUTTONUP: +// if (event->jbutton.which == 0) +// { +// switch (event->jbutton.button) +// { +// case JOYSTICK_BUTTON_UP: +// if (jsState == JS_UP) +// { +// jsState = JS_CENTER; +// xMove = 0; +// yMove = 0; +// } +// break; +// case JOYSTICK_BUTTON_UPLEFT: +// if (jsState == JS_UP_LEFT) +// { +// jsState = JS_CENTER; +// xMove = 0; +// yMove = 0; +// } +// break; +// case JOYSTICK_BUTTON_LEFT: +// if (jsState == JS_LEFT) +// { +// jsState = JS_CENTER; +// xMove = 0; +// yMove = 0; +// } +// break; +// case JOYSTICK_BUTTON_DOWNLEFT: +// if (jsState == JS_DOWN_LEFT) +// { +// jsState = JS_CENTER; +// xMove = 0; +// yMove = 0; +// } +// break; +// case JOYSTICK_BUTTON_DOWN: +// if (jsState == JS_DOWN) +// { +// jsState = JS_CENTER; +// xMove = 0; +// yMove = 0; +// } +// break; +// case JOYSTICK_BUTTON_DOWNRIGHT: +// if (jsState == JS_DOWN_RIGHT) +// { +// jsState = JS_CENTER; +// xMove = 0; +// yMove = 0; +// } +// break; +// case JOYSTICK_BUTTON_RIGHT: +// if (jsState == JS_RIGHT) +// { +// jsState = JS_CENTER; +// xMove = 0; +// yMove = 0; +// } +// break; +// case JOYSTICK_BUTTON_UPRIGHT: +// if (jsState == JS_UP_RIGHT) +// { +// jsState = JS_CENTER; +// xMove = 0; +// yMove = 0; +// } +// break; +// case JOYSTICK_BUTTON_PRIMARY: +// { +// PointerButtonEvent pbe(PB_PRIMARY, xPos, yPos); +// for (std::list::iterator it = pointerButtonListeners.begin(); it != pointerButtonListeners.end(); ++it) +// { +// (*it)->PointerButtonReleased(pbe); +// } +// } +// break; +// case JOYSTICK_BUTTON_SECONDARY: +// { +// PointerButtonEvent pbe(PB_SECONDARY, xPos, yPos); +// for (std::list::iterator it = pointerButtonListeners.begin(); it != pointerButtonListeners.end(); ++it) +// { +// (*it)->PointerButtonReleased(pbe); +// } +// } +// break; +// case JOYSTICK_BUTTON_TERTIARY: +// { +// PointerButtonEvent pbe(PB_TERTIARY, xPos, yPos); +// for (std::list::iterator it = pointerButtonListeners.begin(); it != pointerButtonListeners.end(); ++it) +// { +// (*it)->PointerButtonReleased(pbe); +// } +// } +// break; +// default: +// break; +// } +// } +// break; +// case SDL_USEREVENT: +// { +// // timer event +// clock->CancelTimer((unsigned long)event->user.data1); +// TimerEvent te((unsigned long)event->user.data1); +// for (std::list::iterator it = timerListeners.begin(); it != timerListeners.end(); ++it) +// { +// (*it)->TimerExpired(te); +// } +// } +// break; +// default: +// break; +// } +//} + +//void +//SDL_Toolkit::UpdatePointer() +//{ +// if (xMove) +// { +// xPos = xPos + xMove * JOYSTICK_SPEED; +// if (xPos < 0) +// { +// xPos = 0; +// } +// else if (xPos > video->GetWidth()) +// { +// xPos = video->GetWidth(); +// } +// } +// if (yMove) +// { +// yPos = yPos + yMove * JOYSTICK_SPEED; +// if (yPos < 0) +// { +// yPos = 0; +// } +// else if (yPos > video->GetHeight()) +// { +// yPos = video->GetHeight(); +// } +// } +// if (xMove || yMove) +// { +// PointerMotionEvent pme(xPos, yPos); +// for (std::list::iterator it = pointerMotionListeners.begin(); it != pointerMotionListeners.end(); ++it) +// { +// (*it)->PointerMoved(pme); +// } +// } +//} + +//void +//SDL_Toolkit::PollEvents() +//{ +// SDL_Event event; +// while (SDL_PollEvent(&event)) +// { +// HandleEvent(&event); +// } +// UpdatePointer(); +//} + +//void +//SDL_Toolkit::PollEventLoop() +//{ +// int currentTicks; +// int previousTicks = SDL_GetTicks(); + +// eventLoopRunning = true; +// while (eventLoopRunning) +// { +// PollEvents(); +// currentTicks = SDL_GetTicks(); +// LoopEvent le(currentTicks - previousTicks); +// for (std::list::iterator it = loopListeners.begin(); it != loopListeners.end(); ++it) +// { +// (*it)->LoopComplete(le); +// } +// previousTicks = currentTicks; +// } +//} + +//void +//SDL_Toolkit::WaitEvents() +//{ +// SDL_Event event; +// if (SDL_WaitEvent(&event)) +// { +// HandleEvent(&event); +// } +// UpdatePointer(); +//} + +//void +//SDL_Toolkit::WaitEventLoop() +//{ +// int currentTicks; +// int previousTicks = SDL_GetTicks(); + +// eventLoopRunning = true; +// while (eventLoopRunning) +// { +// WaitEvents(); +// currentTicks = SDL_GetTicks(); +// LoopEvent le(currentTicks - previousTicks); +// for (std::list::iterator it = loopListeners.begin(); it != loopListeners.end(); ++it) +// { +// (*it)->LoopComplete(le); +// } +// previousTicks = currentTicks; +// } +//} + +//void +//SDL_Toolkit::ClearEvents() +//{ +// SDL_Event event; +// while (SDL_PollEvent(&event)) +// { +// // nothing +// } +//} + +//void +//SDL_Toolkit::GetPointerPosition(int *x, int *y) +//{ +// SDL_GetMouseState(x, y); +//} + +//void +//SDL_Toolkit::SetPointerPosition(int x, int y) +//{ +// int scaling = video->GetScaling(); +// SDL_WarpMouse(x * scaling, y * scaling); +//} diff --git a/csdl_toolkit.h b/csdl_toolkit.h new file mode 100644 index 0000000..01b9e0c --- /dev/null +++ b/csdl_toolkit.h @@ -0,0 +1,43 @@ +#ifndef CSDL_TOOLKIT_H +#define CSDL_TOOLKIT_H + + +#include "cmediatoolkit.h" +//#include "SDL.h" + + +class cSDL_Toolkit : public cMediaToolkit +{ + enum JoystickState { JS_CENTER, + JS_UP, + JS_UP_LEFT, + JS_LEFT, + JS_DOWN_LEFT, + JS_DOWN, + JS_DOWN_RIGHT, + JS_RIGHT, + JS_UP_RIGHT }; + +public: + cSDL_Toolkit(); + ~cSDL_Toolkit(); +// void PollEvents(); +// void PollEventLoop(); +// void WaitEvents(); +// void WaitEventLoop(); +// void ClearEvents(); +// void GetPointerPosition ( int *x, int *y ); +// void SetPointerPosition ( int x, int y ); + +private: +// int xPos; +// int yPos; +// int xMove; +// int yMove; +// enum JoystickState jsState; +// SDL_Joystick *joystick; +// void HandleEvent ( SDL_Event *event ); +// void UpdatePointer(); +}; + +#endif // CSDL_TOOLKIT_H diff --git a/ctaggedresource.cpp b/ctaggedresource.cpp new file mode 100644 index 0000000..3a4e77f --- /dev/null +++ b/ctaggedresource.cpp @@ -0,0 +1,92 @@ +#include "cexception.h" +#include "ctaggedresource.h" + + +cTaggedResource::cTaggedResource() +{ +} + +cTaggedResource::~cTaggedResource() +{ + clearTags(); +} + +void cTaggedResource::clearTags() +{ + for(std::map::iterator it = m_bufferMap.begin(); it != m_bufferMap.end(); ++it) + delete it->second; + + m_bufferMap.clear(); +} + +void cTaggedResource::split(cFileBuffer *buffer) +{ + while(!buffer->atEnd()) + { + unsigned int label = buffer->getUint32LE(); + switch (label) + { + case TAG_ADS: + case TAG_APP: + case TAG_BIN: + case TAG_BMP: + case TAG_DAT: + case TAG_FNT: + case TAG_GID: + case TAG_INF: + case TAG_MAP: + case TAG_PAG: + case TAG_PAL: + case TAG_RES: + case TAG_SCR: + case TAG_SND: + case TAG_TAG: + case TAG_TT3: + case TAG_TTI: + case TAG_VER: + case TAG_VGA: + { + unsigned int size = buffer->getUint32LE(); + std::map::iterator it = m_bufferMap.find(label); + + if(it != m_bufferMap.end()) + { + delete it->second; + m_bufferMap.erase(it); + } + + if(size & 0x80000000) + { + cFileBuffer *lblbuf = new cFileBuffer(size & 0x7fffffff); + lblbuf->fill(buffer); + m_bufferMap.insert(std::pair(label, 0)); + split(lblbuf); + delete lblbuf; + } + else + { + cFileBuffer *lblbuf = new cFileBuffer(size); + lblbuf->fill(buffer); + m_bufferMap.insert(std::pair(label, lblbuf)); + } + } + break; + default: + throw cUnexpectedValue(__FILE__, __LINE__, label); + break; + } + } +} + +bool cTaggedResource::find(const unsigned int label, cFileBuffer* &buffer) +{ + try + { + buffer = m_bufferMap[label]; + } + catch (...) + { + return(false); + } + return(buffer != 0); +} diff --git a/ctaggedresource.h b/ctaggedresource.h new file mode 100644 index 0000000..aa5b15c --- /dev/null +++ b/ctaggedresource.h @@ -0,0 +1,45 @@ +#ifndef CTAGGEDRESOURCE_H +#define CTAGGEDRESOURCE_H + + +#include + +#include "cresourcedata.h" + + +const uint32_t TAG_ADS = 0x3a534441; +const uint32_t TAG_APP = 0x3a505041; +const uint32_t TAG_BIN = 0x3a4e4942; +const uint32_t TAG_BMP = 0x3a504d42; +const uint32_t TAG_DAT = 0x3a544144; +const uint32_t TAG_FNT = 0x3a544e46; +const uint32_t TAG_GID = 0x3a444947; +const uint32_t TAG_INF = 0x3a464e49; +const uint32_t TAG_MAP = 0x3a50414d; +const uint32_t TAG_PAG = 0x3a474150; +const uint32_t TAG_PAL = 0x3a4c4150; +const uint32_t TAG_RES = 0x3a534552; +const uint32_t TAG_SCR = 0x3a524353; +const uint32_t TAG_SND = 0x3a444e53; +const uint32_t TAG_TAG = 0x3a474154; +const uint32_t TAG_TT3 = 0x3a335454; +const uint32_t TAG_TTI = 0x3a495454; +const uint32_t TAG_VER = 0x3a524556; +const uint32_t TAG_VGA = 0x3a414756; + + +class cTaggedResource : public cResourceData +{ +public: + cTaggedResource(); + virtual ~cTaggedResource(); + void clearTags(); + void split(cFileBuffer *buffer); + bool find(const unsigned label, cFileBuffer* &buffer); + +private: + std::map m_bufferMap; +}; + + +#endif // CTAGGEDRESOURCE_H diff --git a/defines.h b/defines.h new file mode 100644 index 0000000..9578e48 --- /dev/null +++ b/defines.h @@ -0,0 +1,143 @@ +#ifndef DEFINES_H +#define DEFINES_H + + +typedef uint16_t Uint16; +typedef uint32_t Uint32; + + +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MAX(a,b) (((a)>(b))?(a):(b)) + + +#if defined(__GNUC__) && defined(__i386__) && \ + !(__GNUC__ == 2 && __GNUC_MINOR__ <= 95 /* broken gcc version */) +static __inline__ Uint16 SDL_Swap16(Uint16 x) +{ + __asm__("xchgb %b0,%h0" : "=q" (x) : "0" (x)); + return x; +} +#elif defined(__GNUC__) && defined(__x86_64__) +static __inline__ Uint16 SDL_Swap16(Uint16 x) +{ + __asm__("xchgb %b0,%h0" : "=Q" (x) : "0" (x)); + return x; +} +#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) +static __inline__ Uint16 SDL_Swap16(Uint16 x) +{ + int result; + + __asm__("rlwimi %0,%2,8,16,23" : "=&r" (result) : "0" (x >> 8), "r" (x)); + return (Uint16)result; +} +#elif defined(__GNUC__) && (defined(__m68k__) && !defined(__mcoldfire__)) +static __inline__ Uint16 SDL_Swap16(Uint16 x) +{ + __asm__("rorw #8,%0" : "=d" (x) : "0" (x) : "cc"); + return x; +} +#else +static __inline__ Uint16 SDL_Swap16(Uint16 x) { + return SDL_static_cast(Uint16, ((x<<8)|(x>>8))); +} +#endif + +#if defined(__GNUC__) && defined(__i386__) && \ + !(__GNUC__ == 2 && __GNUC_MINOR__ <= 95 /* broken gcc version */) +static __inline__ Uint32 SDL_Swap32(Uint32 x) +{ + __asm__("bswap %0" : "=r" (x) : "0" (x)); + return x; +} +#elif defined(__GNUC__) && defined(__x86_64__) +static __inline__ Uint32 SDL_Swap32(Uint32 x) +{ + __asm__("bswapl %0" : "=r" (x) : "0" (x)); + return x; +} +#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) +static __inline__ Uint32 SDL_Swap32(Uint32 x) +{ + Uint32 result; + + __asm__("rlwimi %0,%2,24,16,23" : "=&r" (result) : "0" (x>>24), "r" (x)); + __asm__("rlwimi %0,%2,8,8,15" : "=&r" (result) : "0" (result), "r" (x)); + __asm__("rlwimi %0,%2,24,0,7" : "=&r" (result) : "0" (result), "r" (x)); + return result; +} +#elif defined(__GNUC__) && (defined(__m68k__) && !defined(__mcoldfire__)) +static __inline__ Uint32 SDL_Swap32(Uint32 x) +{ + __asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0" : "=d" (x) : "0" (x) : "cc"); + return x; +} +#else +static __inline__ Uint32 SDL_Swap32(Uint32 x) { + return SDL_static_cast(Uint32, ((x<<24)|((x<<8)&0x00FF0000)|((x>>8)&0x0000FF00)|(x>>24))); +} +#endif + +#ifdef SDL_HAS_64BIT_TYPE +#if defined(__GNUC__) && defined(__i386__) && \ + !(__GNUC__ == 2 && __GNUC_MINOR__ <= 95 /* broken gcc version */) +static __inline__ Uint64 SDL_Swap64(Uint64 x) +{ + union { + struct { Uint32 a,b; } s; + Uint64 u; + } v; + v.u = x; + __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1" + : "=r" (v.s.a), "=r" (v.s.b) + : "0" (v.s.a), "1" (v.s.b)); + return v.u; +} +#elif defined(__GNUC__) && defined(__x86_64__) +static __inline__ Uint64 SDL_Swap64(Uint64 x) +{ + __asm__("bswapq %0" : "=r" (x) : "0" (x)); + return x; +} +#else +static __inline__ Uint64 SDL_Swap64(Uint64 x) +{ + Uint32 hi, lo; + + /* Separate into high and low 32-bit values and swap them */ + lo = SDL_static_cast(Uint32, x & 0xFFFFFFFF); + x >>= 32; + hi = SDL_static_cast(Uint32, x & 0xFFFFFFFF); + x = SDL_Swap32(lo); + x <<= 32; + x |= SDL_Swap32(hi); + return (x); +} +#endif +#else +/* This is mainly to keep compilers from complaining in SDL code. + * If there is no real 64-bit datatype, then compilers will complain about + * the fake 64-bit datatype that SDL provides when it compiles user code. + */ +#define SDL_Swap64(X) (X) +#endif /* SDL_HAS_64BIT_TYPE */ +/*@}*/ + +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define SDL_SwapLE16(X) (X) +#define SDL_SwapLE32(X) (X) +#define SDL_SwapLE64(X) (X) +#define SDL_SwapBE16(X) SDL_Swap16(X) +#define SDL_SwapBE32(X) SDL_Swap32(X) +#define SDL_SwapBE64(X) SDL_Swap64(X) +#else +#define SDL_SwapLE16(X) SDL_Swap16(X) +#define SDL_SwapLE32(X) SDL_Swap32(X) +#define SDL_SwapLE64(X) SDL_Swap64(X) +#define SDL_SwapBE16(X) (X) +#define SDL_SwapBE32(X) (X) +#define SDL_SwapBE64(X) (X) +#endif + + +#endif // DEFINES_H diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..025da0a --- /dev/null +++ b/main.cpp @@ -0,0 +1,11 @@ +#include "cmainwindow.h" + +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + cMainWindow w; + w.show(); + return a.exec(); +} diff --git a/xBAK.pro b/xBAK.pro new file mode 100644 index 0000000..53c9f7c --- /dev/null +++ b/xBAK.pro @@ -0,0 +1,64 @@ +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + cbasicfile.cpp \ + cconfigfile.cpp \ + cdirectories.cpp \ + cexception.cpp \ + cfilebuffer.cpp \ + cfilemanager.cpp \ + cfont.cpp \ + cfontresource.cpp \ + cgameapplication.cpp \ + cmediatoolkit.cpp \ + cresourcearchive.cpp \ + cresourcefile.cpp \ + cresourceindex.cpp \ + csdl_toolkit.cpp \ + ctaggedresource.cpp \ + main.cpp \ + cmainwindow.cpp + +HEADERS += \ + cbasicfile.h \ + cconfigdata.h \ + cconfigfile.h \ + cdirectories.h \ + cexception.h \ + cfilebuffer.h \ + cfilemanager.h \ + cfont.h \ + cfontresource.h \ + cgameapplication.h \ + cmainwindow.h \ + cmediatoolkit.h \ + cresourcearchive.h \ + cresourcedata.h \ + cresourcefile.h \ + cresourceindex.h \ + csdl_toolkit.h \ + ctaggedresource.h \ + defines.h + +FORMS += \ + cmainwindow.ui + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target