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