From b7b4df52f3081c75a849ab0f7e7943503cc840d1 Mon Sep 17 00:00:00 2001 From: Antidote Date: Sun, 21 Jul 2013 20:06:54 -0700 Subject: [PATCH] * Fixed compression code, old code was unreliable and failed at random (don't use zlib's compress function) * More refactory work, ready for merge --- include/ALTTPEnums.hpp | 4 + include/ALTTPFileReader.hpp | 6 +- include/ALTTPFileWriter.hpp | 2 +- include/BinaryReader.hpp | 2 + include/BinaryWriter.hpp | 7 ++ include/Compression.hpp | 2 +- include/MCFileReader.hpp | 2 +- include/MCFileWriter.hpp | 6 +- include/Stream.hpp | 8 +- include/Types.hpp | 5 + include/WiiSaveReader.hpp | 9 +- include/WiiSaveWriter.hpp | 3 +- include/{ZQuest.hpp => ZQuestFile.hpp} | 78 ++++++------- include/ZQuestFileReader.hpp | 8 +- include/ZQuestFileWriter.hpp | 6 +- include/md5.h | 2 +- include/utility.hpp | 22 +++- libzelda.pro | 8 +- src/BinaryReader.cpp | 32 ++--- src/BinaryWriter.cpp | 42 ++++--- src/Compression.cpp | 60 ++++++++-- src/MCFileWriter.cpp | 3 + src/TextStream.cpp | 4 +- src/WiiImage.cpp | 2 +- src/WiiSave.cpp | 1 - src/WiiSaveReader.cpp | 2 +- src/WiiSaveWriter.cpp | 10 +- src/{ZQuest.cpp => ZQuestFile.cpp} | 43 ++++--- src/ZQuestFileReader.cpp | 14 +-- src/ZQuestFileWriter.cpp | 28 +++-- src/aes.c | 130 ++++++++++----------- src/ec.cpp | 16 +-- src/sha1.cpp | 4 +- src/utility.cpp | 155 +++++++++++++------------ 34 files changed, 408 insertions(+), 318 deletions(-) rename include/{ZQuest.hpp => ZQuestFile.hpp} (58%) rename src/{ZQuest.cpp => ZQuestFile.cpp} (73%) diff --git a/include/ALTTPEnums.hpp b/include/ALTTPEnums.hpp index 85a13d7..8b2344e 100644 --- a/include/ALTTPEnums.hpp +++ b/include/ALTTPEnums.hpp @@ -20,6 +20,9 @@ #include "Types.hpp" +namespace zelda +{ + enum BowType : char { BowNone, @@ -105,5 +108,6 @@ enum ALTTPTagAlong AfterBoss }; +} // zelda #endif // __DOXYGEN_IGNORE__ #endif // __ALTTP_ENUMS_HPP__ diff --git a/include/ALTTPFileReader.hpp b/include/ALTTPFileReader.hpp index 3fd1e55..d5d4774 100644 --- a/include/ALTTPFileReader.hpp +++ b/include/ALTTPFileReader.hpp @@ -24,9 +24,9 @@ namespace zelda { class ALTTPFile; + namespace io { - /*! \class ALTTPFileReader * \brief A Link to the Past save data reader class * @@ -34,10 +34,10 @@ namespace io * all work is done using a memory buffer, and not read directly from the disk. * \sa BinaryReader */ - -class ALTTPFileReader : public io::BinaryReader +class ALTTPFileReader : protected BinaryReader { BINARYREADER_BASE + public: /*! \brief This constructor takes an existing buffer to read from. * diff --git a/include/ALTTPFileWriter.hpp b/include/ALTTPFileWriter.hpp index 647d0fa..825e95e 100644 --- a/include/ALTTPFileWriter.hpp +++ b/include/ALTTPFileWriter.hpp @@ -34,7 +34,7 @@ namespace io * all work is done using a memory buffer, and not written directly to the disk. * \sa BinaryReader */ -class ALTTPFileWriter : public io::BinaryWriter +class ALTTPFileWriter : protected BinaryWriter { BINARYWRITER_BASE diff --git a/include/BinaryReader.hpp b/include/BinaryReader.hpp index 6b09e3e..a48ff49 100644 --- a/include/BinaryReader.hpp +++ b/include/BinaryReader.hpp @@ -23,6 +23,7 @@ namespace zelda { namespace io { + /*! \class BinaryReader * \brief A Stream class for reading binary data * @@ -177,4 +178,5 @@ protected: private: \ typedef zelda::io::BinaryReader base; #endif // BINARYREADER_BASE + #endif // __BINARYREADER_HPP__ diff --git a/include/BinaryWriter.hpp b/include/BinaryWriter.hpp index 2bc3ba0..8531a32 100644 --- a/include/BinaryWriter.hpp +++ b/include/BinaryWriter.hpp @@ -138,6 +138,13 @@ public: * \param str The string to write to the buffer */ void writeUnicode(const std::string& str); + + /*! \brief Writes an string to the buffer and advances the buffer. + * + * \sa Endian + * \param str The string to write to the buffer + */ + void writeString(const std::string& str); protected: Int8 readByte(); Int8* readBytes(Int64); diff --git a/include/Compression.hpp b/include/Compression.hpp index 1e39ce6..c8112cf 100644 --- a/include/Compression.hpp +++ b/include/Compression.hpp @@ -25,7 +25,7 @@ namespace io namespace Compression { Int32 decompressZlib(Uint8* src, Uint32 srcLen, Uint8* dst, Uint32 dstLen); - void compressZlib(const Uint8* src, Uint32 srcLen, Uint8* dst, Uint32* dstLen); + Int32 compressZlib(const Uint8* src, Uint32 srcLen, Uint8* dst, Uint32 dstLen); } } } diff --git a/include/MCFileReader.hpp b/include/MCFileReader.hpp index 9ed8e22..84fdab4 100644 --- a/include/MCFileReader.hpp +++ b/include/MCFileReader.hpp @@ -34,7 +34,7 @@ namespace io * all work is done using a memory buffer, and not read directly from the disk. * \sa BinaryReader */ -class MCFileReader : public io::BinaryReader +class MCFileReader : protected BinaryReader { BINARYREADER_BASE public: diff --git a/include/MCFileWriter.hpp b/include/MCFileWriter.hpp index 06d3f58..4750072 100644 --- a/include/MCFileWriter.hpp +++ b/include/MCFileWriter.hpp @@ -24,6 +24,9 @@ namespace zelda class MCFile; +namespace io +{ + /*! \class MCFileWriter * \brief The Minish Cap Save save data writer class * @@ -31,7 +34,7 @@ class MCFile; * all work is done using a memory buffer, and not written directly from the disk. * \sa BinaryWriter */ -class MCFileWriter : public io::BinaryWriter +class MCFileWriter : protected BinaryWriter { BINARYWRITER_BASE public: @@ -64,6 +67,7 @@ private: void unscramble(); }; +} // io } // zelda #endif // __MCFILEWRITER_HPP__ diff --git a/include/Stream.hpp b/include/Stream.hpp index de05754..4ccd9c6 100644 --- a/include/Stream.hpp +++ b/include/Stream.hpp @@ -80,16 +80,16 @@ public: * \throw IOException */ virtual void writeBit(bool val); + /*! \brief Writes a byte at the current position and advances the position by one byte. * \param byte The value to write * \throw IOException */ virtual void writeUByte(Uint8 byte); - /*! \brief Writes a byte at the current position and advances the position by one byte. - * \param byte The value to write - * \throw IOException - */ + * \param byte The value to write + * \throw IOException + */ virtual void writeByte(Int8 byte); /*! \brief Writes the given buffer with the specified length, buffers can be bigger than the length diff --git a/include/Types.hpp b/include/Types.hpp index 9ad0597..538c2bc 100644 --- a/include/Types.hpp +++ b/include/Types.hpp @@ -17,6 +17,9 @@ #include +#ifdef __cplusplus +namespace zelda +{ /*! \enum Endian * \brief Allows the user to specify the Endianness of data.
* The proper actions are automatically taken depending on platform and @@ -27,6 +30,8 @@ enum Endian LittleEndian, //!< Specifies that the Stream is Little Endian (LSB) BigEndian //!< Specifies that the Stream is Big Endian (MSB) }; +} // zelda +#endif // 8 bits integer types #if UCHAR_MAX == 0xFF diff --git a/include/WiiSaveReader.hpp b/include/WiiSaveReader.hpp index c899e0a..a926140 100644 --- a/include/WiiSaveReader.hpp +++ b/include/WiiSaveReader.hpp @@ -12,12 +12,13 @@ // // You should have received a copy of the GNU General Public License // along with libZelda. If not, see + #ifndef __WII_SAVE_READER_HPP__ #define __WII_SAVE_READER_HPP__ -#include -#include -#include +#include "Types.hpp" +#include "utility.hpp" +#include "BinaryReader.hpp" namespace zelda { @@ -36,7 +37,7 @@ namespace io * all work is done using a memory buffer, and not read directly from the disk. * \sa BinaryReader */ -class WiiSaveReader : public io::BinaryReader +class WiiSaveReader : protected BinaryReader { BINARYREADER_BASE public: diff --git a/include/WiiSaveWriter.hpp b/include/WiiSaveWriter.hpp index 54b6dd3..de6e880 100644 --- a/include/WiiSaveWriter.hpp +++ b/include/WiiSaveWriter.hpp @@ -22,7 +22,6 @@ namespace zelda { - class WiiSave; class WiiBanner; class WiiFile; @@ -38,7 +37,7 @@ namespace io * all work is done using a memory buffer, and not written directly to the disk. * \sa BinaryReader */ -class WiiSaveWriter : public io::BinaryWriter +class WiiSaveWriter : protected BinaryWriter { BINARYWRITER_BASE public: diff --git a/include/ZQuest.hpp b/include/ZQuestFile.hpp similarity index 58% rename from include/ZQuest.hpp rename to include/ZQuestFile.hpp index 4f31e87..76608a4 100644 --- a/include/ZQuest.hpp +++ b/include/ZQuestFile.hpp @@ -16,7 +16,7 @@ #ifndef ZQUEST_HPP #define ZQUEST_HPP -#include +#include "Types.hpp" #include #include @@ -25,65 +25,70 @@ namespace zelda /*! * \brief The ZQuest class */ -class ZQuest +class ZQuestFile { public: /*! - * \brief Major + * \brief The current major version of the ZQuest format */ static const Uint32 Major; /*! - * \brief Minor + * \brief The current minor version of the ZQuest format */ static const Uint32 Minor; /*! - * \brief Revision + * \brief The current revision of the ZQuest format */ static const Uint32 Revision; /*! - * \brief Build + * \brief The current build of the ZQuest format */ static const Uint32 Build; /*! - * \brief Version + * \brief The current version of the ZQuest format */ static const Uint32 Version; /*! - * \brief Magic + * \brief The magic number used to identify the file e.g. "ZQS1" */ static const Uint32 Magic; /*! - * \brief The Game enum + * \enum Game + * \brief The list of games currently supported by ZQuest */ enum Game { - NoGame, - LegendofZelda, - AdventureOfLink, - ALinkToThePast, - LinksAwakening, - OcarinaOfTime, - OcarinaOfTime3D, - MajorasMask, - OracleOfSeasons, - OracleOfAges, - FourSwords, - WindWaker, - FourSwordsAdventures, - MinishCap, - TwilightPrincess, - PhantomHourglass, - SpiritTracks, - SkywardSword, - ALinkBetweenWorlds // Not released + NoGame, //!< None or Unsupported + LoZ, //!< Legend of Zelda + AoL, //!< Adventure of Link + ALttP, //!< A Link to the Past + LA, //!< Links Awakening + OoT, //!< Ocarin of Time + OoT3D, //!< Ocarina of Time 3D + MM, //!< Majora's Mask + OoS, //!< Oracle of Season + OoA, //!< Oracle of Ages + FS, //!< Four Swords + WW, //!< Wind Waker + FSA, //!< Four Swords Adventures + MC, //!< Minish Cap + TP, //!< Twilight Princess + PH, //!< Phantom Hourglass + ST, //!< Spirit Tracks + SS, //!< Skyward Sword + ALBW, //!< A Link Between Worlds + // Add more games here + + // This must always be last + GameCount //!< Total number of supported games }; /*! * \brief ZQuest */ - ZQuest(); + ZQuestFile(); /*! * \brief ZQuest @@ -92,8 +97,8 @@ public: * \param data * \param length */ - ZQuest(Game game, Endian endian, Uint8* data, Uint32 length); - ~ZQuest(); + ZQuestFile(Game game, Endian endian, Uint8* data, Uint32 length); + ~ZQuestFile(); /*! * \brief setGame @@ -121,9 +126,10 @@ public: /*! * \brief setData - * \param data + * \param data The data to assign + * \param length The length of the data */ - void setData(Uint8* data); + void setData(Uint8* data, Uint32 length); /*! * \brief data @@ -131,12 +137,6 @@ public: */ Uint8* data() const; - /*! - * \brief setLength - * \param length - */ - void setLength(Uint32 length); - /*! * \brief length * \return diff --git a/include/ZQuestFileReader.hpp b/include/ZQuestFileReader.hpp index 351452e..48335f9 100644 --- a/include/ZQuestFileReader.hpp +++ b/include/ZQuestFileReader.hpp @@ -20,16 +20,18 @@ namespace zelda { -class ZQuest; +class ZQuestFile; + namespace io { /*! * \brief The ZQuestFileReader class */ -class ZQuestFileReader : public io::BinaryReader +class ZQuestFileReader : protected BinaryReader { BINARYREADER_BASE + public: /*! * \brief ZQuestFileReader @@ -48,7 +50,7 @@ public: * \brief read * \return */ - ZQuest* read(); + ZQuestFile* read(); }; } // io diff --git a/include/ZQuestFileWriter.hpp b/include/ZQuestFileWriter.hpp index 193f012..291b877 100644 --- a/include/ZQuestFileWriter.hpp +++ b/include/ZQuestFileWriter.hpp @@ -20,7 +20,7 @@ namespace zelda { -class ZQuest; +class ZQuestFile; namespace io { @@ -28,7 +28,7 @@ namespace io /*! * \brief The ZQuestFileWriter class */ -class ZQuestFileWriter : public io::BinaryWriter +class ZQuestFileWriter : protected BinaryWriter { BINARYWRITER_BASE @@ -51,7 +51,7 @@ public: * \param quest * \param compress */ - void write(ZQuest* quest, bool compress = true); + void write(ZQuestFile* quest, bool compress = true); }; } // io diff --git a/include/md5.h b/include/md5.h index cdc334e..c74fa9c 100644 --- a/include/md5.h +++ b/include/md5.h @@ -88,7 +88,7 @@ extern "C" * Typedefs: */ -typedef struct +typedef struct auth_md5Ctx_ { unsigned int len; unsigned int ABCD[4]; diff --git a/include/utility.hpp b/include/utility.hpp index 3e84937..df12c56 100644 --- a/include/utility.hpp +++ b/include/utility.hpp @@ -19,13 +19,19 @@ #include #include "Types.hpp" -bool isEmpty(Int8*, size_t); +namespace zelda +{ +namespace utility +{ -unsigned short swapU16(unsigned short val ); -short swap16 (short val ); -unsigned int swapU32(unsigned int val); -int swap32 (int val ); -long long swap64 (long long val); +bool isEmpty(Int8*, Uint32); + +Uint16 swapU16(Uint16 val ); +Int16 swap16 (Int16 val ); +Uint32 swapU32(Uint32 val); +Int32 swap32 (Int32 val ); +Uint64 swapU64(Uint64 val); +Int64 swap64 (Int64 val); float swapFloat(float val); double swapDouble(double val); @@ -36,4 +42,8 @@ void fillRandom(Uint8 * rndArea, Uint8 count); void yaz0Decode(Uint8* src, Uint8* dst, Uint32 uncompressedSize); + +} // utility +} // zelda + #endif diff --git a/libzelda.pro b/libzelda.pro index b7b8438..22f4fba 100644 --- a/libzelda.pro +++ b/libzelda.pro @@ -50,9 +50,9 @@ HEADERS += \ include/MCFileWriter.hpp \ include/ZQuestFileWriter.hpp \ include/ZQuestFileReader.hpp \ - include/ZQuest.hpp \ include/Compression.hpp \ - include/WiiImage.hpp + include/WiiImage.hpp \ + include/ZQuestFile.hpp SOURCES += \ src/utility.cpp \ @@ -79,9 +79,9 @@ SOURCES += \ src/MCFileWriter.cpp \ src/ZQuestFileWriter.cpp \ src/ZQuestFileReader.cpp \ - src/ZQuest.cpp \ src/Compression.cpp \ - src/WiiImage.cpp + src/WiiImage.cpp \ + src/ZQuestFile.cpp system("exec doxygen libzelda.conf") #system("cd doc/latex && make") diff --git a/src/BinaryReader.cpp b/src/BinaryReader.cpp index 00f6449..c49e2f0 100644 --- a/src/BinaryReader.cpp +++ b/src/BinaryReader.cpp @@ -103,8 +103,8 @@ Int16 BinaryReader::readInt16() Int16 ret = *(Int16*)(m_data + m_position); m_position += 2; - if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian)) - ret = swap16(ret); + if ((!utility::isSystemBigEndian() && m_endian == BigEndian) || (utility::isSystemBigEndian() && m_endian == LittleEndian)) + ret = utility::swap16(ret); return ret; } @@ -120,8 +120,8 @@ Uint16 BinaryReader::readUInt16() Uint16 ret = *(Uint16*)(m_data + m_position); m_position += 2; - if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian)) - ret = swapU16(ret); + if ((!utility::isSystemBigEndian() && m_endian == BigEndian) || (utility::isSystemBigEndian() && m_endian == LittleEndian)) + ret = utility::swapU16(ret); return ret; } @@ -138,8 +138,8 @@ Int32 BinaryReader::readInt32() Int32 ret = *(Int32*)(m_data + m_position); m_position += 4; - if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian)) - ret = swap32(ret); + if ((!utility::isSystemBigEndian() && m_endian == BigEndian) || (utility::isSystemBigEndian() && m_endian == LittleEndian)) + ret = utility::swap32(ret); return ret; } @@ -156,8 +156,8 @@ Uint32 BinaryReader::readUInt32() Uint32 ret = *(Uint32*)(m_data + m_position); m_position += 4; - if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian)) - ret = swapU32(ret); + if ((!utility::isSystemBigEndian() && m_endian == BigEndian) || (utility::isSystemBigEndian() && m_endian == LittleEndian)) + ret = utility::swapU32(ret); return ret; } @@ -174,8 +174,8 @@ Int64 BinaryReader::readInt64() Int64 ret = *(Int64*)(m_data + m_position); m_position += 8; - if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian)) - ret = swap64(ret); + if ((!utility::isSystemBigEndian() && m_endian == BigEndian) || (utility::isSystemBigEndian() && m_endian == LittleEndian)) + ret = utility::swap64(ret); return ret; } @@ -191,8 +191,8 @@ Uint64 BinaryReader::readUInt64() Uint64 ret = *(Uint64*)(m_data + m_position); m_position += 8; - if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian)) - ret = swap64(ret); + if ((!utility::isSystemBigEndian() && m_endian == BigEndian) || (utility::isSystemBigEndian() && m_endian == LittleEndian)) + ret = utility::swapU64(ret); return ret; } @@ -209,8 +209,8 @@ float BinaryReader::readFloat() float ret = *(float*)(m_data + m_position); m_position += 4; - if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian)) - ret = swapFloat(ret); + if ((!utility::isSystemBigEndian() && m_endian == BigEndian) || (utility::isSystemBigEndian() && m_endian == LittleEndian)) + ret = utility::swapFloat(ret); return ret; } @@ -227,8 +227,8 @@ double BinaryReader::readDouble() double ret = *(double*)(m_data + m_position); m_position += 8; - if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian)) - ret = swapDouble(ret); + if ((!utility::isSystemBigEndian() && m_endian == BigEndian) || (utility::isSystemBigEndian() && m_endian == LittleEndian)) + ret = utility::swapDouble(ret); return ret; } diff --git a/src/BinaryWriter.cpp b/src/BinaryWriter.cpp index a71830e..7907f71 100644 --- a/src/BinaryWriter.cpp +++ b/src/BinaryWriter.cpp @@ -105,8 +105,8 @@ void BinaryWriter::writeInt16(Int16 val) else if (m_position > m_length) throw error::IOException("BinaryWriter::WriteInt16 -> Position outside stream bounds"); - if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian)) - val = swap16(val); + if ((!utility::isSystemBigEndian() && m_endian == BigEndian) || (utility::isSystemBigEndian() && m_endian == LittleEndian)) + val = utility::swap16(val); *(Int16*)(m_data + m_position) = val; m_position += sizeof(Int16); @@ -126,8 +126,8 @@ void BinaryWriter::writeUInt16(Uint16 val) throw error::IOException("BinaryWriter::WriteUInt16 -> Position outside stream bounds"); - if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian)) - val = swapU16(val); + if ((!utility::isSystemBigEndian() && m_endian == BigEndian) || (utility::isSystemBigEndian() && m_endian == LittleEndian)) + val = utility::swapU16(val); *(Uint16*)(m_data + m_position) = val; m_position += sizeof(Uint16); @@ -146,8 +146,8 @@ void BinaryWriter::writeInt32(Int32 val) else if (m_position > m_length) throw error::IOException("BinaryWriter::WriteInt32 -> Position outside stream bounds"); - if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian)) - val = swap32(val); + if ((!utility::isSystemBigEndian() && m_endian == BigEndian) || (utility::isSystemBigEndian() && m_endian == LittleEndian)) + val = utility::swap32(val); *(Int32*)(m_data + m_position) = val; m_position += sizeof(Int32); @@ -166,8 +166,8 @@ void BinaryWriter::writeUInt32(Uint32 val) else if (m_position > m_length) throw error::IOException("BinaryWriter::WriteUInt32 -> Position outside stream bounds"); - if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian)) - val = swap32(val); + if ((!utility::isSystemBigEndian() && m_endian == BigEndian) || (utility::isSystemBigEndian() && m_endian == LittleEndian)) + val = utility::swapU32(val); *(Uint32*)(m_data + m_position) = val; m_position += sizeof(Uint32); @@ -187,8 +187,8 @@ void BinaryWriter::writeInt64(Int64 val) throw error::IOException("BinaryWriter::WriteInt64 -> Position outside stream bounds"); - if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian)) - val = swap64(val); + if ((!utility::isSystemBigEndian() && m_endian == BigEndian) || (utility::isSystemBigEndian() && m_endian == LittleEndian)) + val = utility::swap64(val); *(Int64*)(m_data + m_position) = val; m_position += sizeof(Int64); @@ -207,8 +207,8 @@ void BinaryWriter::writeUInt64(Uint64 val) else if (m_position > m_length) throw error::IOException("BinaryWriter::WriteUInt64 -> Position outside stream bounds"); - if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian)) - val = swap64(val); + if ((!utility::isSystemBigEndian() && m_endian == BigEndian) || (utility::isSystemBigEndian() && m_endian == LittleEndian)) + val = utility::swapU64(val); *(Uint64*)(m_data + m_position) = val; m_position += sizeof(Uint64); @@ -227,8 +227,8 @@ void BinaryWriter::writeFloat(float val) else if (m_position > m_length) throw error::IOException("BinaryWriter::WriteFloat -> Position outside stream bounds"); - if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian)) - val = swapFloat(val); + if ((!utility::isSystemBigEndian() && m_endian == BigEndian) || (utility::isSystemBigEndian() && m_endian == LittleEndian)) + val = utility::swapFloat(val); *(float*)(m_data + m_position) = val; m_position += sizeof(float); @@ -247,8 +247,8 @@ void BinaryWriter::writeDouble(double val) else if (m_position > m_length) throw error::IOException("BinaryWriter::WriteDouble -> Position outside stream bounds"); - if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian)) - val = swapDouble(val); + if ((!utility::isSystemBigEndian() && m_endian == BigEndian) || (utility::isSystemBigEndian() && m_endian == LittleEndian)) + val = utility::swapDouble(val); *(double*)(m_data + m_position)= val; m_position += sizeof(double); @@ -287,6 +287,16 @@ void BinaryWriter::writeUnicode(const std::string& str) } } +void BinaryWriter::writeString(const std::string& str) +{ + for (Uint8 c : str) + { + if (c != '\0') + writeUByte(c); + } + writeUByte(0); +} + bool BinaryWriter::isOpenForReading() { return false; diff --git a/src/Compression.cpp b/src/Compression.cpp index 712a5fa..c4fc99a 100644 --- a/src/Compression.cpp +++ b/src/Compression.cpp @@ -14,6 +14,8 @@ // along with libZelda. If not, see #include "Compression.hpp" +#include "Exception.hpp" +#include #include @@ -26,7 +28,7 @@ namespace Compression Int32 decompressZlib(Uint8 *src, Uint32 srcLen, Uint8* dst, Uint32 dstLen) { - z_stream strm; + z_stream strm = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; strm.total_in = strm.avail_in = srcLen; strm.total_out = strm.avail_out = dstLen; strm.next_in = (Bytef *) src; @@ -39,18 +41,20 @@ Int32 decompressZlib(Uint8 *src, Uint32 srcLen, Uint8* dst, Uint32 dstLen) Int32 err = -1; Int32 ret = -1; - err = inflateInit2(&strm, (15 + 32)); //15 window bits, and the +32 tells zlib to to detect if using gzip or zlib - if (err == Z_OK) { + err = inflateInit(&strm); //15 window bits, and the +32 tells zlib to to detect if using gzip or zlib + if (err == Z_OK) + { err = inflate(&strm, Z_FINISH); - if (err == Z_STREAM_END) { + if (err == Z_STREAM_END) ret = strm.total_out; - } - else { - inflateEnd(&strm); - return err; + else + { + inflateEnd(&strm); + return err; } } - else { + else + { inflateEnd(&strm); return err; } @@ -60,9 +64,43 @@ Int32 decompressZlib(Uint8 *src, Uint32 srcLen, Uint8* dst, Uint32 dstLen) return ret; } -void compressZlib(const Uint8 *src, Uint32 srcLen, Uint8 *dst, Uint32* dstLen) +Int32 compressZlib(const Uint8 *src, Uint32 srcLen, Uint8 *dst, Uint32 dstLen) { - compress(dst, (uLongf*)dstLen, src, srcLen); + z_stream strm = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + strm.total_in = strm.avail_in = srcLen; + strm.total_out = strm.avail_out = dstLen; + strm.next_in = (Bytef *) src; + strm.next_out = (Bytef *) dst; + + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + + Int32 err = -1; + Int32 ret = -1; + + err = deflateInit(&strm, Z_BEST_COMPRESSION); + + if (err == Z_OK) + { + err = deflate(&strm, Z_FINISH); + if (err == Z_STREAM_END) + ret = strm.total_out; + else + { + deflateEnd(&strm); + return err; + } + } + else + { + deflateEnd(&strm); + return err; + } + + deflateEnd(&strm); + + return ret; } } // Compression diff --git a/src/MCFileWriter.cpp b/src/MCFileWriter.cpp index da3b150..c9f48dd 100644 --- a/src/MCFileWriter.cpp +++ b/src/MCFileWriter.cpp @@ -17,6 +17,8 @@ namespace zelda { +namespace io +{ MCFileWriter::MCFileWriter(Uint8* data, Uint64 length) : base(data, length) @@ -93,4 +95,5 @@ void MCFileWriter::unscramble() } } +} // io } // zelda diff --git a/src/TextStream.cpp b/src/TextStream.cpp index a69d149..1db2aca 100644 --- a/src/TextStream.cpp +++ b/src/TextStream.cpp @@ -156,9 +156,9 @@ std::vector TextStream::readLines(Uint32 numLines) std::string TextStream::readLineAt(Uint32 line) { if (m_accessmode != ReadOnly && m_accessmode != ReadWrite) - throw error::InvalidOperationException("Stream not open for reading"); + throw error::InvalidOperationException("TextStream::readLineAt -> Stream not open for reading"); if (line <= 0) - throw error::InvalidOperationException("A line cannot be zero indexed"); + throw error::InvalidOperationException("TextStream::readLineAt -> A line cannot be zero indexed"); if ((line - 1) >= m_lines.size()) throw error::IOException("TextStream::readLineAt -> Line index out of range"); diff --git a/src/WiiImage.cpp b/src/WiiImage.cpp index fd5d5f1..e593570 100644 --- a/src/WiiImage.cpp +++ b/src/WiiImage.cpp @@ -72,7 +72,7 @@ Uint8 *WiiImage::toRGBA() Uint16 oldpixel = *(Uint16*)(m_data + ((iv++) * 2)); //if((x >= m_width) || (y >= m_height)) // continue; - oldpixel = swapU16(oldpixel); + oldpixel = utility::swapU16(oldpixel); if(oldpixel & (1 << 15)) { // RGB5 diff --git a/src/WiiSave.cpp b/src/WiiSave.cpp index 6e7136f..056ac47 100644 --- a/src/WiiSave.cpp +++ b/src/WiiSave.cpp @@ -18,7 +18,6 @@ #include "WiiBanner.hpp" #include "BinaryReader.hpp" #include "BinaryWriter.hpp" -#include "IOException.hpp" #include "aes.h" #include "ec.h" #include "utility.hpp" diff --git a/src/WiiSaveReader.cpp b/src/WiiSaveReader.cpp index fdfebda..f9154bb 100644 --- a/src/WiiSaveReader.cpp +++ b/src/WiiSaveReader.cpp @@ -225,7 +225,7 @@ WiiImage* WiiSaveReader::readImage(Uint32 width, Uint32 height) { Uint8* image = (Uint8*)base::readBytes(width*height*2); - if (!isEmpty((Int8*)image, width*height*2)) + if (!utility::isEmpty((Int8*)image, width*height*2)) return new WiiImage(width, height, image); return NULL; diff --git a/src/WiiSaveWriter.cpp b/src/WiiSaveWriter.cpp index 7421d60..86d21e7 100644 --- a/src/WiiSaveWriter.cpp +++ b/src/WiiSaveWriter.cpp @@ -167,15 +167,15 @@ Uint32 WiiSaveWriter::writeFile(WiiFile *file) base::writeByte(file->type()); Uint8 name[0x45]; - fillRandom(name, 0x45); + utility::fillRandom(name, 0x45); memcpy(name, file->filename().c_str(), file->filename().size()); name[file->filename().size()] = '\0'; base::writeBytes((Int8*)name, 0x45); Uint8 iv[16]; - fillRandom(iv, 0x10); + utility::fillRandom(iv, 0x10); base::writeBytes((Int8*)iv, 0x10); Uint8 crap[0x20]; - fillRandom(crap, 0x20); + utility::fillRandom(crap, 0x20); base::writeBytes((Int8*)crap, 0x20); if (file->type() == WiiFile::File) @@ -245,8 +245,8 @@ void WiiSaveWriter::writeCerts(Uint32 filesSize, Uint32 ngId, Uint8 *ngPriv, Uin generate_ecdsa(sig, sig+30, apPriv, hash2); int stuff = 0x2f536969; - if (!isSystemBigEndian()) - stuff = swap32(stuff); + if (!utility::isSystemBigEndian()) + stuff = utility::swap32(stuff); *(Uint32*)(sig+60) = stuff; delete[] hash2; diff --git a/src/ZQuest.cpp b/src/ZQuestFile.cpp similarity index 73% rename from src/ZQuest.cpp rename to src/ZQuestFile.cpp index b1b7b63..dc0c528 100644 --- a/src/ZQuest.cpp +++ b/src/ZQuestFile.cpp @@ -13,21 +13,21 @@ // You should have received a copy of the GNU General Public License // along with libZelda. If not, see -#include "ZQuest.hpp" +#include "ZQuestFile.hpp" namespace zelda { -const Uint32 ZQuest::Major = 1; -const Uint32 ZQuest::Minor = 0; -const Uint32 ZQuest::Revision = 0; -const Uint32 ZQuest::Build = 0; +const Uint32 ZQuestFile::Major = 1; +const Uint32 ZQuestFile::Minor = 0; +const Uint32 ZQuestFile::Revision = 0; +const Uint32 ZQuestFile::Build = 0; -const Uint32 ZQuest::Version = Major | (Minor << 8) | (Revision << 16) | (Build << 24); +const Uint32 ZQuestFile::Version = Major | (Minor << 8) | (Revision << 16) | (Build << 24); -const Uint32 ZQuest::Magic = 'Z' | ('Q' << 8) | ('S' << 16) | ('1' << 24); +const Uint32 ZQuestFile::Magic = 'Z' | ('Q' << 8) | ('S' << 16) | ('1' << 24); -ZQuest::ZQuest() +ZQuestFile::ZQuestFile() : m_game(NoGame), m_endian(LittleEndian), m_data(NULL), @@ -36,7 +36,7 @@ ZQuest::ZQuest() initGameStrings(); } -ZQuest::ZQuest(ZQuest::Game game, Endian endian, Uint8* data, Uint32 length) +ZQuestFile::ZQuestFile(ZQuestFile::Game game, Endian endian, Uint8* data, Uint32 length) : m_game(game), m_endian(endian), m_data(data), @@ -45,34 +45,34 @@ ZQuest::ZQuest(ZQuest::Game game, Endian endian, Uint8* data, Uint32 length) initGameStrings(); } -ZQuest::~ZQuest() +ZQuestFile::~ZQuestFile() { delete[] m_data; m_data = NULL; m_length = 0; } -void ZQuest::setGame(ZQuest::Game game) +void ZQuestFile::setGame(ZQuestFile::Game game) { m_game = game; } -ZQuest::Game ZQuest::game() const +ZQuestFile::Game ZQuestFile::game() const { return m_game; } -void ZQuest::setEndian(Endian endian) +void ZQuestFile::setEndian(Endian endian) { m_endian = endian; } -Endian ZQuest::endian() const +Endian ZQuestFile::endian() const { return m_endian; } -void ZQuest::setData(Uint8* data) +void ZQuestFile::setData(Uint8* data, Uint32 length) { // ensure we're not overwritting our data without freeing first // or assigning unnecessisarily @@ -80,25 +80,22 @@ void ZQuest::setData(Uint8* data) { delete[] m_data; m_data = data; + m_length = length; } } -Uint8* ZQuest::data() const +Uint8* ZQuestFile::data() const { return m_data; } -void ZQuest::setLength(Uint32 length) -{ - m_length = length; -} -Uint32 ZQuest::length() const +Uint32 ZQuestFile::length() const { return m_length; } -std::string ZQuest::gameString() const +std::string ZQuestFile::gameString() const { if (m_game > m_gameStrings.size() - 1) return "Unsupported Game"; @@ -106,7 +103,7 @@ std::string ZQuest::gameString() const return m_gameStrings[m_game]; } -void ZQuest::initGameStrings() +void ZQuestFile::initGameStrings() { m_gameStrings.push_back("No Game"); m_gameStrings.push_back("Legend Of Zelda"); diff --git a/src/ZQuestFileReader.cpp b/src/ZQuestFileReader.cpp index 5e76e64..63e035a 100644 --- a/src/ZQuestFileReader.cpp +++ b/src/ZQuestFileReader.cpp @@ -14,7 +14,7 @@ // along with libZelda. If not, see #include "ZQuestFileReader.hpp" -#include "ZQuest.hpp" +#include "ZQuestFile.hpp" #include "InvalidOperationException.hpp" #include "Compression.hpp" @@ -33,26 +33,26 @@ ZQuestFileReader::ZQuestFileReader(const std::string &filename) { } -ZQuest *ZQuestFileReader::read() +ZQuestFile *ZQuestFileReader::read() { Uint32 magic, version, compressedLen, uncompressedLen; - ZQuest::Game game; + ZQuestFile::Game game; Uint16 BOM; Uint8* data; magic = base::readUInt32(); - if (magic != ZQuest::Magic) + if (magic != ZQuestFile::Magic) throw error::InvalidOperationException("ZQuestFileReader::read -> Not a valid ZQuest file"); version = base::readUInt32(); - if (version != ZQuest::Version) + if (version != ZQuestFile::Version) throw error::InvalidOperationException("ZQuestFileReader::read -> Unsupported ZQuest version"); compressedLen = base::readUInt32(); uncompressedLen = base::readUInt32(); - game = (ZQuest::Game)base::readUInt32(); + game = (ZQuestFile::Game)base::readUInt32(); BOM = base::readUInt16(); base::seek(0x0A); data = (Uint8*)base::readBytes(compressedLen); // compressedLen is always the total file size @@ -73,7 +73,7 @@ ZQuest *ZQuestFileReader::read() data = dst; } - return new ZQuest(game, BOM == 0xFEFF ? BigEndian : LittleEndian, data, uncompressedLen); + return new ZQuestFile(game, BOM == 0xFEFF ? BigEndian : LittleEndian, data, uncompressedLen); } } // io diff --git a/src/ZQuestFileWriter.cpp b/src/ZQuestFileWriter.cpp index 6071b23..ecc0f2f 100644 --- a/src/ZQuestFileWriter.cpp +++ b/src/ZQuestFileWriter.cpp @@ -15,7 +15,7 @@ #include "ZQuestFileWriter.hpp" #include "InvalidOperationException.hpp" -#include "ZQuest.hpp" +#include "ZQuestFile.hpp" #include "Compression.hpp" namespace zelda @@ -33,22 +33,23 @@ ZQuestFileWriter::ZQuestFileWriter(const std::string& filename) { } -void ZQuestFileWriter::write(ZQuest* quest, bool compress) +void ZQuestFileWriter::write(ZQuestFile* quest, bool compress) { if (!quest) - throw error::InvalidOperationException("ZQuestFileWriter::writer -> quest cannot be NULL"); + throw error::InvalidOperationException("ZQuestFileWriter::write -> quest cannot be NULL"); - base::writeUInt32(ZQuest::Magic); - base::writeUInt32(ZQuest::Version); + base::writeUInt32(ZQuestFile::Magic); + base::writeUInt32(ZQuestFile::Version); Uint8* questData = quest->data(); - Uint32 compLen = quest->length(); + Uint32 compLen; if (compress) { - Uint8* compData = new Uint8[quest->length() + 0x20]; // add 20 bytes because sometimes the file grows with compression - io::Compression::compressZlib(questData, quest->length(), compData, &compLen); + Uint8* compData = new Uint8[quest->length() + 0x40]; // add 20 bytes because sometimes the file grows with compression + compLen = quest->length() + 0x40; + compLen = io::Compression::compressZlib(questData, quest->length(), compData, compLen); // if the compressed data is the same length or larger than the original data, just store the original - if (compLen >= quest->length()) + if (compLen >= quest->length() || compLen <= 0) { compLen = quest->length(); // Delete the compressed data since we won't be using it @@ -64,7 +65,10 @@ void ZQuestFileWriter::write(ZQuest* quest, bool compress) } } else + { + compLen = quest->length(); base::writeUInt32(quest->length()); + } base::writeUInt32(quest->length()); base::writeUInt32(quest->game()); @@ -73,6 +77,12 @@ void ZQuestFileWriter::write(ZQuest* quest, bool compress) base::writeUBytes(questData, compLen); base::save(); + // Delete compressed data to preven memory leaks + if (questData != quest->data()) + { + delete[] questData; + questData = NULL; + } } } // io diff --git a/src/aes.c b/src/aes.c index e753f58..9d6175e 100644 --- a/src/aes.c +++ b/src/aes.c @@ -8,15 +8,11 @@ algorithm place on its exploitation. */ - +#include "aes.h" #include //#include #include -typedef unsigned char u8; /* 8 bits */ -typedef unsigned long u32; /* 32 bits */ -typedef unsigned long long u64; - /* rotates x one bit to the left */ #define ROTL(x) (((x)>>7)|((x)<<1)) @@ -29,38 +25,38 @@ typedef unsigned long long u64; /* Fixed Data */ -static u8 InCo[4]={0xB,0xD,0x9,0xE}; /* Inverse Coefficients */ +static Uint8 InCo[4]={0xB,0xD,0x9,0xE}; /* Inverse Coefficients */ -static u8 fbsub[256]; -static u8 rbsub[256]; -static u8 ptab[256],ltab[256]; -static u32 ftable[256]; -static u32 rtable[256]; -static u32 rco[30]; +static Uint8 fbsub[256]; +static Uint8 rbsub[256]; +static Uint8 ptab[256],ltab[256]; +static Uint32 ftable[256]; +static Uint32 rtable[256]; +static Uint32 rco[30]; /* Parameter-dependent data */ int Nk,Nb,Nr; -u8 fi[24],ri[24]; -u32 fkey[120]; -u32 rkey[120]; +Uint8 fi[24],ri[24]; +Uint32 fkey[120]; +Uint32 rkey[120]; -static u32 pack(u8 *b) +static Uint32 pack(const Uint8 *b) { /* pack bytes into a 32-bit Word */ - return ((u32)b[3]<<24)|((u32)b[2]<<16)|((u32)b[1]<<8)|(u32)b[0]; + return ((Uint32)b[3]<<24)|((Uint32)b[2]<<16)|((Uint32)b[1]<<8)|(Uint32)b[0]; } -static void unpack(u32 a,u8 *b) +static void unpack(Uint32 a,Uint8 *b) { /* unpack bytes from a word */ - b[0]=(u8)a; - b[1]=(u8)(a>>8); - b[2]=(u8)(a>>16); - b[3]=(u8)(a>>24); + b[0]=(Uint8)a; + b[1]=(Uint8)(a>>8); + b[2]=(Uint8)(a>>16); + b[3]=(Uint8)(a>>24); } -static u8 xtime(u8 a) +static Uint8 xtime(Uint8 a) { - u8 b; + Uint8 b; if (a&0x80) b=0x1B; else b=0; a<<=1; @@ -68,15 +64,15 @@ static u8 xtime(u8 a) return a; } -static u8 bmul(u8 x,u8 y) +static Uint8 bmul(Uint8 x,Uint8 y) { /* x.y= AntiLog(Log(x) + Log(y)) */ if (x && y) return ptab[(ltab[x]+ltab[y])%255]; else return 0; } -static u32 SubByte(u32 a) +static Uint32 SubByte(Uint32 a) { - u8 b[4]; + Uint8 b[4]; unpack(a,b); b[0]=fbsub[b[0]]; b[1]=fbsub[b[1]]; @@ -85,18 +81,18 @@ static u32 SubByte(u32 a) return pack(b); } -static u8 product(u32 x,u32 y) +static Uint8 product(Uint32 x,Uint32 y) { /* dot product of two 4-byte arrays */ - u8 xb[4],yb[4]; + Uint8 xb[4],yb[4]; unpack(x,xb); unpack(y,yb); return bmul(xb[0],yb[0])^bmul(xb[1],yb[1])^bmul(xb[2],yb[2])^bmul(xb[3],yb[3]); } -static u32 InvMixCol(u32 x) +static Uint32 InvMixCol(Uint32 x) { /* matrix Multiplication */ - u32 y,m; - u8 b[4]; + Uint32 y,m; + Uint8 b[4]; m=pack(InCo); b[3]=product(m,x); @@ -110,9 +106,9 @@ static u32 InvMixCol(u32 x) return y; } -u8 ByteSub(u8 x) +Uint8 ByteSub(Uint8 x) { - u8 y=ptab[255-ltab[x]]; /* multiplicative inverse */ + Uint8 y=ptab[255-ltab[x]]; /* multiplicative inverse */ x=y; x=ROTL(x); y^=x; x=ROTL(x); y^=x; x=ROTL(x); @@ -124,7 +120,7 @@ u8 ByteSub(u8 x) void gentables(void) { /* generate tables */ int i; - u8 y,b[4]; + Uint8 y,b[4]; /* use 3 as primitive root to generate power and log tables */ @@ -143,7 +139,7 @@ void gentables(void) rbsub[0x63]=0; for (i=1;i<256;i++) { - y=ByteSub((u8)i); + y=ByteSub((Uint8)i); fbsub[i]=y; rbsub[y]=i; } @@ -168,14 +164,14 @@ void gentables(void) } } -void gkey(int nb,int nk,u8 *key) +void gkey(int nb,int nk, const Uint8 *key) { /* blocksize=32*nb bits. Key=32*nk bits */ /* currently nb,bk = 4, 6 or 8 */ /* key comes as 4*Nk bytes */ /* Key Scheduler. Create expanded encryption key */ int i,j,k,m,N; int C1,C2,C3; - u32 CipherKey[8]; + Uint32 CipherKey[8]; Nb=nb; Nk=nk; @@ -240,10 +236,10 @@ void gkey(int nb,int nk,u8 *key) * Instead of just one ftable[], I could have 4, the other * * 3 pre-rotated to save the ROTL8, ROTL16 and ROTL24 overhead */ -void encrypt(u8 *buff) +void encrypt(Uint8 *buff) { int i,j,k,m; - u32 a[8],b[8],*x,*y,*t; + Uint32 a[8],b[8],*x,*y,*t; for (i=j=0;i>8)])^ - ROTL16(ftable[(u8)(x[fi[m+1]]>>16)])^ - ROTL24(ftable[(u8)(x[fi[m+2]]>>24)]); + y[j]=fkey[k++]^ftable[(Uint8)x[j]]^ + ROTL8(ftable[(Uint8)(x[fi[m]]>>8)])^ + ROTL16(ftable[(Uint8)(x[fi[m+1]]>>16)])^ + ROTL24(ftable[(Uint8)(x[fi[m+2]]>>24)]); } t=x; x=y; y=t; /* swap pointers */ } @@ -274,23 +270,23 @@ void encrypt(u8 *buff) /* Last Round - unroll if possible */ for (m=j=0;j>8)])^ - ROTL16((u32)fbsub[(u8)(x[fi[m+1]]>>16)])^ - ROTL24((u32)fbsub[(u8)(x[fi[m+2]]>>24)]); + y[j]=fkey[k++]^(Uint32)fbsub[(Uint8)x[j]]^ + ROTL8((Uint32)fbsub[(Uint8)(x[fi[m]]>>8)])^ + ROTL16((Uint32)fbsub[(Uint8)(x[fi[m+1]]>>16)])^ + ROTL24((Uint32)fbsub[(Uint8)(x[fi[m+2]]>>24)]); } for (i=j=0;i>8)])^ - ROTL16(rtable[(u8)(x[ri[m+1]]>>16)])^ - ROTL24(rtable[(u8)(x[ri[m+2]]>>24)]); + y[j]=rkey[k++]^rtable[(Uint8)x[j]]^ + ROTL8(rtable[(Uint8)(x[ri[m]]>>8)])^ + ROTL16(rtable[(Uint8)(x[ri[m+1]]>>16)])^ + ROTL24(rtable[(Uint8)(x[ri[m+2]]>>24)]); } t=x; x=y; y=t; /* swap pointers */ } @@ -320,28 +316,28 @@ void decrypt(u8 *buff) /* Last Round - unroll if possible */ for (m=j=0;j>8)])^ - ROTL16((u32)rbsub[(u8)(x[ri[m+1]]>>16)])^ - ROTL24((u32)rbsub[(u8)(x[ri[m+2]]>>24)]); + y[j]=rkey[k++]^(Uint32)rbsub[(Uint8)x[j]]^ + ROTL8((Uint32)rbsub[(Uint8)(x[ri[m]]>>8)])^ + ROTL16((Uint32)rbsub[(Uint8)(x[ri[m+1]]>>16)])^ + ROTL24((Uint32)rbsub[(Uint8)(x[ri[m+2]]>>24)]); } for (i=j=0;i #include -bool isEmpty(Int8* buf, size_t size) +namespace zelda +{ +namespace utility +{ + +bool isEmpty(Int8* buf, Uint32 size) { return buf[0] == 0 && !memcmp(buf, buf + 1, size - 1); } -unsigned short swapU16(unsigned short val ) +Uint16 swapU16(Uint16 val ) { - return (val << 8) | (val >> 8 ); + return (Uint16)swap16(val); } -short swap16(short val ) +Int16 swap16(Int16 val ) { return (val << 8) | ((val >> 8) & 0xFF); } -unsigned int swapU32(unsigned int val) +Uint32 swapU32(Uint32 val) { - val = (val & 0x0000FFFF) << 16 | (val & 0xFFFF0000) >> 16; - val = (val & 0x00FF00FF) << 8 | (val & 0xFF00FF00) >> 8; - return (Uint32)val; + return (Uint32)swap32(val); } -int swap32( int val ) +int swap32(Int32 val ) { val = (val & 0x0000FFFF) << 16 | (val & 0xFFFF0000) >> 16; val = (val & 0x00FF00FF) << 8 | (val & 0xFF00FF00) >> 8; return val; } -long long swap64(long long val) +Uint64 swapU64(Uint64 val) { - return ((long long)((((long long)(val) & 0xFF00000000000000ULL) >> 56) | - (((long long)(val) & 0x00FF000000000000ULL) >> 40) | - (((long long)(val) & 0x0000FF0000000000ULL) >> 24) | - (((long long)(val) & 0x000000FF00000000ULL) >> 8) | - (((long long)(val) & 0x00000000FF000000ULL) << 8) | - (((long long)(val) & 0x0000000000FF0000ULL) << 24) | - (((long long)(val) & 0x000000000000FF00ULL) << 40) | - (((long long)(val) & 0x00000000000000FFULL) << 56))); + return (Uint64)swap64(val); +} + +Int64 swap64(Int64 val) +{ + return ((Int64)((((Int64)(val) & 0xFF00000000000000ULL) >> 56) | + (((Int64)(val) & 0x00FF000000000000ULL) >> 40) | + (((Int64)(val) & 0x0000FF0000000000ULL) >> 24) | + (((Int64)(val) & 0x000000FF00000000ULL) >> 8) | + (((Int64)(val) & 0x00000000FF000000ULL) << 8) | + (((Int64)(val) & 0x0000000000FF0000ULL) << 24) | + (((Int64)(val) & 0x000000000000FF00ULL) << 40) | + (((Int64)(val) & 0x00000000000000FFULL) << 56))); } bool isSystemBigEndian() { - char* test = (char*)"\xFE\xFF"; - return (*(unsigned short*)test == 0xFEFF); + Uint8* test = (Uint8*)"\xFE\xFF"; + return (*(Uint16*)test == 0xFEFF); } void fillRandom(Uint8 * rndArea, Uint8 count) { - for(Uint16 i = 0; i < count; i++) - rndArea[i]=rand(); + for(Uint16 i = 0; i < count; i++) + rndArea[i]=rand(); } float swapFloat(float val) @@ -108,57 +116,60 @@ double swapDouble(double val) //the second 4 bytes in the Yaz0 header). void yaz0Decode(Uint8* src, Uint8* dst, Uint32 uncompressedSize) { - Uint32 srcPlace = 0, dstPlace = 0; //current read/write positions + Uint32 srcPlace = 0, dstPlace = 0; //current read/write positions - Int32 validBitCount = 0; //number of valid bits left in "code" byte - Uint8 currCodeByte; - while(dstPlace < uncompressedSize) - { - //read new "code" byte if the current one is used up - if(validBitCount == 0) + Int32 validBitCount = 0; //number of valid bits left in "code" byte + Uint8 currCodeByte; + while(dstPlace < uncompressedSize) { - currCodeByte = src[srcPlace]; - ++srcPlace; - validBitCount = 8; + //read new "code" byte if the current one is used up + if(validBitCount == 0) + { + currCodeByte = src[srcPlace]; + ++srcPlace; + validBitCount = 8; + } + + if((currCodeByte & 0x80) != 0) + { + //straight copy + dst[dstPlace] = src[srcPlace]; + dstPlace++; + srcPlace++; + } + else + { + //RLE part + Uint8 byte1 = src[srcPlace]; + Uint8 byte2 = src[srcPlace + 1]; + srcPlace += 2; + + Uint32 dist = ((byte1 & 0xF) << 8) | byte2; + Uint32 copySource = dstPlace - (dist + 1); + + Uint32 numBytes = byte1 >> 4; + if(numBytes == 0) + { + numBytes = src[srcPlace] + 0x12; + srcPlace++; + } + else + numBytes += 2; + + //copy run + for(Uint32 i = 0; i < numBytes; ++i) + { + dst[dstPlace] = dst[copySource]; + copySource++; + dstPlace++; + } + } + + //use next bit from "code" byte + currCodeByte <<= 1; + validBitCount-=1; } - - if((currCodeByte & 0x80) != 0) - { - //straight copy - dst[dstPlace] = src[srcPlace]; - dstPlace++; - srcPlace++; - } - else - { - //RLE part - Uint8 byte1 = src[srcPlace]; - Uint8 byte2 = src[srcPlace + 1]; - srcPlace += 2; - - Uint32 dist = ((byte1 & 0xF) << 8) | byte2; - Uint32 copySource = dstPlace - (dist + 1); - - Uint32 numBytes = byte1 >> 4; - if(numBytes == 0) - { - numBytes = src[srcPlace] + 0x12; - srcPlace++; - } - else - numBytes += 2; - - //copy run - for(Uint32 i = 0; i < numBytes; ++i) - { - dst[dstPlace] = dst[copySource]; - copySource++; - dstPlace++; - } - } - - //use next bit from "code" byte - currCodeByte <<= 1; - validBitCount-=1; - } } + +} // utility +} // zelda