New code style refactor

This commit is contained in:
Jack Andersen 2018-12-07 19:18:17 -10:00
parent e1b29fda7a
commit 7243c687a8
123 changed files with 15125 additions and 18399 deletions

View File

@ -5,15 +5,14 @@
#include <wiiuse/wpad.h> #include <wiiuse/wpad.h>
#endif #endif
static void *xfb = nullptr; static void* xfb = nullptr;
static GXRModeObj* rmode = nullptr; static GXRModeObj* rmode = nullptr;
#endif #endif
#include <athena/MemoryReader.hpp> #include <athena/MemoryReader.hpp>
int main() int main() {
{
#if GEKKO #if GEKKO
VIDEO_Init(); VIDEO_Init();
#if HW_RVL #if HW_RVL
@ -37,8 +36,7 @@ int main()
VIDEO_WaitVSync(); VIDEO_WaitVSync();
athena::io::MemoryCopyReader test("sd:/test.dat"); athena::io::MemoryCopyReader test("sd:/test.dat");
while(true) while (true) {
{
#if HW_RVL #if HW_RVL
WPAD_ScanPads(); WPAD_ScanPads();
#endif #endif
@ -55,4 +53,3 @@ int main()
#endif #endif
return 0; return 0;
} }

File diff suppressed because it is too large Load Diff

View File

@ -3,8 +3,7 @@
#define EXPECTED_BYTES 281 #define EXPECTED_BYTES 281
int main(int argc, const char** argv) int main(int argc, const char** argv) {
{
TESTFile<atUint32, 2> file = {}; TESTFile<atUint32, 2> file = {};
file.arrCount[0] = 2; file.arrCount[0] = 2;
file.array.push_back(42); file.array.push_back(42);

View File

@ -3,42 +3,30 @@
using namespace athena; using namespace athena;
typedef io::DNA<Big> BigDNA; typedef io::DNA<Big> BigDNA;
enum ETest : atUint8 enum ETest : atUint8 { ZERO, ONE, TWO, THREE };
{
ZERO,
ONE,
TWO,
THREE
};
template <ETest EVal> template <ETest EVal>
struct AT_SPECIALIZE_PARMS(ETest::ZERO, ETest::ONE, ETest::TWO, ETest::THREE) struct AT_SPECIALIZE_PARMS(ETest::ZERO, ETest::ONE, ETest::TWO, ETest::THREE) TESTSubFile : public BigDNA {
TESTSubFile : public BigDNA
{
AT_DECL_DNA AT_DECL_DNA
Value<ETest> varE = EVal; Value<ETest> varE = EVal;
Value<atUint32> sub1; Value<atUint32> sub1;
Value<atUint32> sub2; Value<atUint32> sub2;
}; };
struct TESTSubClassFile : public TESTSubFile<ETest::ONE> struct TESTSubClassFile : public TESTSubFile<ETest::ONE> {
{
AT_DECL_DNA AT_DECL_DNA
Value<atUint32> sub3; Value<atUint32> sub3;
Value<atUint16> sub4; Value<atUint16> sub4;
}; };
struct TESTSubSubClassFile : public TESTSubClassFile struct TESTSubSubClassFile : public TESTSubClassFile {
{
AT_DECL_DNA AT_DECL_DNA
Value<atUint32> sub5; Value<atUint32> sub5;
Value<atUint32> sub6; Value<atUint32> sub6;
}; };
template <class Var32Tp, int Var32Val> template <class Var32Tp, int Var32Val>
struct AT_SPECIALIZE_PARMS(atUint16, 42, atUint32, 87, atUint32, 2) struct AT_SPECIALIZE_PARMS(atUint16, 42, atUint32, 87, atUint32, 2) TESTFile : public BigDNA {
TESTFile : public BigDNA
{
AT_DECL_DNA AT_DECL_DNA
Value<bool> varBool; Value<bool> varBool;
AT_OVERRIDE_RCRC32(12345678) Value<Var32Tp> x4_var32 = Var32Val; AT_OVERRIDE_RCRC32(12345678) Value<Var32Tp> x4_var32 = Var32Val;
@ -46,8 +34,7 @@ TESTFile : public BigDNA
Value<atVec3f> vec3; Value<atVec3f> vec3;
Value<atVec4f> vec4; Value<atVec4f> vec4;
struct TESTNestedSubFile : public BigDNA struct TESTNestedSubFile : public BigDNA {
{
AT_DECL_DNA AT_DECL_DNA
Value<atUint32> nestSub1; Value<atUint32> nestSub1;
Value<atUint32> nestSub2; Value<atUint32> nestSub2;
@ -59,9 +46,7 @@ TESTFile : public BigDNA
Align<4> align; Align<4> align;
template <class NestedTp, int NestedVal> template <class NestedTp, int NestedVal>
struct AT_SPECIALIZE_PARMS(atInt32, 36, atInt64, 96) struct AT_SPECIALIZE_PARMS(atInt32, 36, atInt64, 96) TESTTemplateSubFile : public BigDNA {
TESTTemplateSubFile : public BigDNA
{
AT_DECL_DNA AT_DECL_DNA
Value<NestedTp> explSub1 = NestedVal; Value<NestedTp> explSub1 = NestedVal;
Value<Var32Tp> explSub2 = Var32Val; Value<Var32Tp> explSub2 = Var32Val;
@ -86,4 +71,3 @@ TESTFile : public BigDNA
String<32> str; String<32> str;
WString<64> wstr; WString<64> wstr;
}; };

View File

@ -3,10 +3,10 @@
#include <string> #include <string>
#include "LZ77/LZLookupTable.hpp" #include "LZ77/LZLookupTable.hpp"
class LZBase class LZBase {
{
public: public:
explicit LZBase(atInt32 minimumOffset = 1, atInt32 slidingWindow = 4096, atInt32 minimumMatch = 3, atInt32 blockSize = 8); explicit LZBase(atInt32 minimumOffset = 1, atInt32 slidingWindow = 4096, atInt32 minimumMatch = 3,
atInt32 blockSize = 8);
virtual ~LZBase() {} virtual ~LZBase() {}
virtual atUint32 compress(const atUint8* src, atUint8** dest, atUint32 srcLength) = 0; virtual atUint32 compress(const atUint8* src, atUint8** dest, atUint32 srcLength) = 0;
@ -23,20 +23,18 @@ public:
void setMinimumOffset(atUint32 minimumOffset); void setMinimumOffset(atUint32 minimumOffset);
atUint32 minimumOffset(); atUint32 minimumOffset();
private: private:
atInt32 subMatch(const atUint8* str1, const uint8_t* str2, const atInt32 len); atInt32 subMatch(const atUint8* str1, const uint8_t* str2, const atInt32 len);
LZLengthOffset windowSearch(atUint8* beginSearchPtr, atUint8* searchPosPtr, atUint8* endLABufferPtr, atUint8* startLBPtr); LZLengthOffset windowSearch(atUint8* beginSearchPtr, atUint8* searchPosPtr, atUint8* endLABufferPtr,
atUint8* startLBPtr);
protected: protected:
LZLengthOffset search(atUint8* posPtr, atUint8* dataBegin, atUint8* dataEnd); LZLengthOffset search(atUint8* posPtr, atUint8* dataBegin, atUint8* dataEnd);
atInt32 m_slidingWindow; atInt32 m_slidingWindow;
atInt32 m_readAheadBuffer; atInt32 m_readAheadBuffer;
atInt32 m_minMatch;//Minimum number of bytes that have to matched to go through with compression atInt32 m_minMatch; // Minimum number of bytes that have to matched to go through with compression
atInt32 m_blockSize; atInt32 m_blockSize;
atUint32 m_minOffset; atUint32 m_minOffset;
LZLookupTable m_lookupTable; LZLookupTable m_lookupTable;
}; };

View File

@ -6,24 +6,20 @@
#include <cstdint> #include <cstdint>
#include <athena/Types.hpp> #include <athena/Types.hpp>
struct LZLengthOffset struct LZLengthOffset {
{ atUint32 length; // The number of bytes compressed
atUint32 length;//The number of bytes compressed atUint16 offset; // How far back in sliding window where bytes that match the lookAheadBuffer is located
atUint16 offset;//How far back in sliding window where bytes that match the lookAheadBuffer is located bool compare_equal(const LZLengthOffset& lo_pair) { return length == lo_pair.length && offset == lo_pair.offset; }
bool compare_equal(const LZLengthOffset& lo_pair)
{
return length == lo_pair.length && offset == lo_pair.offset;
}
}; };
class LZLookupTable class LZLookupTable {
{
public: public:
LZLookupTable(); LZLookupTable();
LZLookupTable(atInt32 minimumMatch, atInt32 slidingWindow = 4096, atInt32 lookAheadWindow = 18); LZLookupTable(atInt32 minimumMatch, atInt32 slidingWindow = 4096, atInt32 lookAheadWindow = 18);
~LZLookupTable(); ~LZLookupTable();
LZLengthOffset search(atUint8* curPos, const atUint8* dataBegin, const atUint8* dataEnd); LZLengthOffset search(atUint8* curPos, const atUint8* dataBegin, const atUint8* dataEnd);
void setLookAheadWindow(atInt32 lookAheadWindow); void setLookAheadWindow(atInt32 lookAheadWindow);
private: private:
typedef std::multimap<std::vector<uint8_t>, int32_t> LookupTable; typedef std::multimap<std::vector<uint8_t>, int32_t> LookupTable;
LookupTable table; LookupTable table;
@ -31,7 +27,4 @@ private:
atInt32 m_slidingWindow; atInt32 m_slidingWindow;
atInt32 m_lookAheadWindow; atInt32 m_lookAheadWindow;
std::vector<uint8_t> m_buffer; std::vector<uint8_t> m_buffer;
}; };

View File

@ -2,11 +2,10 @@
#include "LZBase.hpp" #include "LZBase.hpp"
class LZType10 : public LZBase class LZType10 : public LZBase {
{
public: public:
explicit LZType10(atInt32 minimumOffset = 1, atInt32 SlidingWindow = 4096, atInt32 MinimumMatch = 3, atInt32 BlockSize = 8); explicit LZType10(atInt32 minimumOffset = 1, atInt32 SlidingWindow = 4096, atInt32 MinimumMatch = 3,
atInt32 BlockSize = 8);
atUint32 compress(const atUint8* src, atUint8** dest, atUint32 srcLength); atUint32 compress(const atUint8* src, atUint8** dest, atUint32 srcLength);
atUint32 decompress(const atUint8* src, atUint8** dst, atUint32 srcLen); atUint32 decompress(const atUint8* src, atUint8** dst, atUint32 srcLen);
}; };

View File

@ -1,14 +1,11 @@
#pragma once #pragma once
#include "LZBase.hpp" #include "LZBase.hpp"
class LZType11 : public LZBase class LZType11 : public LZBase {
{
public: public:
explicit LZType11(atInt32 MinimumOffset = 1, atInt32 SlidingWindow = 4096, atInt32 MinimumMatch = 3, atInt32 BlockSize = 8); explicit LZType11(atInt32 MinimumOffset = 1, atInt32 SlidingWindow = 4096, atInt32 MinimumMatch = 3,
atInt32 BlockSize = 8);
atUint32 compress(const atUint8* src, atUint8** dest, atUint32 srcLength); atUint32 compress(const atUint8* src, atUint8** dest, atUint32 srcLength);
atUint32 decompress(const atUint8* src, atUint8** dest, atUint32 srcLength); atUint32 decompress(const atUint8* src, atUint8** dest, atUint32 srcLength);
}; };

View File

@ -4,19 +4,16 @@
#include <cstdlib> #include <cstdlib>
#include <memory> #include <memory>
namespace athena namespace athena {
{
class IAES class IAES {
{
public: public:
virtual ~IAES() {} virtual ~IAES() {}
virtual void encrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len)=0; virtual void encrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len) = 0;
virtual void decrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len)=0; virtual void decrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len) = 0;
virtual void setKey(const uint8_t* key)=0; virtual void setKey(const uint8_t* key) = 0;
}; };
std::unique_ptr<IAES> NewAES(); std::unique_ptr<IAES> NewAES();
} } // namespace athena

View File

@ -2,39 +2,17 @@
#include "Types.hpp" #include "Types.hpp"
namespace athena namespace athena {
{
enum BowType : char enum BowType : char { BowNone, BowArrows, BowSilverArrows };
{
BowNone,
BowArrows,
BowSilverArrows
};
enum BoomerangType : char enum BoomerangType : char { BoomerangNone, BoomerangBlue, BoomerangRed };
{
BoomerangNone,
BoomerangBlue,
BoomerangRed
};
enum MagicType : char enum MagicType : char { MagicNone, MagicMushroom, MagicPowder };
{
MagicNone,
MagicMushroom,
MagicPowder
};
enum ArmorType : char enum ArmorType : char { GreenJerkin, BlueMail, RedMail };
{
GreenJerkin,
BlueMail,
RedMail
};
enum BottleType : char enum BottleType : char {
{
BottleNone, BottleNone,
BottleMushroom, // No Use BottleMushroom, // No Use
BottleEmpty, BottleEmpty,
@ -45,24 +23,11 @@ enum BottleType : char
BottleGoodBee BottleGoodBee
}; };
enum ALTTPStartLocation { LinksHouse = 0x00, Sanctuary = 0x01, Any = 0x05 };
enum ALTTPStartLocation enum ALTTPProgressIndicator { LinkInBed, InCastleWithSword, CompletedFirstDungeon, BeatenAghanim };
{
LinksHouse = 0x00,
Sanctuary = 0x01,
Any = 0x05
};
enum ALTTPProgressIndicator enum ALTTPMapIcon {
{
LinkInBed,
InCastleWithSword,
CompletedFirstDungeon,
BeatenAghanim
};
enum ALTTPMapIcon
{
Nothing = 0x00, //? Nothing = 0x00, //?
CrossInKakariko = 0x01, //? CrossInKakariko = 0x01, //?
CrossAtFirstDungeon = 0x02, // CrossAtFirstDungeon = 0x02, //
@ -74,8 +39,7 @@ enum ALTTPMapIcon
AganhimGanonTower = 0x08 AganhimGanonTower = 0x08
}; };
enum ALTTPTagAlong enum ALTTPTagAlong {
{
Noone, Noone,
Zelda, Zelda,
Unknown1, Unknown1,
@ -90,4 +54,4 @@ enum ALTTPTagAlong
AfterBoss AfterBoss
}; };
} // zelda } // namespace athena

View File

@ -3,8 +3,7 @@
#include "athena/Global.hpp" #include "athena/Global.hpp"
#include <vector> #include <vector>
namespace athena namespace athena {
{
class ALTTPQuest; class ALTTPQuest;
@ -14,8 +13,7 @@ class ALTTPQuest;
* Contains all relevant data for an A Link to the Past * Contains all relevant data for an A Link to the Past
* SRM file. * SRM file.
*/ */
class ALTTPFile class ALTTPFile {
{
public: public:
/*! \brief Quest Iterator /*! \brief Quest Iterator
* *
@ -36,7 +34,6 @@ public:
*/ */
ALTTPFile(std::vector<ALTTPQuest*> questList, std::vector<ALTTPQuest*> backupList); ALTTPFile(std::vector<ALTTPQuest*> questList, std::vector<ALTTPQuest*> backupList);
/*! \brief Sets a quest at the given index /*! \brief Sets a quest at the given index
* *
* \param id Index to the given quest * \param id Index to the given quest
@ -66,9 +63,8 @@ public:
atUint32 questCount() const; atUint32 questCount() const;
private: private:
std::vector<ALTTPQuest*> m_quests; std::vector<ALTTPQuest*> m_quests;
std::vector<ALTTPQuest*> m_backup; std::vector<ALTTPQuest*> m_backup;
}; };
} // zelda } // namespace athena

View File

@ -5,12 +5,10 @@
#include "athena/MemoryReader.hpp" #include "athena/MemoryReader.hpp"
#include "athena/ALTTPQuest.hpp" #include "athena/ALTTPQuest.hpp"
namespace athena namespace athena {
{
class ALTTPFile; class ALTTPFile;
namespace io namespace io {
{
/*! \class ALTTPFileReader /*! \class ALTTPFileReader
* \brief A Link to the Past save data reader class * \brief A Link to the Past save data reader class
* *
@ -18,8 +16,7 @@ namespace io
* all work is done using a memory buffer, and not read directly from the disk. * all work is done using a memory buffer, and not read directly from the disk.
* \sa BinaryReader * \sa BinaryReader
*/ */
class ALTTPFileReader : protected MemoryCopyReader class ALTTPFileReader : protected MemoryCopyReader {
{
public: public:
/*! \brief This constructor takes an existing buffer to read from. /*! \brief This constructor takes an existing buffer to read from.
* *
@ -39,11 +36,12 @@ public:
* \return ALTTPFile* SRAM data * \return ALTTPFile* SRAM data
*/ */
ALTTPFile* readFile(); ALTTPFile* readFile();
private: private:
ALTTPRoomFlags* readRoomFlags(); ALTTPRoomFlags* readRoomFlags();
ALTTPOverworldEvent* readOverworldEvent(); ALTTPOverworldEvent* readOverworldEvent();
ALTTPDungeonItemFlags readDungeonFlags(); ALTTPDungeonItemFlags readDungeonFlags();
}; };
} // io } // namespace io
} // zelda } // namespace athena

View File

@ -4,12 +4,10 @@
#include "athena/MemoryWriter.hpp" #include "athena/MemoryWriter.hpp"
#include "athena/ALTTPQuest.hpp" #include "athena/ALTTPQuest.hpp"
namespace athena namespace athena {
{
class ALTTPFile; class ALTTPFile;
namespace io namespace io {
{
/*! \class ALTTPFileWriter /*! \class ALTTPFileWriter
* \brief A Link to the Past save data writer class * \brief A Link to the Past save data writer class
* *
@ -17,8 +15,7 @@ namespace io
* all work is done using a memory buffer, and not written directly to the disk. * all work is done using a memory buffer, and not written directly to the disk.
* \sa BinaryReader * \sa BinaryReader
*/ */
class ALTTPFileWriter : protected MemoryCopyWriter class ALTTPFileWriter : protected MemoryCopyWriter {
{
public: public:
/*! \brief This constructor takes an existing buffer to write to. /*! \brief This constructor takes an existing buffer to write to.
* *
@ -46,6 +43,5 @@ private:
atUint16 calculateChecksum(atUint32 game); atUint16 calculateChecksum(atUint32 game);
}; };
} // io } // namespace io
} // zelda } // namespace athena

View File

@ -6,8 +6,7 @@
#include "athena/ALTTPStructs.hpp" #include "athena/ALTTPStructs.hpp"
#include "athena/ALTTPEnums.hpp" #include "athena/ALTTPEnums.hpp"
namespace athena namespace athena {
{
/*! \class ALTTPQuest /*! \class ALTTPQuest
* \brief A Link to the Past Quest container class * \brief A Link to the Past Quest container class
@ -15,8 +14,7 @@ namespace athena
* Contains all relevant data for an A Link to the Past * Contains all relevant data for an A Link to the Past
* Quest entry. * Quest entry.
*/ */
class ALTTPQuest class ALTTPQuest {
{
public: public:
/*! /*!
* \brief ALTTPQuest * \brief ALTTPQuest
@ -321,7 +319,6 @@ public:
* \param val * \param val
*/ */
void setCrystals(ALTTPCrystals val); void setCrystals(ALTTPCrystals val);
\
/*! /*!
* \brief crystals * \brief crystals
@ -621,6 +618,7 @@ public:
* \return * \return
*/ */
atUint16 checksum() const; atUint16 checksum() const;
private: private:
std::vector<ALTTPRoomFlags*> m_roomFlags; std::vector<ALTTPRoomFlags*> m_roomFlags;
std::vector<ALTTPOverworldEvent*> m_overworldEvents; std::vector<ALTTPOverworldEvent*> m_overworldEvents;
@ -666,5 +664,4 @@ private:
atUint16 m_checksum; atUint16 m_checksum;
}; };
} // zelda } // namespace athena

View File

@ -3,43 +3,39 @@
#include <string> #include <string>
#include "athena/Types.hpp" #include "athena/Types.hpp"
namespace athena namespace athena {
{
struct ALTTPRoomFlags struct ALTTPRoomFlags {
{ bool Chest1 : 1;
bool Chest1: 1; bool Chest2 : 1;
bool Chest2: 1; bool Chest3 : 1;
bool Chest3: 1; bool Chest4 : 1;
bool Chest4: 1; bool Quadrant1 : 1;
bool Quadrant1: 1; bool Quadrant2 : 1;
bool Quadrant2: 1; bool Quadrant3 : 1;
bool Quadrant3: 1; bool Quadrant4 : 1;
bool Quadrant4: 1; bool Door1 : 1;
bool Door1: 1; bool Door2 : 1;
bool Door2: 1; bool Door3 : 1;
bool Door3: 1; bool Door4 : 1;
bool Door4: 1; bool BossBattleWon : 1;
bool BossBattleWon: 1; bool Key : 1;
bool Key: 1; bool KeyOrChest : 1;
bool KeyOrChest: 1; bool ChestOrTile : 1;
bool ChestOrTile: 1;
}; };
struct ALTTPOverworldEvent struct ALTTPOverworldEvent {
{ bool Unused1 : 1;
bool Unused1: 1; bool HeartPiece : 1;
bool HeartPiece: 1; bool Overlay : 1;
bool Overlay: 1; bool Unused2 : 1;
bool Unused2: 1; bool Unused3 : 1;
bool Unused3: 1; bool Unused4 : 1;
bool Unused4: 1; bool Set : 1;
bool Set: 1; bool Unused5 : 1;
bool Unused5: 1;
}; };
struct ALTTPInventory struct ALTTPInventory {
{
char Bow; char Bow;
char Boomerang; char Boomerang;
bool Hookshot; bool Hookshot;
@ -73,126 +69,110 @@ struct ALTTPInventory
/*! \struct ALTTPLightDarkWorldIndicator /*! \struct ALTTPLightDarkWorldIndicator
*/ */
struct ALTTPLightDarkWorldIndicator struct ALTTPLightDarkWorldIndicator {
{ bool Unused1 : 1;
bool Unused1: 1; bool Unused2 : 1;
bool Unused2: 1; bool Unused3 : 1;
bool Unused3: 1; bool Unused4 : 1;
bool Unused4: 1; bool Unused5 : 1;
bool Unused5: 1; bool Unused6 : 1;
bool Unused6: 1; bool IsDarkWorld : 1;
bool IsDarkWorld: 1; bool Unused7 : 1;
bool Unused7: 1;
}; };
struct ALTTPDungeonItemFlags {
struct ALTTPDungeonItemFlags union {
{ struct {
union bool Unused1 : 1;
{ bool Unused2 : 1;
struct bool GanonsTower : 1;
{ bool TurtleRock : 1;
bool Unused1: 1; bool GargoylesDomain : 1;
bool Unused2: 1; bool TowerOfHera : 1;
bool GanonsTower: 1; bool IcePalace : 1;
bool TurtleRock: 1; bool SkullWoods : 1;
bool GargoylesDomain: 1;
bool TowerOfHera: 1;
bool IcePalace: 1;
bool SkullWoods: 1;
}; };
atUint8 flags1; atUint8 flags1;
}; };
union union {
{ struct {
struct bool MiseryMire : 1;
{ bool DarkPalace : 1;
bool MiseryMire: 1; bool SwampPalace : 1;
bool DarkPalace: 1; bool HyruleCastle2 : 1; // unused in orignal game
bool SwampPalace: 1; bool DesertPalace : 1;
bool HyruleCastle2: 1; // unused in orignal game bool EasternPalace : 1;
bool DesertPalace: 1; bool HyruleCastle : 1; // unused exist in original game
bool EasternPalace: 1; bool SewerPassage : 1; // unused exist in original game
bool HyruleCastle: 1; // unused exist in original game
bool SewerPassage: 1; // unused exist in original game
}; };
atUint8 flags2; atUint8 flags2;
}; };
}; };
struct ALTTPPendants struct ALTTPPendants {
{ bool Courage : 1;
bool Courage: 1; bool Wisdom : 1;
bool Wisdom: 1; bool Power : 1;
bool Power: 1; bool Unused1 : 1;
bool Unused1: 1; bool Unused2 : 1;
bool Unused2: 1; bool Unused3 : 1;
bool Unused3: 1; bool Unused4 : 1;
bool Unused4: 1; bool Unused5 : 1;
bool Unused5: 1;
}; };
struct ALTTPAbilities struct ALTTPAbilities {
{ bool Nothing : 1; //?
bool Nothing: 1; //? bool Swim : 1;
bool Swim: 1; bool Dash : 1;
bool Dash: 1; bool Pull : 1;
bool Pull: 1; bool Unknown1 : 1; //---
bool Unknown1: 1; //--- bool Talk : 1;
bool Talk: 1; bool Read : 1;
bool Read: 1; bool Unknown2 : 1; //---
bool Unknown2: 1; //---
}; };
struct ALTTPCrystals struct ALTTPCrystals {
{ bool MiseryMire : 1;
bool MiseryMire: 1; bool DarkPalace : 1;
bool DarkPalace: 1; bool IcePalace : 1;
bool IcePalace: 1; bool TurtleRock : 1;
bool TurtleRock: 1; bool SwampPalace : 1;
bool SwampPalace: 1; bool GargoyleDomain : 1;
bool GargoyleDomain: 1; bool SkullWoods : 1;
bool SkullWoods: 1;
}; };
struct ALTTPMagicUsage struct ALTTPMagicUsage {
{ bool Normal : 1;
bool Normal: 1; bool Half : 1;
bool Half: 1; bool Quarter : 1;
bool Quarter: 1; bool Unused1 : 1;
bool Unused1: 1; bool Unused2 : 1;
bool Unused2: 1; bool Unused3 : 1;
bool Unused3: 1; bool Unused4 : 1;
bool Unused4: 1; bool Unused5 : 1;
bool Unused5: 1;
}; };
struct ALTTPProgressFlags1 {
struct ALTTPProgressFlags1 bool UncleSecretPassage : 1;
{ bool DyingPriest : 1; //?
bool UncleSecretPassage: 1; bool ZeldaSanctuary : 1; //?
bool DyingPriest: 1; //? bool Unused1 : 1;
bool ZeldaSanctuary: 1; //? bool UncleLeftHouse : 1;
bool Unused1: 1; bool BookOfMudora : 1; //? Math says it's a guess need to investigate
bool UncleLeftHouse: 1; bool DwarfPartner : 1; //?
bool BookOfMudora: 1; //? Math says it's a guess need to investigate bool Unused2 : 1;
bool DwarfPartner: 1; //?
bool Unused2: 1;
}; };
struct ALTTPProgressFlags2 {
struct ALTTPProgressFlags2 bool BottleFromBum : 1;
{ bool BottleFromSalesMen : 1;
bool BottleFromBum: 1; bool Unused1 : 1; //?
bool BottleFromSalesMen: 1; bool FluteBoy : 1;
bool Unused1: 1; //? bool ThiefsChest : 1;
bool FluteBoy: 1; bool SavedSmithPartner : 1;
bool ThiefsChest: 1; bool Unused2 : 1; //?
bool SavedSmithPartner: 1; bool SmithsHaveSword : 1;
bool Unused2: 1; //?
bool SmithsHaveSword: 1;
}; };
} } // namespace athena

View File

@ -2,10 +2,10 @@
#include "athena/Global.hpp" #include "athena/Global.hpp"
namespace athena::checksums namespace athena::checksums {
{ atUint64 crc64(const atUint8* data, atUint64 length, atUint64 seed = 0xFFFFFFFFFFFFFFFF,
atUint64 crc64(const atUint8* data, atUint64 length, atUint64 seed = 0xFFFFFFFFFFFFFFFF, atUint64 final = 0xFFFFFFFFFFFFFFFF); atUint64 final = 0xFFFFFFFFFFFFFFFF);
atUint32 crc32(const atUint8* data, atUint64 length, atUint32 seed = 0xFFFFFFFF, atUint32 final = 0xFFFFFFFF); atUint32 crc32(const atUint8* data, atUint64 length, atUint32 seed = 0xFFFFFFFF, atUint32 final = 0xFFFFFFFF);
atUint16 crc16CCITT(const atUint8* data, atUint64 length, atUint16 seed = 0xFFFF, atUint16 final = 0); atUint16 crc16CCITT(const atUint8* data, atUint64 length, atUint16 seed = 0xFFFF, atUint16 final = 0);
atUint16 crc16(const atUint8* data, atUint64 length, atUint16 seed = 0, atUint16 final = 0); atUint16 crc16(const atUint8* data, atUint64 length, atUint16 seed = 0, atUint16 final = 0);
} } // namespace athena::checksums

View File

@ -2,196 +2,161 @@
#include <cstdint> #include <cstdint>
namespace athena::checksums::literals namespace athena::checksums::literals {
{
constexpr uint32_t crc32_table[] = constexpr uint32_t crc32_table[] = {
{ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832,
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A,
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3,
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4,
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074,
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615,
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76,
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7,
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7,
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330,
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D};
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, template <uint32_t CRC, char... Chars>
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, struct Crc32Impl {};
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
template <uint32_t CRC, char Head, char... Tail>
struct Crc32Impl<CRC, Head, Tail...> {
static constexpr uint32_t value =
Crc32Impl<crc32_table[static_cast<unsigned char>(CRC) ^ static_cast<unsigned char>(Head)] ^ (CRC >> 8),
Tail...>::value;
}; };
template<uint32_t CRC, char ...Chars> struct Crc32Impl { template <uint32_t CRC>
}; struct Crc32Impl<CRC> {
template<uint32_t CRC, char Head, char ...Tail> struct Crc32Impl<CRC, Head, Tail...> {
static constexpr uint32_t value = Crc32Impl<
crc32_table[static_cast<unsigned char>(CRC) ^ static_cast<unsigned char>(Head)]
^ (CRC >> 8), Tail...>::value;
};
template<uint32_t CRC> struct Crc32Impl<CRC> {
static constexpr uint32_t value = CRC ^ 0xFFFFFFFF; static constexpr uint32_t value = CRC ^ 0xFFFFFFFF;
}; };
template <char... Chars>
using Crc32 = Crc32Impl<0xFFFFFFFF, Chars...>;
template<char ...Chars> using Crc32 = Crc32Impl<0xFFFFFFFF, Chars...>; constexpr uint32_t crc32_rec(uint32_t crc, const char* s) {
return *s == 0 ? crc ^ 0xFFFFFFFF
constexpr uint32_t crc32_rec(uint32_t crc, const char *s) { : crc32_rec(crc32_table[static_cast<unsigned char>(crc) ^ static_cast<unsigned char>(*s)] ^ (crc >> 8),
return *s == 0 ? crc ^ 0xFFFFFFFF : s + 1);
crc32_rec(crc32_table[static_cast<unsigned char>(crc) ^
static_cast<unsigned char>(*s)]
^ (crc >> 8), s + 1);
} }
constexpr uint32_t operator "" _crc32(const char *s, size_t len) { constexpr uint32_t operator"" _crc32(const char* s, size_t len) { return crc32_rec(0xFFFFFFFF, s); }
return crc32_rec(0xFFFFFFFF, s);
static_assert("Hello"_crc32 == Crc32<'H', 'e', 'l', 'l', 'o'>::value, "CRC32 values don't match");
static_assert("0"_crc32 == Crc32<'0'>::value, "CRC32 values don't match");
constexpr uint32_t rcrc32_rec(uint32_t crc, const char* s) {
return *s == 0 ? crc
: crc32_rec(crc32_table[static_cast<unsigned char>(crc) ^ static_cast<unsigned char>(*s)] ^ (crc >> 8),
s + 1);
} }
static_assert("Hello"_crc32 == Crc32<'H', 'e', 'l', 'l', 'o'>::value, constexpr uint32_t operator"" _rcrc32(const char* s, size_t len) { return rcrc32_rec(0xFFFFFFFF, s); }
"CRC32 values don't match");
static_assert("0"_crc32 == Crc32<'0'>::value,
"CRC32 values don't match");
static_assert("Hello"_rcrc32 == Crc32<'H', 'e', 'l', 'l', 'o'>::value, "CRC32 values don't match");
static_assert("0"_rcrc32 == Crc32<'0'>::value, "CRC32 values don't match");
constexpr uint32_t rcrc32_rec(uint32_t crc, const char *s) { constexpr uint64_t crc64_table[] = {
return *s == 0 ? crc : 0x0000000000000000, 0x42F0E1EBA9EA3693, 0x85E1C3D753D46D26, 0xC711223CFA3E5BB5, 0x493366450E42ECDF,
crc32_rec(crc32_table[static_cast<unsigned char>(crc) ^ 0x0BC387AEA7A8DA4C, 0xCCD2A5925D9681F9, 0x8E224479F47CB76A, 0x9266CC8A1C85D9BE, 0xD0962D61B56FEF2D,
static_cast<unsigned char>(*s)] 0x17870F5D4F51B498, 0x5577EEB6E6BB820B, 0xDB55AACF12C73561, 0x99A54B24BB2D03F2, 0x5EB4691841135847,
^ (crc >> 8), s + 1); 0x1C4488F3E8F96ED4, 0x663D78FF90E185EF, 0x24CD9914390BB37C, 0xE3DCBB28C335E8C9, 0xA12C5AC36ADFDE5A,
} 0x2F0E1EBA9EA36930, 0x6DFEFF5137495FA3, 0xAAEFDD6DCD770416, 0xE81F3C86649D3285, 0xF45BB4758C645C51,
0xB6AB559E258E6AC2, 0x71BA77A2DFB03177, 0x334A9649765A07E4, 0xBD68D2308226B08E, 0xFF9833DB2BCC861D,
0x388911E7D1F2DDA8, 0x7A79F00C7818EB3B, 0xCC7AF1FF21C30BDE, 0x8E8A101488293D4D, 0x499B3228721766F8,
0x0B6BD3C3DBFD506B, 0x854997BA2F81E701, 0xC7B97651866BD192, 0x00A8546D7C558A27, 0x4258B586D5BFBCB4,
0x5E1C3D753D46D260, 0x1CECDC9E94ACE4F3, 0xDBFDFEA26E92BF46, 0x990D1F49C77889D5, 0x172F5B3033043EBF,
0x55DFBADB9AEE082C, 0x92CE98E760D05399, 0xD03E790CC93A650A, 0xAA478900B1228E31, 0xE8B768EB18C8B8A2,
0x2FA64AD7E2F6E317, 0x6D56AB3C4B1CD584, 0xE374EF45BF6062EE, 0xA1840EAE168A547D, 0x66952C92ECB40FC8,
0x2465CD79455E395B, 0x3821458AADA7578F, 0x7AD1A461044D611C, 0xBDC0865DFE733AA9, 0xFF3067B657990C3A,
0x711223CFA3E5BB50, 0x33E2C2240A0F8DC3, 0xF4F3E018F031D676, 0xB60301F359DBE0E5, 0xDA050215EA6C212F,
0x98F5E3FE438617BC, 0x5FE4C1C2B9B84C09, 0x1D14202910527A9A, 0x93366450E42ECDF0, 0xD1C685BB4DC4FB63,
0x16D7A787B7FAA0D6, 0x5427466C1E109645, 0x4863CE9FF6E9F891, 0x0A932F745F03CE02, 0xCD820D48A53D95B7,
0x8F72ECA30CD7A324, 0x0150A8DAF8AB144E, 0x43A04931514122DD, 0x84B16B0DAB7F7968, 0xC6418AE602954FFB,
0xBC387AEA7A8DA4C0, 0xFEC89B01D3679253, 0x39D9B93D2959C9E6, 0x7B2958D680B3FF75, 0xF50B1CAF74CF481F,
0xB7FBFD44DD257E8C, 0x70EADF78271B2539, 0x321A3E938EF113AA, 0x2E5EB66066087D7E, 0x6CAE578BCFE24BED,
0xABBF75B735DC1058, 0xE94F945C9C3626CB, 0x676DD025684A91A1, 0x259D31CEC1A0A732, 0xE28C13F23B9EFC87,
0xA07CF2199274CA14, 0x167FF3EACBAF2AF1, 0x548F120162451C62, 0x939E303D987B47D7, 0xD16ED1D631917144,
0x5F4C95AFC5EDC62E, 0x1DBC74446C07F0BD, 0xDAAD56789639AB08, 0x985DB7933FD39D9B, 0x84193F60D72AF34F,
0xC6E9DE8B7EC0C5DC, 0x01F8FCB784FE9E69, 0x43081D5C2D14A8FA, 0xCD2A5925D9681F90, 0x8FDAB8CE70822903,
0x48CB9AF28ABC72B6, 0x0A3B7B1923564425, 0x70428B155B4EAF1E, 0x32B26AFEF2A4998D, 0xF5A348C2089AC238,
0xB753A929A170F4AB, 0x3971ED50550C43C1, 0x7B810CBBFCE67552, 0xBC902E8706D82EE7, 0xFE60CF6CAF321874,
0xE224479F47CB76A0, 0xA0D4A674EE214033, 0x67C58448141F1B86, 0x253565A3BDF52D15, 0xAB1721DA49899A7F,
0xE9E7C031E063ACEC, 0x2EF6E20D1A5DF759, 0x6C0603E6B3B7C1CA, 0xF6FAE5C07D3274CD, 0xB40A042BD4D8425E,
0x731B26172EE619EB, 0x31EBC7FC870C2F78, 0xBFC9838573709812, 0xFD39626EDA9AAE81, 0x3A28405220A4F534,
0x78D8A1B9894EC3A7, 0x649C294A61B7AD73, 0x266CC8A1C85D9BE0, 0xE17DEA9D3263C055, 0xA38D0B769B89F6C6,
0x2DAF4F0F6FF541AC, 0x6F5FAEE4C61F773F, 0xA84E8CD83C212C8A, 0xEABE6D3395CB1A19, 0x90C79D3FEDD3F122,
0xD2377CD44439C7B1, 0x15265EE8BE079C04, 0x57D6BF0317EDAA97, 0xD9F4FB7AE3911DFD, 0x9B041A914A7B2B6E,
0x5C1538ADB04570DB, 0x1EE5D94619AF4648, 0x02A151B5F156289C, 0x4051B05E58BC1E0F, 0x87409262A28245BA,
0xC5B073890B687329, 0x4B9237F0FF14C443, 0x0962D61B56FEF2D0, 0xCE73F427ACC0A965, 0x8C8315CC052A9FF6,
0x3A80143F5CF17F13, 0x7870F5D4F51B4980, 0xBF61D7E80F251235, 0xFD913603A6CF24A6, 0x73B3727A52B393CC,
0x31439391FB59A55F, 0xF652B1AD0167FEEA, 0xB4A25046A88DC879, 0xA8E6D8B54074A6AD, 0xEA16395EE99E903E,
0x2D071B6213A0CB8B, 0x6FF7FA89BA4AFD18, 0xE1D5BEF04E364A72, 0xA3255F1BE7DC7CE1, 0x64347D271DE22754,
0x26C49CCCB40811C7, 0x5CBD6CC0CC10FAFC, 0x1E4D8D2B65FACC6F, 0xD95CAF179FC497DA, 0x9BAC4EFC362EA149,
0x158E0A85C2521623, 0x577EEB6E6BB820B0, 0x906FC95291867B05, 0xD29F28B9386C4D96, 0xCEDBA04AD0952342,
0x8C2B41A1797F15D1, 0x4B3A639D83414E64, 0x09CA82762AAB78F7, 0x87E8C60FDED7CF9D, 0xC51827E4773DF90E,
0x020905D88D03A2BB, 0x40F9E43324E99428, 0x2CFFE7D5975E55E2, 0x6E0F063E3EB46371, 0xA91E2402C48A38C4,
0xEBEEC5E96D600E57, 0x65CC8190991CB93D, 0x273C607B30F68FAE, 0xE02D4247CAC8D41B, 0xA2DDA3AC6322E288,
0xBE992B5F8BDB8C5C, 0xFC69CAB42231BACF, 0x3B78E888D80FE17A, 0x7988096371E5D7E9, 0xF7AA4D1A85996083,
0xB55AACF12C735610, 0x724B8ECDD64D0DA5, 0x30BB6F267FA73B36, 0x4AC29F2A07BFD00D, 0x08327EC1AE55E69E,
0xCF235CFD546BBD2B, 0x8DD3BD16FD818BB8, 0x03F1F96F09FD3CD2, 0x41011884A0170A41, 0x86103AB85A2951F4,
0xC4E0DB53F3C36767, 0xD8A453A01B3A09B3, 0x9A54B24BB2D03F20, 0x5D45907748EE6495, 0x1FB5719CE1045206,
0x919735E51578E56C, 0xD367D40EBC92D3FF, 0x1476F63246AC884A, 0x568617D9EF46BED9, 0xE085162AB69D5E3C,
0xA275F7C11F7768AF, 0x6564D5FDE549331A, 0x279434164CA30589, 0xA9B6706FB8DFB2E3, 0xEB46918411358470,
0x2C57B3B8EB0BDFC5, 0x6EA7525342E1E956, 0x72E3DAA0AA188782, 0x30133B4B03F2B111, 0xF7021977F9CCEAA4,
0xB5F2F89C5026DC37, 0x3BD0BCE5A45A6B5D, 0x79205D0E0DB05DCE, 0xBE317F32F78E067B, 0xFCC19ED95E6430E8,
0x86B86ED5267CDBD3, 0xC4488F3E8F96ED40, 0x0359AD0275A8B6F5, 0x41A94CE9DC428066, 0xCF8B0890283E370C,
0x8D7BE97B81D4019F, 0x4A6ACB477BEA5A2A, 0x089A2AACD2006CB9, 0x14DEA25F3AF9026D, 0x562E43B4931334FE,
0x913F6188692D6F4B, 0xD3CF8063C0C759D8, 0x5DEDC41A34BBEEB2, 0x1F1D25F19D51D821, 0xD80C07CD676F8394,
0x9AFCE626CE85B507};
constexpr uint32_t operator "" _rcrc32(const char *s, size_t len) { template <uint64_t CRC, char... Chars>
return rcrc32_rec(0xFFFFFFFF, s); struct Crc64Impl {};
}
static_assert("Hello"_rcrc32 == Crc32<'H', 'e', 'l', 'l', 'o'>::value, template <uint64_t CRC, char Head, char... Tail>
"CRC32 values don't match"); struct Crc64Impl<CRC, Head, Tail...> {
static_assert("0"_rcrc32 == Crc32<'0'>::value, static constexpr uint64_t value =
"CRC32 values don't match"); Crc64Impl<crc64_table[static_cast<unsigned char>(CRC >> 56) ^ static_cast<unsigned char>(Head)] ^ (CRC << 8),
Tail...>::value;
constexpr uint64_t crc64_table[] =
{
0x0000000000000000, 0x42F0E1EBA9EA3693, 0x85E1C3D753D46D26, 0xC711223CFA3E5BB5,
0x493366450E42ECDF, 0x0BC387AEA7A8DA4C, 0xCCD2A5925D9681F9, 0x8E224479F47CB76A,
0x9266CC8A1C85D9BE, 0xD0962D61B56FEF2D, 0x17870F5D4F51B498, 0x5577EEB6E6BB820B,
0xDB55AACF12C73561, 0x99A54B24BB2D03F2, 0x5EB4691841135847, 0x1C4488F3E8F96ED4,
0x663D78FF90E185EF, 0x24CD9914390BB37C, 0xE3DCBB28C335E8C9, 0xA12C5AC36ADFDE5A,
0x2F0E1EBA9EA36930, 0x6DFEFF5137495FA3, 0xAAEFDD6DCD770416, 0xE81F3C86649D3285,
0xF45BB4758C645C51, 0xB6AB559E258E6AC2, 0x71BA77A2DFB03177, 0x334A9649765A07E4,
0xBD68D2308226B08E, 0xFF9833DB2BCC861D, 0x388911E7D1F2DDA8, 0x7A79F00C7818EB3B,
0xCC7AF1FF21C30BDE, 0x8E8A101488293D4D, 0x499B3228721766F8, 0x0B6BD3C3DBFD506B,
0x854997BA2F81E701, 0xC7B97651866BD192, 0x00A8546D7C558A27, 0x4258B586D5BFBCB4,
0x5E1C3D753D46D260, 0x1CECDC9E94ACE4F3, 0xDBFDFEA26E92BF46, 0x990D1F49C77889D5,
0x172F5B3033043EBF, 0x55DFBADB9AEE082C, 0x92CE98E760D05399, 0xD03E790CC93A650A,
0xAA478900B1228E31, 0xE8B768EB18C8B8A2, 0x2FA64AD7E2F6E317, 0x6D56AB3C4B1CD584,
0xE374EF45BF6062EE, 0xA1840EAE168A547D, 0x66952C92ECB40FC8, 0x2465CD79455E395B,
0x3821458AADA7578F, 0x7AD1A461044D611C, 0xBDC0865DFE733AA9, 0xFF3067B657990C3A,
0x711223CFA3E5BB50, 0x33E2C2240A0F8DC3, 0xF4F3E018F031D676, 0xB60301F359DBE0E5,
0xDA050215EA6C212F, 0x98F5E3FE438617BC, 0x5FE4C1C2B9B84C09, 0x1D14202910527A9A,
0x93366450E42ECDF0, 0xD1C685BB4DC4FB63, 0x16D7A787B7FAA0D6, 0x5427466C1E109645,
0x4863CE9FF6E9F891, 0x0A932F745F03CE02, 0xCD820D48A53D95B7, 0x8F72ECA30CD7A324,
0x0150A8DAF8AB144E, 0x43A04931514122DD, 0x84B16B0DAB7F7968, 0xC6418AE602954FFB,
0xBC387AEA7A8DA4C0, 0xFEC89B01D3679253, 0x39D9B93D2959C9E6, 0x7B2958D680B3FF75,
0xF50B1CAF74CF481F, 0xB7FBFD44DD257E8C, 0x70EADF78271B2539, 0x321A3E938EF113AA,
0x2E5EB66066087D7E, 0x6CAE578BCFE24BED, 0xABBF75B735DC1058, 0xE94F945C9C3626CB,
0x676DD025684A91A1, 0x259D31CEC1A0A732, 0xE28C13F23B9EFC87, 0xA07CF2199274CA14,
0x167FF3EACBAF2AF1, 0x548F120162451C62, 0x939E303D987B47D7, 0xD16ED1D631917144,
0x5F4C95AFC5EDC62E, 0x1DBC74446C07F0BD, 0xDAAD56789639AB08, 0x985DB7933FD39D9B,
0x84193F60D72AF34F, 0xC6E9DE8B7EC0C5DC, 0x01F8FCB784FE9E69, 0x43081D5C2D14A8FA,
0xCD2A5925D9681F90, 0x8FDAB8CE70822903, 0x48CB9AF28ABC72B6, 0x0A3B7B1923564425,
0x70428B155B4EAF1E, 0x32B26AFEF2A4998D, 0xF5A348C2089AC238, 0xB753A929A170F4AB,
0x3971ED50550C43C1, 0x7B810CBBFCE67552, 0xBC902E8706D82EE7, 0xFE60CF6CAF321874,
0xE224479F47CB76A0, 0xA0D4A674EE214033, 0x67C58448141F1B86, 0x253565A3BDF52D15,
0xAB1721DA49899A7F, 0xE9E7C031E063ACEC, 0x2EF6E20D1A5DF759, 0x6C0603E6B3B7C1CA,
0xF6FAE5C07D3274CD, 0xB40A042BD4D8425E, 0x731B26172EE619EB, 0x31EBC7FC870C2F78,
0xBFC9838573709812, 0xFD39626EDA9AAE81, 0x3A28405220A4F534, 0x78D8A1B9894EC3A7,
0x649C294A61B7AD73, 0x266CC8A1C85D9BE0, 0xE17DEA9D3263C055, 0xA38D0B769B89F6C6,
0x2DAF4F0F6FF541AC, 0x6F5FAEE4C61F773F, 0xA84E8CD83C212C8A, 0xEABE6D3395CB1A19,
0x90C79D3FEDD3F122, 0xD2377CD44439C7B1, 0x15265EE8BE079C04, 0x57D6BF0317EDAA97,
0xD9F4FB7AE3911DFD, 0x9B041A914A7B2B6E, 0x5C1538ADB04570DB, 0x1EE5D94619AF4648,
0x02A151B5F156289C, 0x4051B05E58BC1E0F, 0x87409262A28245BA, 0xC5B073890B687329,
0x4B9237F0FF14C443, 0x0962D61B56FEF2D0, 0xCE73F427ACC0A965, 0x8C8315CC052A9FF6,
0x3A80143F5CF17F13, 0x7870F5D4F51B4980, 0xBF61D7E80F251235, 0xFD913603A6CF24A6,
0x73B3727A52B393CC, 0x31439391FB59A55F, 0xF652B1AD0167FEEA, 0xB4A25046A88DC879,
0xA8E6D8B54074A6AD, 0xEA16395EE99E903E, 0x2D071B6213A0CB8B, 0x6FF7FA89BA4AFD18,
0xE1D5BEF04E364A72, 0xA3255F1BE7DC7CE1, 0x64347D271DE22754, 0x26C49CCCB40811C7,
0x5CBD6CC0CC10FAFC, 0x1E4D8D2B65FACC6F, 0xD95CAF179FC497DA, 0x9BAC4EFC362EA149,
0x158E0A85C2521623, 0x577EEB6E6BB820B0, 0x906FC95291867B05, 0xD29F28B9386C4D96,
0xCEDBA04AD0952342, 0x8C2B41A1797F15D1, 0x4B3A639D83414E64, 0x09CA82762AAB78F7,
0x87E8C60FDED7CF9D, 0xC51827E4773DF90E, 0x020905D88D03A2BB, 0x40F9E43324E99428,
0x2CFFE7D5975E55E2, 0x6E0F063E3EB46371, 0xA91E2402C48A38C4, 0xEBEEC5E96D600E57,
0x65CC8190991CB93D, 0x273C607B30F68FAE, 0xE02D4247CAC8D41B, 0xA2DDA3AC6322E288,
0xBE992B5F8BDB8C5C, 0xFC69CAB42231BACF, 0x3B78E888D80FE17A, 0x7988096371E5D7E9,
0xF7AA4D1A85996083, 0xB55AACF12C735610, 0x724B8ECDD64D0DA5, 0x30BB6F267FA73B36,
0x4AC29F2A07BFD00D, 0x08327EC1AE55E69E, 0xCF235CFD546BBD2B, 0x8DD3BD16FD818BB8,
0x03F1F96F09FD3CD2, 0x41011884A0170A41, 0x86103AB85A2951F4, 0xC4E0DB53F3C36767,
0xD8A453A01B3A09B3, 0x9A54B24BB2D03F20, 0x5D45907748EE6495, 0x1FB5719CE1045206,
0x919735E51578E56C, 0xD367D40EBC92D3FF, 0x1476F63246AC884A, 0x568617D9EF46BED9,
0xE085162AB69D5E3C, 0xA275F7C11F7768AF, 0x6564D5FDE549331A, 0x279434164CA30589,
0xA9B6706FB8DFB2E3, 0xEB46918411358470, 0x2C57B3B8EB0BDFC5, 0x6EA7525342E1E956,
0x72E3DAA0AA188782, 0x30133B4B03F2B111, 0xF7021977F9CCEAA4, 0xB5F2F89C5026DC37,
0x3BD0BCE5A45A6B5D, 0x79205D0E0DB05DCE, 0xBE317F32F78E067B, 0xFCC19ED95E6430E8,
0x86B86ED5267CDBD3, 0xC4488F3E8F96ED40, 0x0359AD0275A8B6F5, 0x41A94CE9DC428066,
0xCF8B0890283E370C, 0x8D7BE97B81D4019F, 0x4A6ACB477BEA5A2A, 0x089A2AACD2006CB9,
0x14DEA25F3AF9026D, 0x562E43B4931334FE, 0x913F6188692D6F4B, 0xD3CF8063C0C759D8,
0x5DEDC41A34BBEEB2, 0x1F1D25F19D51D821, 0xD80C07CD676F8394, 0x9AFCE626CE85B507
}; };
template<uint64_t CRC, char ...Chars> struct Crc64Impl { template <uint64_t CRC>
}; struct Crc64Impl<CRC> {
template<uint64_t CRC, char Head, char ...Tail> struct Crc64Impl<CRC, Head, Tail...> {
static constexpr uint64_t value = Crc64Impl<
crc64_table[static_cast<unsigned char>(CRC >> 56) ^ static_cast<unsigned char>(Head)]
^ (CRC << 8), Tail...>::value;
};
template<uint64_t CRC> struct Crc64Impl<CRC> {
static constexpr uint64_t value = CRC ^ 0xFFFFFFFFFFFFFFFF; static constexpr uint64_t value = CRC ^ 0xFFFFFFFFFFFFFFFF;
}; };
template <char... Chars>
using Crc64 = Crc64Impl<0xFFFFFFFFFFFFFFFF, Chars...>;
template<char ...Chars> using Crc64 = Crc64Impl<0xFFFFFFFFFFFFFFFF, Chars...>; constexpr uint64_t crc64_rec(uint64_t crc, const char* s) {
return *s == 0 ? crc ^ 0xFFFFFFFFFFFFFFFF
constexpr uint64_t crc64_rec(uint64_t crc, const char *s) { : crc64_rec(crc64_table[static_cast<unsigned char>(crc >> 56) ^ static_cast<unsigned char>(*s)] ^
return *s == 0 ? crc ^ 0xFFFFFFFFFFFFFFFF : (crc << 8),
crc64_rec(crc64_table[static_cast<unsigned char>(crc >> 56) ^ s + 1);
static_cast<unsigned char>(*s)]
^ (crc << 8), s + 1);
} }
constexpr uint64_t operator "" _crc64(const char *s, size_t len) { constexpr uint64_t operator"" _crc64(const char* s, size_t len) { return crc64_rec(0xFFFFFFFFFFFFFFFF, s); }
return crc64_rec(0xFFFFFFFFFFFFFFFF, s);
}
static_assert("Hello"_crc64 == Crc64<'H', 'e', 'l', 'l', 'o'>::value,
"CRC64 values don't match");
static_assert("0"_crc64 == Crc64<'0'>::value,
"CRC64 values don't match");
}
static_assert("Hello"_crc64 == Crc64<'H', 'e', 'l', 'l', 'o'>::value, "CRC64 values don't match");
static_assert("0"_crc64 == Crc64<'0'>::value, "CRC64 values don't match");
} // namespace athena::checksums::literals

View File

@ -2,8 +2,7 @@
#include "athena/Global.hpp" #include "athena/Global.hpp"
namespace athena::io::Compression namespace athena::io::Compression {
{
// Zlib compression // Zlib compression
atInt32 decompressZlib(const atUint8* src, atUint32 srcLen, atUint8* dst, atUint32 dstLen); atInt32 decompressZlib(const atUint8* src, atUint32 srcLen, atUint8* dst, atUint32 dstLen);
atInt32 compressZlib(const atUint8* src, atUint32 srcLen, atUint8* dst, atUint32 dstLen); atInt32 compressZlib(const atUint8* src, atUint32 srcLen, atUint8* dst, atUint32 dstLen);
@ -17,4 +16,4 @@ atUint32 yaz0Encode(const atUint8* src, atUint32 srcSize, atUint8* data);
atUint32 decompressLZ77(const atUint8* src, atUint32 srcLen, atUint8** dst); atUint32 decompressLZ77(const atUint8* src, atUint32 srcLen, atUint8** dst);
atUint32 compressLZ77(const atUint8* src, atUint32 srcLen, atUint8** dst, bool extended = false); atUint32 compressLZ77(const atUint8* src, atUint32 srcLen, atUint8** dst, bool extended = false);
} } // namespace athena::io::Compression

View File

@ -13,8 +13,7 @@
#include <vector> #include <vector>
#include <memory> #include <memory>
namespace athena::io namespace athena::io {
{
/** /**
* @brief Base DNA class used against 'atdna' * @brief Base DNA class used against 'atdna'
@ -26,8 +25,7 @@ namespace athena::io
* a streamed medium * a streamed medium
*/ */
template <Endian DNAE> template <Endian DNAE>
struct DNA struct DNA {
{
/** /**
* @brief Designated byte-order used for serializing fields * @brief Designated byte-order used for serializing fields
*/ */
@ -120,8 +118,7 @@ struct DNA
* { (Do stuff with `r`) } * { (Do stuff with `r`) }
*/ */
template <Endian DNAE> template <Endian DNAE>
struct DNAV : DNA<DNAE> struct DNAV : DNA<DNAE> {
{
virtual ~DNAV() = default; virtual ~DNAV() = default;
virtual void read(athena::io::IStreamReader& r) = 0; virtual void read(athena::io::IStreamReader& r) = 0;
virtual void write(athena::io::IStreamWriter& w) const = 0; virtual void write(athena::io::IStreamWriter& w) const = 0;
@ -130,8 +127,7 @@ struct DNAV : DNA<DNAE>
}; };
template <Endian DNAE> template <Endian DNAE>
struct DNAVYaml : DNAV<DNAE> struct DNAVYaml : DNAV<DNAE> {
{
virtual ~DNAVYaml() = default; virtual ~DNAVYaml() = default;
virtual void read(athena::io::IStreamReader& r) = 0; virtual void read(athena::io::IStreamReader& r) = 0;
virtual void write(athena::io::IStreamWriter& w) const = 0; virtual void write(athena::io::IStreamWriter& w) const = 0;
@ -147,6 +143,4 @@ struct DNAVYaml : DNAV<DNAE>
#define AT_DNA_COUNT(cnt) 0 #define AT_DNA_COUNT(cnt) 0
#endif #endif
} } // namespace athena::io

File diff suppressed because it is too large Load Diff

View File

@ -6,26 +6,20 @@
#include "FileReader.hpp" #include "FileReader.hpp"
#include "FileWriter.hpp" #include "FileWriter.hpp"
namespace athena::io namespace athena::io {
{
template <class T> template <class T>
static inline const char* __GetDNAName(const T& dna, static inline const char* __GetDNAName(const T& dna, typename std::enable_if_t<athena::io::__IsDNAVRecord_v<T>>* = 0) {
typename std::enable_if_t<athena::io::__IsDNAVRecord_v<T>>* = 0)
{
return dna.DNATypeV(); return dna.DNATypeV();
} }
template <class T> template <class T>
static inline const char* __GetDNAName(const T& dna, static inline const char* __GetDNAName(const T& dna, typename std::enable_if_t<!athena::io::__IsDNAVRecord_v<T>>* = 0) {
typename std::enable_if_t<!athena::io::__IsDNAVRecord_v<T>>* = 0)
{
return dna.DNAType(); return dna.DNAType();
} }
template <class T> template <class T>
static inline std::string ToYAMLString(const T& dna) static inline std::string ToYAMLString(const T& dna) {
{
YAMLDocWriter docWriter(__GetDNAName(dna)); YAMLDocWriter docWriter(__GetDNAName(dna));
std::string res; std::string res;
@ -41,8 +35,7 @@ static inline std::string ToYAMLString(const T& dna)
} }
template <class T> template <class T>
static inline bool FromYAMLString(T& dna, std::string_view str) static inline bool FromYAMLString(T& dna, std::string_view str) {
{
YAMLStdStringViewReaderState reader(str); YAMLStdStringViewReaderState reader(str);
YAMLDocReader docReader; YAMLDocReader docReader;
yaml_parser_set_input(docReader.getParser(), (yaml_read_handler_t*)YAMLStdStringReader, &reader); yaml_parser_set_input(docReader.getParser(), (yaml_read_handler_t*)YAMLStdStringReader, &reader);
@ -52,9 +45,8 @@ static inline bool FromYAMLString(T& dna, std::string_view str)
return true; return true;
} }
template<class DNASubtype> template <class DNASubtype>
static inline bool ValidateFromYAMLString(std::string_view str) static inline bool ValidateFromYAMLString(std::string_view str) {
{
YAMLStdStringViewReaderState reader(str); YAMLStdStringViewReaderState reader(str);
YAMLDocReader docReader; YAMLDocReader docReader;
yaml_parser_set_input(docReader.getParser(), (yaml_read_handler_t*)YAMLStdStringReader, &reader); yaml_parser_set_input(docReader.getParser(), (yaml_read_handler_t*)YAMLStdStringReader, &reader);
@ -63,8 +55,7 @@ static inline bool ValidateFromYAMLString(std::string_view str)
} }
template <class T> template <class T>
static inline bool ToYAMLStream(const T& dna, athena::io::IStreamWriter& fout) static inline bool ToYAMLStream(const T& dna, athena::io::IStreamWriter& fout) {
{
YAMLDocWriter docWriter(__GetDNAName(dna)); YAMLDocWriter docWriter(__GetDNAName(dna));
yaml_emitter_set_unicode(docWriter.getEmitter(), true); yaml_emitter_set_unicode(docWriter.getEmitter(), true);
@ -76,8 +67,7 @@ static inline bool ToYAMLStream(const T& dna, athena::io::IStreamWriter& fout)
template <class T> template <class T>
static inline bool ToYAMLStream(const T& dna, athena::io::IStreamWriter& fout, static inline bool ToYAMLStream(const T& dna, athena::io::IStreamWriter& fout,
void(T::*fn)(YAMLDocWriter& out)const) void (T::*fn)(YAMLDocWriter& out) const) {
{
YAMLDocWriter docWriter(__GetDNAName(dna)); YAMLDocWriter docWriter(__GetDNAName(dna));
yaml_emitter_set_unicode(docWriter.getEmitter(), true); yaml_emitter_set_unicode(docWriter.getEmitter(), true);
@ -88,8 +78,7 @@ static inline bool ToYAMLStream(const T& dna, athena::io::IStreamWriter& fout,
} }
template <class T> template <class T>
static inline bool FromYAMLStream(T& dna, athena::io::IStreamReader& fin) static inline bool FromYAMLStream(T& dna, athena::io::IStreamReader& fin) {
{
YAMLDocReader docReader; YAMLDocReader docReader;
if (!docReader.parse(&fin)) if (!docReader.parse(&fin))
return false; return false;
@ -98,9 +87,7 @@ static inline bool FromYAMLStream(T& dna, athena::io::IStreamReader& fin)
} }
template <class T> template <class T>
static inline bool FromYAMLStream(T& dna, athena::io::IStreamReader& fin, static inline bool FromYAMLStream(T& dna, athena::io::IStreamReader& fin, void (T::*fn)(YAMLDocReader& in)) {
void(T::*fn)(YAMLDocReader& in))
{
YAMLDocReader docReader; YAMLDocReader docReader;
if (!docReader.parse(&fin)) if (!docReader.parse(&fin))
return false; return false;
@ -109,8 +96,7 @@ static inline bool FromYAMLStream(T& dna, athena::io::IStreamReader& fin,
} }
template <class T, typename NameT> template <class T, typename NameT>
static inline bool MergeToYAMLFile(const T& dna, const NameT& filename) static inline bool MergeToYAMLFile(const T& dna, const NameT& filename) {
{
athena::io::FileReader r(filename); athena::io::FileReader r(filename);
YAMLDocWriter docWriter(__GetDNAName(dna), r.isOpen() ? &r : nullptr); YAMLDocWriter docWriter(__GetDNAName(dna), r.isOpen() ? &r : nullptr);
r.close(); r.close();
@ -123,8 +109,7 @@ static inline bool MergeToYAMLFile(const T& dna, const NameT& filename)
} }
template <class DNASubtype> template <class DNASubtype>
static inline bool ValidateFromYAMLStream(athena::io::IStreamReader& fin) static inline bool ValidateFromYAMLStream(athena::io::IStreamReader& fin) {
{
YAMLDocReader reader; YAMLDocReader reader;
atUint64 pos = fin.position(); atUint64 pos = fin.position();
yaml_parser_set_input(reader.getParser(), (yaml_read_handler_t*)YAMLAthenaReader, &fin); yaml_parser_set_input(reader.getParser(), (yaml_read_handler_t*)YAMLAthenaReader, &fin);
@ -133,5 +118,4 @@ static inline bool ValidateFromYAMLStream(athena::io::IStreamReader& fin)
return retval; return retval;
} }
} } // namespace athena::io

View File

@ -8,20 +8,16 @@
typedef int mode_t; typedef int mode_t;
#endif #endif
namespace athena namespace athena {
{ class Dir {
class Dir
{
public: public:
explicit Dir(std::string_view path); explicit Dir(std::string_view path);
std::string absolutePath() const; std::string absolutePath() const;
static inline std::string absolutePath(std::string_view path) static inline std::string absolutePath(std::string_view path) { return Dir(path).absolutePath(); }
{ return Dir(path).absolutePath(); }
bool isDir() const; bool isDir() const;
static bool isDir(std::string_view dir) static bool isDir(std::string_view dir) { return Dir(dir).isDir(); }
{ return Dir(dir).isDir(); }
std::vector<FileInfo> files() const; std::vector<FileInfo> files() const;
@ -30,8 +26,8 @@ public:
bool touch(); bool touch();
static bool mkdir(std::string_view dir, mode_t mode = 0755); static bool mkdir(std::string_view dir, mode_t mode = 0755);
static bool mkpath(std::string_view path, mode_t mode = 0755); static bool mkpath(std::string_view path, mode_t mode = 0755);
private: private:
std::string m_path; std::string m_path;
}; };
} } // namespace athena

View File

@ -4,54 +4,41 @@
#include "athena/Global.hpp" #include "athena/Global.hpp"
namespace athena namespace athena {
{ class FileInfo {
class FileInfo
{
public: public:
explicit FileInfo(std::string_view path = {}); explicit FileInfo(std::string_view path = {});
std::string absolutePath() const; std::string absolutePath() const;
static inline std::string absolutePath(std::string_view lnk) static inline std::string absolutePath(std::string_view lnk) { return FileInfo(lnk).absolutePath(); }
{ return FileInfo(lnk).absolutePath(); }
std::string absoluteFilePath() const; std::string absoluteFilePath() const;
static inline std::string absoluteFilePath(std::string_view path) static inline std::string absoluteFilePath(std::string_view path) { return FileInfo(path).absoluteFilePath(); }
{ return FileInfo(path).absoluteFilePath(); }
std::string filename() const; std::string filename() const;
static inline std::string filename(std::string_view path) static inline std::string filename(std::string_view path) { return FileInfo(path).filename(); }
{ return FileInfo(path).filename(); }
std::string path() const { return m_path; } std::string path() const { return m_path; }
static inline std::string path(std::string_view path) static inline std::string path(std::string_view path) { return FileInfo(path).path(); }
{ return FileInfo(path).path(); }
std::string extension() const; std::string extension() const;
static inline std::string extension(std::string_view path) static inline std::string extension(std::string_view path) { return FileInfo(path).extension(); }
{ return FileInfo(path).extension(); }
atUint64 size() const; atUint64 size() const;
static inline atUint64 size(std::string_view path) static inline atUint64 size(std::string_view path) { return FileInfo(path).size(); }
{ return FileInfo(path).size(); }
bool exists() const; bool exists() const;
static inline bool exists(std::string_view path) static inline bool exists(std::string_view path) { return FileInfo(path).exists(); }
{ return FileInfo(path).exists(); }
bool isLink() const; bool isLink() const;
static inline bool isLink(std::string_view lnk) static inline bool isLink(std::string_view lnk) { return FileInfo(lnk).isLink(); }
{ return FileInfo(lnk).isLink(); }
bool isFile() const; bool isFile() const;
static inline bool isFile(std::string_view path) static inline bool isFile(std::string_view path) { return FileInfo(path).isFile(); }
{ return FileInfo(path).isFile(); }
bool touch() const; bool touch() const;
static inline bool touch(std::string_view path) static inline bool touch(std::string_view path) { return FileInfo(path).touch(); }
{ return FileInfo(path).touch(); }
private: private:
std::string m_path; std::string m_path;
}; };
} } // namespace athena

View File

@ -13,17 +13,14 @@
#include <memory> #include <memory>
#include "athena/IStreamReader.hpp" #include "athena/IStreamReader.hpp"
namespace athena::io namespace athena::io {
{ class FileReader : public IStreamReader {
class FileReader : public IStreamReader
{
public: public:
FileReader(std::string_view filename, atInt32 cacheSize = (32 * 1024), bool globalErr=true); FileReader(std::string_view filename, atInt32 cacheSize = (32 * 1024), bool globalErr = true);
FileReader(std::wstring_view filename, atInt32 cacheSize = (32 * 1024), bool globalErr=true); FileReader(std::wstring_view filename, atInt32 cacheSize = (32 * 1024), bool globalErr = true);
virtual ~FileReader(); virtual ~FileReader();
inline std::string filename() const inline std::string filename() const {
{
#if _WIN32 #if _WIN32
return utility::wideToUtf8(m_filename); return utility::wideToUtf8(m_filename);
#else #else
@ -31,8 +28,7 @@ public:
#endif #endif
} }
inline std::wstring wfilename() const inline std::wstring wfilename() const {
{
#if _WIN32 #if _WIN32
return m_filename; return m_filename;
#else #else
@ -42,8 +38,7 @@ public:
void open(); void open();
void close(); void close();
inline bool isOpen() const inline bool isOpen() const { return m_fileHandle != 0; }
{return m_fileHandle != 0;}
bool save(); bool save();
void seek(atInt64 pos, SeekOrigin origin = SeekOrigin::Current); void seek(atInt64 pos, SeekOrigin origin = SeekOrigin::Current);
atUint64 position() const; atUint64 position() const;
@ -58,7 +53,8 @@ public:
using HandleType = FILE*; using HandleType = FILE*;
#endif #endif
HandleType _fileHandle() {return m_fileHandle;} HandleType _fileHandle() { return m_fileHandle; }
protected: protected:
#if _WIN32 #if _WIN32
std::wstring m_filename; std::wstring m_filename;
@ -72,7 +68,7 @@ protected:
atUint64 m_offset; atUint64 m_offset;
bool m_globalErr; bool m_globalErr;
}; };
} // Athena } // namespace athena::io
#ifndef FILEREADER_BASE #ifndef FILEREADER_BASE
#define FILEREADER_BASE() \ #define FILEREADER_BASE() \
@ -80,4 +76,3 @@ private: \
typedef athena::io::FileReader base typedef athena::io::FileReader base
#endif // FILEREADER_BASE #endif // FILEREADER_BASE

View File

@ -10,25 +10,21 @@
#endif #endif
#include "athena/IStreamWriter.hpp" #include "athena/IStreamWriter.hpp"
namespace athena::io namespace athena::io {
{ class FileWriter : public IStreamWriter {
class FileWriter : public IStreamWriter
{
public: public:
FileWriter(std::string_view filename, bool overwrite = true, bool globalErr=true); FileWriter(std::string_view filename, bool overwrite = true, bool globalErr = true);
FileWriter(std::wstring_view filename, bool overwrite = true, bool globalErr=true); FileWriter(std::wstring_view filename, bool overwrite = true, bool globalErr = true);
virtual ~FileWriter(); virtual ~FileWriter();
inline std::string filename() const inline std::string filename() const {
{
#if _WIN32 #if _WIN32
return utility::wideToUtf8(m_filename); return utility::wideToUtf8(m_filename);
#else #else
return m_filename; return m_filename;
#endif #endif
} }
inline std::wstring wfilename() const inline std::wstring wfilename() const {
{
#if _WIN32 #if _WIN32
return m_filename; return m_filename;
#else #else
@ -38,8 +34,7 @@ public:
void open(bool overwrite = true); void open(bool overwrite = true);
void close(); void close();
inline bool isOpen() const inline bool isOpen() const { return m_fileHandle != 0; }
{return m_fileHandle != 0;}
void seek(atInt64 pos, SeekOrigin origin = SeekOrigin::Current); void seek(atInt64 pos, SeekOrigin origin = SeekOrigin::Current);
atUint64 position() const; atUint64 position() const;
atUint64 length() const; atUint64 length() const;
@ -51,7 +46,8 @@ public:
using HandleType = FILE*; using HandleType = FILE*;
#endif #endif
HandleType _fileHandle() {return m_fileHandle;} HandleType _fileHandle() { return m_fileHandle; }
private: private:
#if _WIN32 #if _WIN32
std::wstring m_filename; std::wstring m_filename;
@ -62,8 +58,7 @@ private:
bool m_globalErr; bool m_globalErr;
}; };
class TransactionalFileWriter : public IStreamWriter class TransactionalFileWriter : public IStreamWriter {
{
#if _WIN32 #if _WIN32
std::wstring m_filename; std::wstring m_filename;
#else #else
@ -72,19 +67,18 @@ class TransactionalFileWriter : public IStreamWriter
bool m_overwrite, m_globalErr; bool m_overwrite, m_globalErr;
std::vector<uint8_t> m_deferredBuffer; std::vector<uint8_t> m_deferredBuffer;
atUint64 m_position = 0; atUint64 m_position = 0;
public: public:
TransactionalFileWriter(std::string_view filename, bool overwrite = true, bool globalErr=true) TransactionalFileWriter(std::string_view filename, bool overwrite = true, bool globalErr = true)
: m_overwrite(overwrite), m_globalErr(globalErr) : m_overwrite(overwrite), m_globalErr(globalErr) {
{
#if _WIN32 #if _WIN32
m_filename = utility::utf8ToWide(filename); m_filename = utility::utf8ToWide(filename);
#else #else
m_filename = filename; m_filename = filename;
#endif #endif
} }
TransactionalFileWriter(std::wstring_view filename, bool overwrite = true, bool globalErr=true) TransactionalFileWriter(std::wstring_view filename, bool overwrite = true, bool globalErr = true)
: m_overwrite(overwrite), m_globalErr(globalErr) : m_overwrite(overwrite), m_globalErr(globalErr) {
{
#if _WIN32 #if _WIN32
m_filename = filename; m_filename = filename;
#else #else
@ -92,17 +86,18 @@ public:
#endif #endif
} }
void flush() void flush() {
{ if (m_deferredBuffer.size()) {
if (m_deferredBuffer.size())
{
FileWriter w(m_filename, m_overwrite, m_globalErr); FileWriter w(m_filename, m_overwrite, m_globalErr);
w.writeUBytes(m_deferredBuffer.data(), m_deferredBuffer.size()); w.writeUBytes(m_deferredBuffer.data(), m_deferredBuffer.size());
cancel(); cancel();
} }
} }
void cancel() { m_deferredBuffer.clear(); m_position = 0; } void cancel() {
m_deferredBuffer.clear();
m_position = 0;
}
inline atUint64 position() const { return m_position; } inline atUint64 position() const { return m_position; }
inline atUint64 length() const { return m_deferredBuffer.size(); } inline atUint64 length() const { return m_deferredBuffer.size(); }
@ -111,7 +106,7 @@ public:
~TransactionalFileWriter() { flush(); } ~TransactionalFileWriter() { flush(); }
}; };
} // Athena } // namespace athena::io
#ifndef FILEWRITER_BASE #ifndef FILEWRITER_BASE
#define FILEWRITER_BASE() \ #define FILEWRITER_BASE() \

View File

@ -82,80 +82,57 @@ typedef struct stat64 atStat64_t;
#ifndef ENABLE_BITWISE_ENUM #ifndef ENABLE_BITWISE_ENUM
#define ENABLE_BITWISE_ENUM(type) \ #define ENABLE_BITWISE_ENUM(type) \
constexpr type operator|(type a, type b) \ constexpr type operator|(type a, type b) { \
{ \
using T = std::underlying_type_t<type>; \ using T = std::underlying_type_t<type>; \
return type(static_cast<T>(a) | static_cast<T>(b)); \ return type(static_cast<T>(a) | static_cast<T>(b)); \
} \ } \
constexpr type operator&(type a, type b) \ constexpr type operator&(type a, type b) { \
{ \
using T = std::underlying_type_t<type>; \ using T = std::underlying_type_t<type>; \
return type(static_cast<T>(a) & static_cast<T>(b)); \ return type(static_cast<T>(a) & static_cast<T>(b)); \
} \ } \
inline type& operator|=(type& a, const type& b) \ inline type& operator|=(type& a, const type& b) { \
{ \
using T = std::underlying_type_t<type>; \ using T = std::underlying_type_t<type>; \
a = type(static_cast<T>(a) | static_cast<T>(b)); \ a = type(static_cast<T>(a) | static_cast<T>(b)); \
return a; \ return a; \
} \ } \
inline type& operator&=(type& a, const type& b) \ inline type& operator&=(type& a, const type& b) { \
{ \
using T = std::underlying_type_t<type>; \ using T = std::underlying_type_t<type>; \
a = type(static_cast<T>(a) & static_cast<T>(b)); \ a = type(static_cast<T>(a) & static_cast<T>(b)); \
return a; \ return a; \
} \ } \
inline type operator~(const type& key) \ inline type operator~(const type& key) { \
{ \
using T = std::underlying_type_t<type>; \ using T = std::underlying_type_t<type>; \
return type(~static_cast<T>(key)); \ return type(~static_cast<T>(key)); \
} }
#endif #endif
namespace athena namespace athena {
{ namespace error {
namespace error enum class Level { Message, Warning, Error, Fatal };
{
enum class Level
{
Message,
Warning,
Error,
Fatal
};
} }
enum SeekOrigin enum SeekOrigin { Begin, Current, End };
{
Begin,
Current,
End
};
enum Endian enum Endian { Little, Big };
{
Little,
Big
};
namespace io namespace io {
{
template <Endian DNAE> template <Endian DNAE>
struct DNA; struct DNA;
template <Endian DNAE> template <Endian DNAE>
struct DNAV; struct DNAV;
template <class T> template <class T>
using __IsDNARecord = typename std::disjunction<std::is_base_of<DNA<Endian::Big>, T>, using __IsDNARecord =
std::is_base_of<DNA<Endian::Little>, T>>; typename std::disjunction<std::is_base_of<DNA<Endian::Big>, T>, std::is_base_of<DNA<Endian::Little>, T>>;
template <class T> template <class T>
inline constexpr bool __IsDNARecord_v = __IsDNARecord<T>::value; inline constexpr bool __IsDNARecord_v = __IsDNARecord<T>::value;
template <class T> template <class T>
using __IsDNAVRecord = typename std::disjunction<std::is_base_of<DNAV<Endian::Big>, T>, using __IsDNAVRecord =
std::is_base_of<DNAV<Endian::Little>, T>>; typename std::disjunction<std::is_base_of<DNAV<Endian::Big>, T>, std::is_base_of<DNAV<Endian::Little>, T>>;
template <class T> template <class T>
inline constexpr bool __IsDNAVRecord_v = __IsDNAVRecord<T>::value; inline constexpr bool __IsDNAVRecord_v = __IsDNAVRecord<T>::value;
} } // namespace io
} // Athena } // namespace athena
typedef void (*atEXCEPTION_HANDLER)(athena::error::Level level, const char* file, const char* function, int line, typedef void (*atEXCEPTION_HANDLER)(athena::error::Level level, const char* file, const char* function, int line,
const char* fmt, ...); const char* fmt, ...);
@ -173,8 +150,7 @@ std::ostream& operator<<(std::ostream& os, const athena::Endian& endian);
#ifdef _MSC_VER #ifdef _MSC_VER
#ifndef NDEBUG #ifndef NDEBUG
#define atDebug(fmt, ...) \ #define atDebug(fmt, ...) \
do \ do { \
{ \
atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \ atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \ if (__handler) \
__handler(athena::error::Level::Message, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt, ##__VA_ARGS__); \ __handler(athena::error::Level::Message, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt, ##__VA_ARGS__); \
@ -184,32 +160,28 @@ std::ostream& operator<<(std::ostream& os, const athena::Endian& endian);
#endif #endif
#define atMessage(fmt, ...) \ #define atMessage(fmt, ...) \
do \ do { \
{ \
atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \ atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \ if (__handler) \
__handler(athena::error::Level::Message, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt, ##__VA_ARGS__); \ __handler(athena::error::Level::Message, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt, ##__VA_ARGS__); \
} while (0) } while (0)
#define atWarning(fmt, ...) \ #define atWarning(fmt, ...) \
do \ do { \
{ \
atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \ atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \ if (__handler) \
__handler(athena::error::Level::Warning, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt, ##__VA_ARGS__); \ __handler(athena::error::Level::Warning, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt, ##__VA_ARGS__); \
} while (0) } while (0)
#define atError(fmt, ...) \ #define atError(fmt, ...) \
do \ do { \
{ \
atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \ atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \ if (__handler) \
__handler(athena::error::Level::Error, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt, ##__VA_ARGS__); \ __handler(athena::error::Level::Error, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt, ##__VA_ARGS__); \
} while (0) } while (0)
#define atFatal(fmt, ...) \ #define atFatal(fmt, ...) \
do \ do { \
{ \
atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \ atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \ if (__handler) \
__handler(athena::error::Level::Fatal, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt, ##__VA_ARGS__); \ __handler(athena::error::Level::Fatal, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt, ##__VA_ARGS__); \
@ -218,8 +190,7 @@ std::ostream& operator<<(std::ostream& os, const athena::Endian& endian);
#ifndef NDEBUG #ifndef NDEBUG
#define atDebug(fmt...) \ #define atDebug(fmt...) \
do \ do { \
{ \
atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \ atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \ if (__handler) \
__handler(athena::error::Level::Message, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt); \ __handler(athena::error::Level::Message, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt); \
@ -229,35 +200,30 @@ std::ostream& operator<<(std::ostream& os, const athena::Endian& endian);
#endif // NDEBUG #endif // NDEBUG
#define atMessage(fmt...) \ #define atMessage(fmt...) \
do \ do { \
{ \
atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \ atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \ if (__handler) \
__handler(athena::error::Level::Message, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt); \ __handler(athena::error::Level::Message, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt); \
} while (0) } while (0)
#define atWarning(fmt...) \ #define atWarning(fmt...) \
do \ do { \
{ \
atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \ atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \ if (__handler) \
__handler(athena::error::Level::Warning, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt); \ __handler(athena::error::Level::Warning, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt); \
} while (0) } while (0)
#define atError(fmt...) \ #define atError(fmt...) \
do \ do { \
{ \
atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \ atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \ if (__handler) \
__handler(athena::error::Level::Error, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt); \ __handler(athena::error::Level::Error, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt); \
} while (0) } while (0)
#define atFatal(fmt...) \ #define atFatal(fmt...) \
do \ do { \
{ \
atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \ atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \ if (__handler) \
__handler(athena::error::Level::Fatal, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt); \ __handler(athena::error::Level::Fatal, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt); \
} while (0) } while (0)
#endif // defined(__GNUC__) #endif // defined(__GNUC__)

View File

@ -2,12 +2,10 @@
#include "Global.hpp" #include "Global.hpp"
namespace athena::io namespace athena::io {
{
std::ostream& operator<<(std::ostream& os, Endian& endian); std::ostream& operator<<(std::ostream& os, Endian& endian);
class IStream class IStream {
{
public: public:
virtual ~IStream() = default; virtual ~IStream() = default;
@ -20,6 +18,7 @@ public:
virtual atUint64 position() const = 0; virtual atUint64 position() const = 0;
virtual atUint64 length() const = 0; virtual atUint64 length() const = 0;
bool hasError() const { return m_hasError; } bool hasError() const { return m_hasError; }
protected: protected:
void setError() { m_hasError = true; } void setError() { m_hasError = true; }
bool m_hasError = false; bool m_hasError = false;
@ -29,4 +28,4 @@ protected:
Endian m_endian = Little; Endian m_endian = Little;
#endif #endif
}; };
} } // namespace athena::io

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2,8 +2,7 @@
#include "athena/Global.hpp" #include "athena/Global.hpp"
namespace athena namespace athena {
{
class MCSlot; class MCSlot;
/*! \class MCFile /*! \class MCFile
@ -12,23 +11,18 @@ class MCSlot;
* Contains all relevant data for a The Minish Cap save, * Contains all relevant data for a The Minish Cap save,
* file. * file.
*/ */
class MCFile class MCFile {
{
public: public:
static const char VERSION_EU_JP[33]; static const char VERSION_EU_JP[33];
static const char VERSION_US[33]; static const char VERSION_US[33];
enum SlotType enum SlotType { New = 0x54494E49, Valid = 0x4D435A33, Deleted = 0x466C6544 };
{
New = 0x54494E49,
Valid = 0x4D435A33,
Deleted = 0x466C6544
};
MCFile(); MCFile();
static atUint8* unscramble(atUint8* data, atUint64 length); static atUint8* unscramble(atUint8* data, atUint64 length);
private: private:
MCSlot* m_slots[3]; MCSlot* m_slots[3];
}; };
} // zelda } // namespace athena

View File

@ -2,13 +2,11 @@
#include "athena/MemoryReader.hpp" #include "athena/MemoryReader.hpp"
namespace athena namespace athena {
{
class MCFile; class MCFile;
namespace io namespace io {
{
/*! \class MCFileReader /*! \class MCFileReader
* \brief The Minish Cap Save save data reader class * \brief The Minish Cap Save save data reader class
@ -17,8 +15,7 @@ namespace io
* all work is done using a memory buffer, and not read directly from the disk. * all work is done using a memory buffer, and not read directly from the disk.
* \sa BinaryReader * \sa BinaryReader
*/ */
class MCFileReader : public MemoryCopyReader class MCFileReader : public MemoryCopyReader {
{
public: public:
/*! /*!
* \brief This constructor takes an existing buffer to read from. * \brief This constructor takes an existing buffer to read from.
@ -43,6 +40,5 @@ public:
MCFile* readFile(); MCFile* readFile();
}; };
} // io } // namespace io
} // zelda } // namespace athena

View File

@ -3,13 +3,11 @@
#include "athena/Types.hpp" #include "athena/Types.hpp"
#include "athena/MemoryWriter.hpp" #include "athena/MemoryWriter.hpp"
namespace athena namespace athena {
{
class MCFile; class MCFile;
namespace io namespace io {
{
/*! \class MCFileWriter /*! \class MCFileWriter
* \brief The Minish Cap Save save data writer class * \brief The Minish Cap Save save data writer class
@ -18,8 +16,7 @@ namespace io
* all work is done using a memory buffer, and not written directly from the disk. * all work is done using a memory buffer, and not written directly from the disk.
* \sa BinaryWriter * \sa BinaryWriter
*/ */
class MCFileWriter : protected MemoryCopyWriter class MCFileWriter : protected MemoryCopyWriter {
{
public: public:
/*! /*!
* \brief This constructor takes an existing buffer to write to. * \brief This constructor takes an existing buffer to write to.
@ -44,10 +41,10 @@ public:
void writeFile(MCFile* file); void writeFile(MCFile* file);
static atUint16 calculateChecksum(atUint8* data, atUint32 length); static atUint16 calculateChecksum(atUint8* data, atUint32 length);
private: private:
atUint16 calculateSlotChecksum(atUint32 game); atUint16 calculateSlotChecksum(atUint32 game);
}; };
} // io } // namespace io
} // zelda } // namespace athena

View File

@ -3,13 +3,10 @@
#include "athena/Global.hpp" #include "athena/Global.hpp"
#include "athena/ZQuestFile.hpp" #include "athena/ZQuestFile.hpp"
namespace athena namespace athena {
{ class MCSlot : public ZQuestFile {
class MCSlot : public ZQuestFile
{
public: public:
MCSlot(std::unique_ptr<atUint8[]>&& data, atUint32 length); MCSlot(std::unique_ptr<atUint8[]>&& data, atUint32 length);
}; };
} // Athena } // namespace athena

View File

@ -5,8 +5,7 @@
#include <functional> #include <functional>
#include "athena/IStreamReader.hpp" #include "athena/IStreamReader.hpp"
namespace athena::io namespace athena::io {
{
/*! \class MemoryReader /*! \class MemoryReader
* \brief A Stream class for reading data from a memory position * \brief A Stream class for reading data from a memory position
* *
@ -15,10 +14,10 @@ namespace athena::io
* this allows for fast, flexible code as well as the ability to quickly modify data * this allows for fast, flexible code as well as the ability to quickly modify data
* \sa Stream * \sa Stream
*/ */
class MemoryReader : public IStreamReader class MemoryReader : public IStreamReader {
{
protected: protected:
MemoryReader() = default; MemoryReader() = default;
public: public:
virtual ~MemoryReader(); virtual ~MemoryReader();
@ -28,7 +27,7 @@ public:
* \param length The length of the existing buffer * \param length The length of the existing buffer
* \param takeOwnership Memory will be freed with the reader if set * \param takeOwnership Memory will be freed with the reader if set
*/ */
MemoryReader(const void* data, atUint64 length, bool takeOwnership=false, bool globalErr=true); MemoryReader(const void* data, atUint64 length, bool takeOwnership = false, bool globalErr = true);
/*! \brief Sets the buffers position relative to the specified position.<br /> /*! \brief Sets the buffers position relative to the specified position.<br />
* It seeks relative to the current position by default. * It seeks relative to the current position by default.
@ -41,16 +40,13 @@ public:
* *
* \return Int64 The current position in the stream. * \return Int64 The current position in the stream.
*/ */
inline atUint64 position() const inline atUint64 position() const { return m_position; }
{return m_position;}
/*! \brief Returns whether or not the stream is at the end. /*! \brief Returns whether or not the stream is at the end.
* *
* \return bool True if at end; False otherwise. * \return bool True if at end; False otherwise.
*/ */
inline atUint64 length() const inline atUint64 length() const { return m_length; }
{return m_length;}
/*! \brief Sets the buffer to the given one, deleting the current one.<br /> /*! \brief Sets the buffer to the given one, deleting the current one.<br />
* <b>BEWARE:</b> As this deletes the current buffer it WILL cause a loss of data * <b>BEWARE:</b> As this deletes the current buffer it WILL cause a loss of data
@ -62,8 +58,7 @@ public:
* \param takeOwnership Memory will be freed with the reader if set * \param takeOwnership Memory will be freed with the reader if set
* \throw IOException * \throw IOException
*/ */
void setData(const atUint8* data, atUint64 length, bool takeOwnership=false); void setData(const atUint8* data, atUint64 length, bool takeOwnership = false);
/*! \brief Returns a copy of the current buffer.<br /> /*! \brief Returns a copy of the current buffer.<br />
* Changes to the copy do not affect the buffer so it's perfectly safe to * Changes to the copy do not affect the buffer so it's perfectly safe to
@ -89,8 +84,7 @@ protected:
bool m_globalErr = true; bool m_globalErr = true;
}; };
class MemoryCopyReader : public MemoryReader class MemoryCopyReader : public MemoryReader {
{
public: public:
/*! \brief This constructor copies an existing buffer to read from. /*! \brief This constructor copies an existing buffer to read from.
* *
@ -103,9 +97,7 @@ public:
* *
* \param filename The file to create the stream from * \param filename The file to create the stream from
*/ */
MemoryCopyReader(const std::string& filename) MemoryCopyReader(const std::string& filename) : m_filepath(filename) { loadData(); }
: m_filepath(filename)
{loadData();}
void setData(const atUint8* data, atUint64 length); void setData(const atUint8* data, atUint64 length);
@ -115,6 +107,4 @@ protected:
std::string m_filepath; //!< Path to the target file std::string m_filepath; //!< Path to the target file
}; };
} // Athena } // namespace athena::io

View File

@ -5,8 +5,7 @@
#include <functional> #include <functional>
#include "athena/IStreamWriter.hpp" #include "athena/IStreamWriter.hpp"
namespace athena::io namespace athena::io {
{
/*! @class MemoryWriter /*! @class MemoryWriter
* @brief A Stream class for writing data to a memory position * @brief A Stream class for writing data to a memory position
@ -16,10 +15,8 @@ namespace athena::io
* this allows for fast, flexible code as well as the ability to quickly modify data * this allows for fast, flexible code as well as the ability to quickly modify data
* @sa Stream * @sa Stream
*/ */
class MemoryWriter : public IStreamWriter class MemoryWriter : public IStreamWriter {
{
public: public:
virtual ~MemoryWriter(); virtual ~MemoryWriter();
/*! @brief This constructor references an existing buffer to write to in-place. /*! @brief This constructor references an existing buffer to write to in-place.
@ -36,22 +33,19 @@ public:
*/ */
void seek(atInt64 pos, SeekOrigin origin = SeekOrigin::Current); void seek(atInt64 pos, SeekOrigin origin = SeekOrigin::Current);
/*! @brief Returns the current position in the stream. /*! @brief Returns the current position in the stream.
* *
* @return Int64 The current position in the stream. * @return Int64 The current position in the stream.
*/ */
inline atUint64 position() const inline atUint64 position() const { return m_position; }
{return m_position;}
/*! @brief Returns the length of the stream. /*! @brief Returns the length of the stream.
* *
* @return Int64 The length of the stream. * @return Int64 The length of the stream.
*/ */
inline atUint64 length() const inline atUint64 length() const { return m_length; }
{return m_length;}
inline bool isOpen() const {return true;} inline bool isOpen() const { return true; }
/** @brief Sets the buffer to the given one, deleting the current one if it owns it.<br /> /** @brief Sets the buffer to the given one, deleting the current one if it owns it.<br />
* @param data The new buffer. * @param data The new buffer.
@ -60,7 +54,6 @@ public:
*/ */
void setData(atUint8* data, atUint64 length, bool takeOwnership = false); void setData(atUint8* data, atUint64 length, bool takeOwnership = false);
/*! @brief Returns a copy of the current buffer.<br /> /*! @brief Returns a copy of the current buffer.<br />
* Changes to the copy do not affect the buffer so it's perfectly safe to * Changes to the copy do not affect the buffer so it's perfectly safe to
* directly edit the buffer and use setData to set the new information.<br /> * directly edit the buffer and use setData to set the new information.<br />
@ -72,15 +65,12 @@ public:
* *
* @param filepath The path to write to. * @param filepath The path to write to.
*/ */
inline void setFilepath(const std::string& filepath) inline void setFilepath(const std::string& filepath) { m_filepath = filepath; }
{m_filepath = filepath;}
/*! @brief /*! @brief
* Returns the target file * Returns the target file
*/ */
inline std::string filepath() const inline std::string filepath() const { return m_filepath; }
{return m_filepath;}
/*! @brief Saves the file to the specified file. /*! @brief Saves the file to the specified file.
* *
@ -106,16 +96,14 @@ protected:
std::string m_filepath; //!< Path to the target file std::string m_filepath; //!< Path to the target file
}; };
class MemoryCopyWriter : public MemoryWriter class MemoryCopyWriter : public MemoryWriter {
{
public: public:
/*! @brief This constructor copies an existing buffer to write to. /*! @brief This constructor copies an existing buffer to write to.
* *
* @param data The existing buffer * @param data The existing buffer
* @param length The length of the existing buffer * @param length The length of the existing buffer
*/ */
explicit MemoryCopyWriter(atUint8* data=nullptr, atUint64 length=0x10); explicit MemoryCopyWriter(atUint8* data = nullptr, atUint64 length = 0x10);
/*! @brief This constructor creates an instance from a file on disk. /*! @brief This constructor creates an instance from a file on disk.
* *
@ -151,9 +139,9 @@ public:
protected: protected:
std::unique_ptr<atUint8[]> m_dataCopy; std::unique_ptr<atUint8[]> m_dataCopy;
private: private:
void resize(atUint64 newSize); void resize(atUint64 newSize);
}; };
} } // namespace athena::io

View File

@ -5,10 +5,8 @@
#include "athena/Stream.hpp" #include "athena/Stream.hpp"
#include <physfs.h> #include <physfs.h>
namespace athena::io namespace athena::io {
{ class PHYSFSFileReader : public Stream {
class PHYSFSFileReader : public Stream
{
public: public:
PHYSFSFileReader(const std::string& path); PHYSFSFileReader(const std::string& path);
@ -48,11 +46,10 @@ private:
atUint64 m_length; atUint64 m_length;
PHYSFS_File* m_handle; PHYSFS_File* m_handle;
}; };
} } // namespace athena::io
#ifndef PHYSFSFILEREADER_BASE #ifndef PHYSFSFILEREADER_BASE
#define PHYSFSFILEREADER_BASE() \ #define PHYSFSFILEREADER_BASE() typedef athena::io::PHYSFSFileReader base
typedef athena::io::PHYSFSFileReader base
#endif #endif
#endif // PHYSFSSTREAM_HPP #endif // PHYSFSSTREAM_HPP
#endif // ATHENA_ENABLE_PHYSFS #endif // ATHENA_ENABLE_PHYSFS

View File

@ -2,29 +2,18 @@
#include "athena/Global.hpp" #include "athena/Global.hpp"
namespace athena::Sakura namespace athena::Sakura {
{
template <typename T> template <typename T>
class Vector2D class Vector2D {
{
public: public:
T x; T x;
T y; T y;
Vector2D() Vector2D() : x(0), y(0) {}
: x(0),
y(0)
{
}
Vector2D(T x, T y) Vector2D(T x, T y) : x(x), y(y) {}
: x(x),
y(y)
{
}
}; };
typedef Vector2D<int> Vector2Di; typedef Vector2D<int> Vector2Di;
typedef Vector2D<float> Vector2Df; typedef Vector2D<float> Vector2Df;
} // Sakura } // namespace athena::Sakura

View File

@ -5,26 +5,14 @@
// standard lib // standard lib
#include <vector> #include <vector>
namespace athena namespace athena {
{
class SkywardSwordQuest; class SkywardSwordQuest;
enum class Region enum class Region { NTSC, NTSCJ, PAL };
{
NTSC,
NTSCJ,
PAL
};
class SkywardSwordFile class SkywardSwordFile {
{
public: public:
enum MagicNumbers enum MagicNumbers { USMagic = 0x534F5545, JAMagic = 0x534F554A, EUMagic = 0x534F5550 };
{
USMagic = 0x534F5545,
JAMagic = 0x534F554A,
EUMagic = 0x534F5550
};
SkywardSwordFile(); SkywardSwordFile();
SkywardSwordFile(std::vector<SkywardSwordQuest*> quests); SkywardSwordFile(std::vector<SkywardSwordQuest*> quests);
@ -44,4 +32,4 @@ private:
atUint32 m_numQuests; atUint32 m_numQuests;
}; };
} } // namespace athena

View File

@ -2,19 +2,15 @@
#include "athena/MemoryReader.hpp" #include "athena/MemoryReader.hpp"
namespace athena namespace athena {
{
class SkywardSwordFile; class SkywardSwordFile;
namespace io namespace io {
{ class SkywardSwordFileReader : public MemoryCopyReader {
class SkywardSwordFileReader : public MemoryCopyReader
{
public: public:
SkywardSwordFileReader(atUint8* data, atUint64 length); SkywardSwordFileReader(atUint8* data, atUint64 length);
SkywardSwordFileReader(const std::string& filename); SkywardSwordFileReader(const std::string& filename);
SkywardSwordFile* read(); SkywardSwordFile* read();
}; };
} // io } // namespace io
} // zelda } // namespace athena

View File

@ -2,20 +2,17 @@
#include "athena/MemoryWriter.hpp" #include "athena/MemoryWriter.hpp"
namespace athena namespace athena {
{
class SkywardSwordFile; class SkywardSwordFile;
namespace io namespace io {
{
class SkywardSwordFileWriter : public MemoryCopyWriter class SkywardSwordFileWriter : public MemoryCopyWriter {
{
public: public:
SkywardSwordFileWriter(atUint8* data, atUint64 len); SkywardSwordFileWriter(atUint8* data, atUint64 len);
SkywardSwordFileWriter(const std::string& filename); SkywardSwordFileWriter(const std::string& filename);
void write(SkywardSwordFile* file); void write(SkywardSwordFile* file);
}; };
} } // namespace io
} } // namespace athena

View File

@ -4,19 +4,12 @@
#include "athena/Global.hpp" #include "athena/Global.hpp"
#include "athena/ZQuestFile.hpp" #include "athena/ZQuestFile.hpp"
namespace athena namespace athena {
{
// TODO: Handle game specific data // TODO: Handle game specific data
class SkywardSwordQuest : public ZQuestFile class SkywardSwordQuest : public ZQuestFile {
{
public: public:
enum AmmoType enum AmmoType { Arrows, Bombs, Seeds };
{
Arrows,
Bombs,
Seeds
};
SkywardSwordQuest(std::unique_ptr<atUint8[]>&& data, atUint32 len); SkywardSwordQuest(std::unique_ptr<atUint8[]>&& data, atUint32 len);
@ -54,5 +47,5 @@ private:
std::unique_ptr<atUint8[]> m_skipData; std::unique_ptr<atUint8[]> m_skipData;
}; };
} // Athena } // namespace athena
#endif // SSQUEST_HPP #endif // SSQUEST_HPP

View File

@ -14,30 +14,24 @@ typedef UINT_PTR SOCKET;
struct sockaddr_in; struct sockaddr_in;
namespace athena::net namespace athena::net {
{
/** IP address class derived from SFML */ /** IP address class derived from SFML */
class IPAddress class IPAddress {
{
uint32_t m_address = 0; uint32_t m_address = 0;
bool m_valid = false; bool m_valid = false;
void resolve(const std::string& address); void resolve(const std::string& address);
public: public:
IPAddress(const std::string& address) IPAddress(const std::string& address) { resolve(address); }
{
resolve(address);
}
uint32_t toInteger() const; uint32_t toInteger() const;
operator bool() const { return m_valid; } operator bool() const { return m_valid; }
}; };
/** Server-oriented TCP socket class derived from SFML */ /** Server-oriented TCP socket class derived from SFML */
class Socket class Socket {
{
#ifndef _WIN32 #ifndef _WIN32
using SocketTp = int; using SocketTp = int;
#else #else
@ -50,30 +44,19 @@ class Socket
void setRemoteSocket(int remSocket); void setRemoteSocket(int remSocket);
public: public:
enum class EResult enum class EResult { OK, Error, Busy };
{
OK,
Error,
Busy
};
#ifdef _WIN32 #ifdef _WIN32
static EResult LastWSAError(); static EResult LastWSAError();
#endif #endif
Socket(bool blocking) Socket(bool blocking) : m_isBlocking(blocking) {}
: m_isBlocking(blocking) {}
~Socket() { close(); } ~Socket() { close(); }
Socket(const Socket& other) = delete; Socket(const Socket& other) = delete;
Socket& operator=(const Socket& other) = delete; Socket& operator=(const Socket& other) = delete;
Socket(Socket&& other) Socket(Socket&& other) : m_socket(other.m_socket), m_isBlocking(other.m_isBlocking) { other.m_socket = -1; }
: m_socket(other.m_socket), m_isBlocking(other.m_isBlocking) Socket& operator=(Socket&& other) {
{
other.m_socket = -1;
}
Socket& operator=(Socket&& other)
{
close(); close();
m_socket = other.m_socket; m_socket = other.m_socket;
other.m_socket = -1; other.m_socket = -1;
@ -98,5 +81,4 @@ public:
SocketTp GetInternalSocket() const { return m_socket; } SocketTp GetInternalSocket() const { return m_socket; }
}; };
} } // namespace athena::net

View File

@ -4,13 +4,11 @@
#include <string> #include <string>
#include "athena/SakuraGlobal.hpp" #include "athena/SakuraGlobal.hpp"
namespace athena::Sakura namespace athena::Sakura {
{
class SpriteFile; class SpriteFile;
class SpriteFrame; class SpriteFrame;
class Sprite class Sprite {
{
public: public:
Sprite(SpriteFile* root); Sprite(SpriteFile* root);
Sprite(SpriteFile* root, const std::string& name); Sprite(SpriteFile* root, const std::string& name);
@ -56,6 +54,7 @@ public:
void setRoot(SpriteFile* root); void setRoot(SpriteFile* root);
SpriteFile* root() const; SpriteFile* root() const;
private: private:
SpriteFile* m_root; SpriteFile* m_root;
std::string m_name; std::string m_name;
@ -66,5 +65,4 @@ private:
atUint32 m_currentFrame; atUint32 m_currentFrame;
}; };
} // zelda } // namespace athena::Sakura

View File

@ -7,17 +7,14 @@
#include <string> #include <string>
#include "athena/SakuraGlobal.hpp" #include "athena/SakuraGlobal.hpp"
namespace athena::Sakura namespace athena::Sakura {
{ struct STexture {
struct STexture
{
std::string Filepath; std::string Filepath;
bool Preload; bool Preload;
}; };
class Sprite; class Sprite;
class SpriteFile class SpriteFile {
{
public: public:
/*! /*!
* \brief Major * \brief Major
@ -132,7 +129,6 @@ public slots:
*/ */
Vector2Df origin() const; Vector2Df origin() const;
/*! /*!
* \brief originX * \brief originX
* \return * \return
@ -189,6 +185,6 @@ private:
Vector2Df m_origin; Vector2Df m_origin;
std::unordered_map<std::string, Sprite*> m_sprites; std::unordered_map<std::string, Sprite*> m_sprites;
}; };
} // Zelda } // namespace athena::Sakura
#endif // SSPRITE_HPP #endif // SSPRITE_HPP

View File

@ -2,25 +2,19 @@
#include "athena/MemoryReader.hpp" #include "athena/MemoryReader.hpp"
namespace athena::Sakura namespace athena::Sakura {
{
class SpriteFile; class SpriteFile;
} // Sakura } // namespace athena::Sakura
namespace athena namespace athena {
{ namespace io {
namespace io
{
class SpriteFileReader : public MemoryCopyReader class SpriteFileReader : public MemoryCopyReader {
{
public: public:
SpriteFileReader(atUint8* data, atUint64 length); SpriteFileReader(atUint8* data, atUint64 length);
SpriteFileReader(const std::string& filepath); SpriteFileReader(const std::string& filepath);
Sakura::SpriteFile* readFile(); Sakura::SpriteFile* readFile();
}; };
} } // namespace io
} // zelda } // namespace athena

View File

@ -2,18 +2,14 @@
#include "athena/MemoryWriter.hpp" #include "athena/MemoryWriter.hpp"
namespace athena namespace athena {
{ namespace Sakura {
namespace Sakura
{
class SpriteFile; class SpriteFile;
} // Sakura } // namespace Sakura
namespace io namespace io {
{
class SpriteFileWriter : public MemoryCopyWriter class SpriteFileWriter : public MemoryCopyWriter {
{
public: public:
SpriteFileWriter(atUint8* data, atUint64 length); SpriteFileWriter(atUint8* data, atUint64 length);
@ -22,5 +18,5 @@ public:
void writeFile(Sakura::SpriteFile* file); void writeFile(Sakura::SpriteFile* file);
}; };
} // io } // namespace io
} // zelda } // namespace athena

View File

@ -1,17 +1,14 @@
#pragma once #pragma once
#include "athena/SakuraGlobal.hpp" #include "athena/SakuraGlobal.hpp"
#include <vector> #include <vector>
namespace athena::Sakura namespace athena::Sakura {
{
class Sprite; class Sprite;
class SpritePart; class SpritePart;
class SpriteFrame class SpriteFrame {
{
public: public:
/*! /*!
* \brief SSpriteFrame * \brief SSpriteFrame
@ -25,7 +22,6 @@ public:
*/ */
void setFrameTime(float frameTime); void setFrameTime(float frameTime);
/*! /*!
* \brief frameTime * \brief frameTime
* \return * \return
@ -39,11 +35,11 @@ public:
void setRoot(Sprite* root); void setRoot(Sprite* root);
Sprite* root() const; Sprite* root() const;
private: private:
Sprite* m_root; Sprite* m_root;
float m_frameTime; float m_frameTime;
std::vector<SpritePart*> m_parts; std::vector<SpritePart*> m_parts;
}; };
} // zelda } // namespace athena::Sakura

View File

@ -5,12 +5,10 @@
#include <string> #include <string>
namespace athena::Sakura namespace athena::Sakura {
{
class SpriteFrame; class SpriteFrame;
class SpritePart class SpritePart {
{
public: public:
SpritePart(SpriteFrame* root); SpritePart(SpriteFrame* root);
SpritePart(SpriteFrame* root, const std::string& name, bool hasCollision = false); SpritePart(SpriteFrame* root, const std::string& name, bool hasCollision = false);
@ -48,7 +46,7 @@ public:
*/ */
void setTextureOffset(const Vector2Df& offset); void setTextureOffset(const Vector2Df& offset);
/*! /*!
* \brief textureOffset * \brief textureOffset
* \return * \return
*/ */
@ -60,12 +58,12 @@ public:
*/ */
void setSize(atUint32 width, atUint32 height); void setSize(atUint32 width, atUint32 height);
/*! /*!
* \brief setSize * \brief setSize
* \param size * \param size
*/ */
void setSize(const Vector2Di& size); void setSize(const Vector2Di& size);
/*! /*!
* \brief size * \brief size
* \return * \return
*/ */
@ -98,7 +96,6 @@ public:
void setRoot(SpriteFrame* root); void setRoot(SpriteFrame* root);
SpriteFrame* root() const; SpriteFrame* root() const;
private: private:
SpriteFrame* m_root; SpriteFrame* m_root;
std::string m_name; std::string m_name;
@ -110,5 +107,4 @@ private:
bool m_flippedV; bool m_flippedV;
atUint32 m_frameIndex; atUint32 m_frameIndex;
}; };
} } // namespace athena::Sakura

View File

@ -13,23 +13,34 @@ using atUint64 = uint64_t;
// Vector types // Vector types
#include "simd/simd.hpp" #include "simd/simd.hpp"
typedef struct { athena::simd<float> simd; } atVec2f; typedef struct {
typedef struct { athena::simd<float> simd; } atVec3f; athena::simd<float> simd;
typedef struct { athena::simd<float> simd; } atVec4f; } atVec2f;
typedef struct { athena::simd<double> simd; } atVec2d; typedef struct {
typedef struct { athena::simd<double> simd; } atVec3d; athena::simd<float> simd;
typedef struct { athena::simd<double> simd; } atVec4d; } atVec3f;
typedef struct {
athena::simd<float> simd;
} atVec4f;
typedef struct {
athena::simd<double> simd;
} atVec2d;
typedef struct {
athena::simd<double> simd;
} atVec3d;
typedef struct {
athena::simd<double> simd;
} atVec4d;
#ifndef UNUSED #ifndef UNUSED
#define UNUSED(x) ((void)x) #define UNUSED(x) ((void)x)
#endif // UNUSED #endif // UNUSED
#ifdef __GNUC__ #ifdef __GNUC__
#define DEPRECATED(func) func __attribute__ ((deprecated)) #define DEPRECATED(func) func __attribute__((deprecated))
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#define DEPRECATED(func) __declspec(deprecated) func #define DEPRECATED(func) __declspec(deprecated) func
#else #else
#pragma message("WARNING: You need to implement DEPRECATED for this compiler") #pragma message("WARNING: You need to implement DEPRECATED for this compiler")
#define DEPRECATED(func) func #define DEPRECATED(func) func
#endif #endif

View File

@ -9,19 +9,17 @@
#include "athena/Global.hpp" #include "athena/Global.hpp"
#include "athena/Types.hpp" #include "athena/Types.hpp"
namespace athena::utility namespace athena::utility {
{ inline bool isEmpty(atInt8* buf, atUint32 size) { return !memcmp(buf, buf + 1, size - 1); }
inline bool isEmpty(atInt8* buf, atUint32 size) {return !memcmp(buf, buf + 1, size - 1);}
#if _WIN32 #if _WIN32
constexpr bool isSystemBigEndian() {return false;} constexpr bool isSystemBigEndian() { return false; }
#else #else
constexpr bool isSystemBigEndian() {return __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__;} constexpr bool isSystemBigEndian() { return __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__; }
#endif #endif
inline constexpr ::athena::Endian SystemEndian = isSystemBigEndian() ? Big : Little; inline constexpr ::athena::Endian SystemEndian = isSystemBigEndian() ? Big : Little;
inline constexpr ::athena::Endian NotSystemEndian = isSystemBigEndian() ? Little : Big; inline constexpr ::athena::Endian NotSystemEndian = isSystemBigEndian() ? Little : Big;
inline atInt16 swap16(atInt16 val) inline atInt16 swap16(atInt16 val) {
{
#if __GNUC__ #if __GNUC__
return __builtin_bswap16(val); return __builtin_bswap16(val);
#elif _WIN32 #elif _WIN32
@ -30,9 +28,8 @@ inline atInt16 swap16(atInt16 val)
return (val = (val << 8) | ((val >> 8) & 0xFF)); return (val = (val << 8) | ((val >> 8) & 0xFF));
#endif #endif
} }
inline atUint16 swapU16(atUint16 val) {return (atUint16)swap16(val);} inline atUint16 swapU16(atUint16 val) { return (atUint16)swap16(val); }
inline atInt32 swap32(atInt32 val) inline atInt32 swap32(atInt32 val) {
{
#if __GNUC__ #if __GNUC__
return __builtin_bswap32(val); return __builtin_bswap32(val);
#elif _WIN32 #elif _WIN32
@ -43,119 +40,101 @@ inline atInt32 swap32(atInt32 val)
return val; return val;
#endif #endif
} }
inline atUint32 swapU32(atUint32 val) {return (atUint32)swap32(val);} inline atUint32 swapU32(atUint32 val) { return (atUint32)swap32(val); }
inline atInt64 swap64(atInt64 val) inline atInt64 swap64(atInt64 val) {
{
#if __GNUC__ #if __GNUC__
return __builtin_bswap64(val); return __builtin_bswap64(val);
#elif _WIN32 #elif _WIN32
return _byteswap_uint64(val); return _byteswap_uint64(val);
#else #else
return (val = ((atInt64)((((atInt64)(val) & 0xFF00000000000000ULL) >> 56) | return (val = ((atInt64)(
(((atInt64)(val) & 0x00FF000000000000ULL) >> 40) | (((atInt64)(val)&0xFF00000000000000ULL) >> 56) | (((atInt64)(val)&0x00FF000000000000ULL) >> 40) |
(((atInt64)(val) & 0x0000FF0000000000ULL) >> 24) | (((atInt64)(val)&0x0000FF0000000000ULL) >> 24) | (((atInt64)(val)&0x000000FF00000000ULL) >> 8) |
(((atInt64)(val) & 0x000000FF00000000ULL) >> 8) | (((atInt64)(val)&0x00000000FF000000ULL) << 8) | (((atInt64)(val)&0x0000000000FF0000ULL) << 24) |
(((atInt64)(val) & 0x00000000FF000000ULL) << 8) | (((atInt64)(val)&0x000000000000FF00ULL) << 40) | (((atInt64)(val)&0x00000000000000FFULL) << 56))));
(((atInt64)(val) & 0x0000000000FF0000ULL) << 24) |
(((atInt64)(val) & 0x000000000000FF00ULL) << 40) |
(((atInt64)(val) & 0x00000000000000FFULL) << 56))));
#endif #endif
} }
inline atUint64 swapU64(atUint64 val) {return (atUint64)swap64(val);} inline atUint64 swapU64(atUint64 val) { return (atUint64)swap64(val); }
inline float swapFloat(float val) inline float swapFloat(float val) {
{
atInt32 ival = swap32(*((atInt32*)(&val))); atInt32 ival = swap32(*((atInt32*)(&val)));
return *((float*)(&ival)); return *((float*)(&ival));
} }
inline double swapDouble(double val) inline double swapDouble(double val) {
{
atInt64 ival = swap64(*((atInt64*)(&val))); atInt64 ival = swap64(*((atInt64*)(&val)));
return *((double*)(&ival)); return *((double*)(&ival));
} }
inline atInt16 LittleInt16(atInt16& val) inline atInt16 LittleInt16(atInt16& val) {
{
if (athena::utility::isSystemBigEndian()) if (athena::utility::isSystemBigEndian())
val = athena::utility::swap16(val); val = athena::utility::swap16(val);
return val; return val;
} }
inline atUint16 LittleUint16(atUint16& val) inline atUint16 LittleUint16(atUint16& val) {
{
atInt16 ret = val; atInt16 ret = val;
LittleInt16(ret); LittleInt16(ret);
val = ret; val = ret;
return val; return val;
} }
inline atInt16 BigInt16(atInt16& val) inline atInt16 BigInt16(atInt16& val) {
{
if (!athena::utility::isSystemBigEndian()) if (!athena::utility::isSystemBigEndian())
val = athena::utility::swap16(val); val = athena::utility::swap16(val);
return val; return val;
} }
inline atUint16 BigUint16(atUint16& val) inline atUint16 BigUint16(atUint16& val) {
{
atInt16 ret = val; atInt16 ret = val;
BigInt16(ret); BigInt16(ret);
val = ret; val = ret;
return val; return val;
} }
inline atInt32 LittleInt32(atInt32& val) inline atInt32 LittleInt32(atInt32& val) {
{
if (athena::utility::isSystemBigEndian()) if (athena::utility::isSystemBigEndian())
val = athena::utility::swap32(val); val = athena::utility::swap32(val);
return val; return val;
} }
inline atUint32 LittleUint32(atUint32& val) inline atUint32 LittleUint32(atUint32& val) {
{
atInt32 ret = val; atInt32 ret = val;
LittleInt32(ret); LittleInt32(ret);
val = ret; val = ret;
return val; return val;
} }
inline atInt32 BigInt32(atInt32& val) inline atInt32 BigInt32(atInt32& val) {
{
if (!athena::utility::isSystemBigEndian()) if (!athena::utility::isSystemBigEndian())
val = athena::utility::swap32(val); val = athena::utility::swap32(val);
return val; return val;
} }
inline atUint32 BigUint32(atUint32& val) inline atUint32 BigUint32(atUint32& val) {
{
atInt32 ret = val; atInt32 ret = val;
BigInt32(ret); BigInt32(ret);
val = ret; val = ret;
return val; return val;
} }
inline atInt64 LittleInt64(atInt64& val) inline atInt64 LittleInt64(atInt64& val) {
{
if (athena::utility::isSystemBigEndian()) if (athena::utility::isSystemBigEndian())
val = athena::utility::swap64(val); val = athena::utility::swap64(val);
return val; return val;
} }
inline atUint64 LittleUint64(atUint64& val) inline atUint64 LittleUint64(atUint64& val) {
{
atInt64 ret = val; atInt64 ret = val;
LittleInt64(ret); LittleInt64(ret);
val = ret; val = ret;
return val; return val;
} }
inline atInt64 BigInt64(atInt64& val) inline atInt64 BigInt64(atInt64& val) {
{
if (!athena::utility::isSystemBigEndian()) if (!athena::utility::isSystemBigEndian())
val = athena::utility::swap64(val); val = athena::utility::swap64(val);
return val; return val;
} }
inline atUint64 BigUint64(atUint64& val) inline atUint64 BigUint64(atUint64& val) {
{
atInt64 ret = val; atInt64 ret = val;
BigInt64(ret); BigInt64(ret);
val = ret; val = ret;
@ -163,36 +142,32 @@ inline atUint64 BigUint64(atUint64& val)
return val; return val;
} }
inline float LittleFloat(float val) inline float LittleFloat(float val) {
{
if (athena::utility::isSystemBigEndian()) if (athena::utility::isSystemBigEndian())
val = athena::utility::swapFloat(val); val = athena::utility::swapFloat(val);
return val; return val;
} }
inline float BigFloat(float val) inline float BigFloat(float val) {
{
if (!athena::utility::isSystemBigEndian()) if (!athena::utility::isSystemBigEndian())
val = athena::utility::swapFloat(val); val = athena::utility::swapFloat(val);
return val; return val;
} }
inline double LittleDouble(double val) inline double LittleDouble(double val) {
{
if (athena::utility::isSystemBigEndian()) if (athena::utility::isSystemBigEndian())
val = athena::utility::swapDouble(val); val = athena::utility::swapDouble(val);
return val; return val;
} }
inline double BigDouble(double val) inline double BigDouble(double val) {
{
if (!athena::utility::isSystemBigEndian()) if (!athena::utility::isSystemBigEndian())
val = athena::utility::swapDouble(val); val = athena::utility::swapDouble(val);
return val; return val;
} }
void fillRandom(atUint8 * rndArea, atUint64 count); void fillRandom(atUint8* rndArea, atUint64 count);
std::vector<std::string> split(std::string_view s, char delim); std::vector<std::string> split(std::string_view s, char delim);
atUint64 rand64(); atUint64 rand64();
std::string join(const std::vector<std::string>& elems, std::string_view delims); std::string join(const std::vector<std::string>& elems, std::string_view delims);
@ -221,5 +196,5 @@ std::string wideToUtf8(std::wstring_view src);
std::wstring utf8ToWide(std::string_view src); std::wstring utf8ToWide(std::string_view src);
} // Athena } // namespace athena::utility
#endif #endif

View File

@ -6,8 +6,7 @@
#include <vector> #include <vector>
#include "athena/IStreamWriter.hpp" #include "athena/IStreamWriter.hpp"
namespace athena::io namespace athena::io {
{
/*! @class VectorWriter /*! @class VectorWriter
* @brief A Stream class for writing data to a STL vector * @brief A Stream class for writing data to a STL vector
@ -16,8 +15,7 @@ namespace athena::io
* all work is done using a std::vector, and not written directly to the disk * all work is done using a std::vector, and not written directly to the disk
* @sa Stream * @sa Stream
*/ */
class VectorWriter : public IStreamWriter class VectorWriter : public IStreamWriter {
{
public: public:
/*! @brief Sets the buffers position relative to the specified position.<br /> /*! @brief Sets the buffers position relative to the specified position.<br />
* It seeks relative to the current position by default. * It seeks relative to the current position by default.
@ -57,5 +55,4 @@ protected:
atUint64 m_position = 0; atUint64 m_position = 0;
}; };
} } // namespace athena::io

View File

@ -4,23 +4,16 @@
#include <string> #include <string>
#include "athena/Global.hpp" #include "athena/Global.hpp"
namespace athena namespace athena {
{
class WiiImage; class WiiImage;
/*! \class WiiBanner /*! \class WiiBanner
* \brief Wii banner container class * \brief Wii banner container class
* *
* Contains all relevant data for a Wii banner. * Contains all relevant data for a Wii banner.
*/ */
class WiiBanner class WiiBanner {
{
public: public:
enum enum { NoCopy = 0x00000001, Bounce = 0x00000010, NoCopyBounce = NoCopy | Bounce };
{
NoCopy = 0x00000001,
Bounce = 0x00000010,
NoCopyBounce = NoCopy | Bounce
};
/*! /*!
* \brief WiiBanner * \brief WiiBanner
@ -34,8 +27,8 @@ public:
* \param m_banner * \param m_banner
* \param icons * \param icons
*/ */
WiiBanner(atUint32 gameId, const std::u16string& title, const std::u16string& subtitle, WiiBanner(atUint32 gameId, const std::u16string& title, const std::u16string& subtitle, WiiImage* m_banner,
WiiImage* m_banner, std::vector<WiiImage*> icons); std::vector<WiiImage*> icons);
virtual ~WiiBanner(); virtual ~WiiBanner();
/*! /*!
@ -159,6 +152,7 @@ public:
* \return * \return
*/ */
atUint32 flags() const; atUint32 flags() const;
protected: protected:
private: private:
atUint64 m_gameId; atUint64 m_gameId;
@ -171,5 +165,4 @@ private:
std::u16string m_title; std::u16string m_title;
std::u16string m_subtitle; std::u16string m_subtitle;
}; };
} // zelda } // namespace athena

View File

@ -5,28 +5,27 @@
#include <vector> #include <vector>
#include "athena/Global.hpp" #include "athena/Global.hpp"
namespace athena namespace athena {
{
const atUint8 SD_KEY [16] = {0xab, 0x01, 0xb9, 0xd8, 0xe1, 0x62, 0x2b, 0x08, 0xaf, 0xba, 0xd8, 0x4d, 0xbf, 0xc2, 0xa5, 0x5d}; const atUint8 SD_KEY[16] = {0xab, 0x01, 0xb9, 0xd8, 0xe1, 0x62, 0x2b, 0x08,
const atUint8 SD_IV [16] = {0x21, 0x67, 0x12, 0xe6, 0xaa, 0x1f, 0x68, 0x9f, 0x95, 0xc5, 0xa2, 0x23, 0x24, 0xdc, 0x6a, 0x98}; 0xaf, 0xba, 0xd8, 0x4d, 0xbf, 0xc2, 0xa5, 0x5d};
const atUint8 MD5_BLANKER[16] = {0x0e, 0x65, 0x37, 0x81, 0x99, 0xbe, 0x45, 0x17, 0xab, 0x06, 0xec, 0x22, 0x45, 0x1a, 0x57, 0x93}; const atUint8 SD_IV[16] = {0x21, 0x67, 0x12, 0xe6, 0xaa, 0x1f, 0x68, 0x9f,
0x95, 0xc5, 0xa2, 0x23, 0x24, 0xdc, 0x6a, 0x98};
const atUint8 MD5_BLANKER[16] = {0x0e, 0x65, 0x37, 0x81, 0x99, 0xbe, 0x45, 0x17,
0xab, 0x06, 0xec, 0x22, 0x45, 0x1a, 0x57, 0x93};
/*! \class WiiFile /*! \class WiiFile
* \brief Wii file container class * \brief Wii file container class
* *
* Contains all relevant data for a file in a data.bin file. * Contains all relevant data for a file in a data.bin file.
*/ */
class WiiFile class WiiFile {
{
public: public:
/*! \enum Permission /*! \enum Permission
* \brief The Wii uses a bastardized unix permissions system so these flags * \brief The Wii uses a bastardized unix permissions system so these flags
* reflect the file's individual permissions. * reflect the file's individual permissions.
*/ */
enum Permission enum Permission {
{
OtherRead = 0x01, OtherRead = 0x01,
OtherWrite = 0x02, OtherWrite = 0x02,
GroupRead = 0x04, GroupRead = 0x04,
@ -43,11 +42,7 @@ public:
/*! /*!
* \brief The Type enum * \brief The Type enum
*/ */
enum Type enum Type { File = 0x01, Directory = 0x02 };
{
File = 0x01,
Directory = 0x02
};
WiiFile(); WiiFile();
@ -206,6 +201,7 @@ public:
* \return * \return
*/ */
std::string fullpath(); std::string fullpath();
protected: protected:
private: private:
atUint8 m_permissions; atUint8 m_permissions;
@ -218,4 +214,4 @@ private:
std::vector<WiiFile*> m_children; std::vector<WiiFile*> m_children;
}; };
} // zelda } // namespace athena

View File

@ -3,14 +3,12 @@
#include <memory> #include <memory>
#include "athena/Types.hpp" #include "athena/Types.hpp"
namespace athena namespace athena {
{
/*! /*!
* \brief The WiiImage class * \brief The WiiImage class
*/ */
class WiiImage class WiiImage {
{
public: public:
/*! /*!
* \brief WiiImage * \brief WiiImage
@ -72,5 +70,4 @@ private:
std::unique_ptr<atUint8[]> m_data; std::unique_ptr<atUint8[]> m_data;
}; };
} // zelda } // namespace athena

View File

@ -5,8 +5,7 @@
#include <vector> #include <vector>
#include "athena/Global.hpp" #include "athena/Global.hpp"
namespace athena namespace athena {
{
class WiiFile; class WiiFile;
class WiiBanner; class WiiBanner;
@ -19,10 +18,8 @@ class BinaryWriter;
* *
* Contains all relevant data for a Wii data.bin file. * Contains all relevant data for a Wii data.bin file.
*/ */
class WiiSave class WiiSave {
{
public: public:
/*! /*!
* \brief FileIterator * \brief FileIterator
*/ */
@ -74,10 +71,8 @@ public:
protected: protected:
private: private:
WiiFile* m_root; WiiFile* m_root;
WiiBanner* m_banner; WiiBanner* m_banner;
}; };
} // zelda } // namespace athena

View File

@ -3,15 +3,13 @@
#include "athena/Global.hpp" #include "athena/Global.hpp"
#include "athena/MemoryReader.hpp" #include "athena/MemoryReader.hpp"
namespace athena namespace athena {
{
class WiiSave; class WiiSave;
class WiiBanner; class WiiBanner;
class WiiFile; class WiiFile;
class WiiImage; class WiiImage;
namespace io namespace io {
{
/*! \class WiiSaveReader /*! \class WiiSaveReader
* \brief Wii data.bin reader class * \brief Wii data.bin reader class
@ -20,8 +18,7 @@ namespace io
* all work is done using a memory buffer, and not read directly from the disk. * all work is done using a memory buffer, and not read directly from the disk.
* \sa BinaryReader * \sa BinaryReader
*/ */
class WiiSaveReader : public MemoryCopyReader class WiiSaveReader : public MemoryCopyReader {
{
public: public:
/*! \brief This constructor takes an existing buffer to read from. /*! \brief This constructor takes an existing buffer to read from.
* *
@ -41,6 +38,7 @@ public:
* \return * \return
*/ */
std::unique_ptr<WiiSave> readSave(); std::unique_ptr<WiiSave> readSave();
private: private:
WiiBanner* readBanner(); WiiBanner* readBanner();
WiiFile* readFile(); WiiFile* readFile();
@ -49,5 +47,5 @@ private:
WiiFile* buildTree(std::vector<WiiFile*> files); WiiFile* buildTree(std::vector<WiiFile*> files);
}; };
} // io } // namespace io
} // zelda } // namespace athena

View File

@ -2,15 +2,13 @@
#include "athena/MemoryWriter.hpp" #include "athena/MemoryWriter.hpp"
namespace athena namespace athena {
{
class WiiSave; class WiiSave;
class WiiBanner; class WiiBanner;
class WiiFile; class WiiFile;
class WiiImage; class WiiImage;
namespace io namespace io {
{
/*! \class WiiSaveWriter /*! \class WiiSaveWriter
* \brief Wii data.bin writer class * \brief Wii data.bin writer class
@ -19,8 +17,7 @@ namespace io
* all work is done using a memory buffer, and not written directly to the disk. * all work is done using a memory buffer, and not written directly to the disk.
* \sa BinaryReader * \sa BinaryReader
*/ */
class WiiSaveWriter : protected MemoryCopyWriter class WiiSaveWriter : protected MemoryCopyWriter {
{
public: public:
/*! \brief This constructor creates an instance from a file on disk. /*! \brief This constructor creates an instance from a file on disk.
* *
@ -39,7 +36,8 @@ public:
* \param filepath * \param filepath
* \return * \return
*/ */
bool writeSave(WiiSave* save, atUint8* macAddress, atUint32 ngId, atUint8* ngPriv, atUint8* ngSig, atUint32 ngKeyId, const std::string& filepath = ""); bool writeSave(WiiSave* save, atUint8* macAddress, atUint32 ngId, atUint8* ngPriv, atUint8* ngSig, atUint32 ngKeyId,
const std::string& filepath = "");
private: private:
void writeBanner(WiiBanner* banner); void writeBanner(WiiBanner* banner);
@ -48,5 +46,5 @@ private:
void writeCerts(atUint32 filesSize, atUint32 ngId, atUint8* ngPriv, atUint8* ngSig, atUint32 ngKeyId); void writeCerts(atUint32 filesSize, atUint32 ngId, atUint8* ngPriv, atUint8* ngSig, atUint32 ngKeyId);
}; };
} // io } // namespace io
} // zelda } // namespace athena

View File

@ -12,20 +12,13 @@
#include <functional> #include <functional>
#include "Global.hpp" #include "Global.hpp"
namespace athena::io namespace athena::io {
{
class IStreamReader; class IStreamReader;
class IStreamWriter; class IStreamWriter;
enum class YAMLNodeStyle enum class YAMLNodeStyle { Any, Flow, Block };
{
Any,
Flow,
Block
};
struct YAMLNode struct YAMLNode {
{
yaml_node_type_t m_type; yaml_node_type_t m_type;
std::string m_scalarString; std::string m_scalarString;
std::vector<std::unique_ptr<YAMLNode>> m_seqChildren; std::vector<std::unique_ptr<YAMLNode>> m_seqChildren;
@ -34,19 +27,16 @@ struct YAMLNode
YAMLNode(yaml_node_type_t type) : m_type(type) {} YAMLNode(yaml_node_type_t type) : m_type(type) {}
inline const YAMLNode* findMapChild(std::string_view key) const inline const YAMLNode* findMapChild(std::string_view key) const {
{
for (const auto& item : m_mapChildren) for (const auto& item : m_mapChildren)
if (!item.first.compare(key)) if (!item.first.compare(key))
return item.second.get(); return item.second.get();
return nullptr; return nullptr;
} }
inline void assignMapChild(std::string_view key, std::unique_ptr <YAMLNode>&& node) inline void assignMapChild(std::string_view key, std::unique_ptr<YAMLNode>&& node) {
{
for (auto& item : m_mapChildren) for (auto& item : m_mapChildren)
if (!item.first.compare(key)) if (!item.first.compare(key)) {
{
item.second = std::move(node); item.second = std::move(node);
return; return;
} }
@ -54,115 +44,115 @@ struct YAMLNode
} }
}; };
template<typename RETURNTYPE> template <typename RETURNTYPE>
RETURNTYPE NodeToVal(const YAMLNode* node); RETURNTYPE NodeToVal(const YAMLNode* node);
template<> template <>
bool NodeToVal(const YAMLNode* node); bool NodeToVal(const YAMLNode* node);
std::unique_ptr <YAMLNode> ValToNode(bool val); std::unique_ptr<YAMLNode> ValToNode(bool val);
template<> template <>
atInt8 NodeToVal(const YAMLNode* node); atInt8 NodeToVal(const YAMLNode* node);
std::unique_ptr <YAMLNode> ValToNode(atInt8 val); std::unique_ptr<YAMLNode> ValToNode(atInt8 val);
template<> template <>
atUint8 NodeToVal(const YAMLNode* node); atUint8 NodeToVal(const YAMLNode* node);
std::unique_ptr <YAMLNode> ValToNode(atUint8 val); std::unique_ptr<YAMLNode> ValToNode(atUint8 val);
template<> template <>
atInt16 NodeToVal(const YAMLNode* node); atInt16 NodeToVal(const YAMLNode* node);
std::unique_ptr <YAMLNode> ValToNode(atInt16 val); std::unique_ptr<YAMLNode> ValToNode(atInt16 val);
template<> template <>
atUint16 NodeToVal(const YAMLNode* node); atUint16 NodeToVal(const YAMLNode* node);
std::unique_ptr <YAMLNode> ValToNode(atUint16 val); std::unique_ptr<YAMLNode> ValToNode(atUint16 val);
template<> template <>
atInt32 NodeToVal(const YAMLNode* node); atInt32 NodeToVal(const YAMLNode* node);
std::unique_ptr <YAMLNode> ValToNode(atInt32 val); std::unique_ptr<YAMLNode> ValToNode(atInt32 val);
template<> template <>
atUint32 NodeToVal(const YAMLNode* node); atUint32 NodeToVal(const YAMLNode* node);
std::unique_ptr <YAMLNode> ValToNode(atUint32 val); std::unique_ptr<YAMLNode> ValToNode(atUint32 val);
template<> template <>
atInt64 NodeToVal(const YAMLNode* node); atInt64 NodeToVal(const YAMLNode* node);
std::unique_ptr <YAMLNode> ValToNode(atInt64 val); std::unique_ptr<YAMLNode> ValToNode(atInt64 val);
template<> template <>
atUint64 NodeToVal(const YAMLNode* node); atUint64 NodeToVal(const YAMLNode* node);
std::unique_ptr <YAMLNode> ValToNode(atUint64 val); std::unique_ptr<YAMLNode> ValToNode(atUint64 val);
template<> template <>
float NodeToVal(const YAMLNode* node); float NodeToVal(const YAMLNode* node);
std::unique_ptr <YAMLNode> ValToNode(float val); std::unique_ptr<YAMLNode> ValToNode(float val);
template<> template <>
double NodeToVal(const YAMLNode* node); double NodeToVal(const YAMLNode* node);
std::unique_ptr <YAMLNode> ValToNode(double val); std::unique_ptr<YAMLNode> ValToNode(double val);
template<typename RETURNTYPE> template <typename RETURNTYPE>
RETURNTYPE NodeToVec(const YAMLNode* node); RETURNTYPE NodeToVec(const YAMLNode* node);
template<> template <>
atVec2f NodeToVal(const YAMLNode* node); atVec2f NodeToVal(const YAMLNode* node);
std::unique_ptr <YAMLNode> ValToNode(const atVec2f& val); std::unique_ptr<YAMLNode> ValToNode(const atVec2f& val);
template<> template <>
atVec3f NodeToVal(const YAMLNode* node); atVec3f NodeToVal(const YAMLNode* node);
std::unique_ptr <YAMLNode> ValToNode(const atVec3f& val); std::unique_ptr<YAMLNode> ValToNode(const atVec3f& val);
template<> template <>
atVec4f NodeToVal(const YAMLNode* node); atVec4f NodeToVal(const YAMLNode* node);
std::unique_ptr <YAMLNode> ValToNode(const atVec4f& val); std::unique_ptr<YAMLNode> ValToNode(const atVec4f& val);
template<> template <>
atVec2d NodeToVal(const YAMLNode* node); atVec2d NodeToVal(const YAMLNode* node);
std::unique_ptr <YAMLNode> ValToNode(const atVec2d& val); std::unique_ptr<YAMLNode> ValToNode(const atVec2d& val);
template<> template <>
atVec3d NodeToVal(const YAMLNode* node); atVec3d NodeToVal(const YAMLNode* node);
std::unique_ptr <YAMLNode> ValToNode(const atVec3d& val); std::unique_ptr<YAMLNode> ValToNode(const atVec3d& val);
template<> template <>
atVec4d NodeToVal(const YAMLNode* node); atVec4d NodeToVal(const YAMLNode* node);
std::unique_ptr <YAMLNode> ValToNode(const atVec4d& val); std::unique_ptr<YAMLNode> ValToNode(const atVec4d& val);
template<> template <>
std::unique_ptr<atUint8[]> NodeToVal(const YAMLNode* node); std::unique_ptr<atUint8[]> NodeToVal(const YAMLNode* node);
std::unique_ptr <YAMLNode> ValToNode(const std::unique_ptr<atUint8[]>& val, size_t byteCount); std::unique_ptr<YAMLNode> ValToNode(const std::unique_ptr<atUint8[]>& val, size_t byteCount);
template<> template <>
std::string NodeToVal(const YAMLNode* node); std::string NodeToVal(const YAMLNode* node);
std::unique_ptr <YAMLNode> ValToNode(std::string_view val); std::unique_ptr<YAMLNode> ValToNode(std::string_view val);
template<> template <>
std::wstring NodeToVal(const YAMLNode* node); std::wstring NodeToVal(const YAMLNode* node);
std::unique_ptr <YAMLNode> ValToNode(std::wstring_view val); std::unique_ptr<YAMLNode> ValToNode(std::wstring_view val);
std::unique_ptr <YAMLNode> ValToNode(std::u16string_view val); std::unique_ptr<YAMLNode> ValToNode(std::u16string_view val);
std::unique_ptr <YAMLNode> ValToNode(std::u32string_view val); std::unique_ptr<YAMLNode> ValToNode(std::u32string_view val);
std::string base64_encode(const atUint8* bytes_to_encode, size_t in_len); std::string base64_encode(const atUint8* bytes_to_encode, size_t in_len);
@ -172,28 +162,22 @@ void HandleYAMLParserError(yaml_parser_t* parser);
void HandleYAMLEmitterError(yaml_emitter_t* emitter); void HandleYAMLEmitterError(yaml_emitter_t* emitter);
struct YAMLStdStringViewReaderState struct YAMLStdStringViewReaderState {
{
std::string_view::const_iterator begin; std::string_view::const_iterator begin;
std::string_view::const_iterator end; std::string_view::const_iterator end;
YAMLStdStringViewReaderState(std::string_view str) YAMLStdStringViewReaderState(std::string_view str) {
{
begin = str.begin(); begin = str.begin();
end = str.end(); end = str.end();
} }
}; };
int YAMLStdStringReader(YAMLStdStringViewReaderState* str, int YAMLStdStringReader(YAMLStdStringViewReaderState* str, unsigned char* buffer, size_t size, size_t* size_read);
unsigned char* buffer, size_t size, size_t* size_read);
int YAMLStdStringWriter(std::string* str, unsigned char* buffer, size_t size); int YAMLStdStringWriter(std::string* str, unsigned char* buffer, size_t size);
int YAMLAthenaReader(athena::io::IStreamReader* reader, int YAMLAthenaReader(athena::io::IStreamReader* reader, unsigned char* buffer, size_t size, size_t* size_read);
unsigned char* buffer, size_t size, size_t* size_read);
int YAMLAthenaWriter(athena::io::IStreamWriter* writer, int YAMLAthenaWriter(athena::io::IStreamWriter* writer, unsigned char* buffer, size_t size);
unsigned char* buffer, size_t size);
}
} // namespace athena::io

View File

@ -2,11 +2,9 @@
#include "YAMLCommon.hpp" #include "YAMLCommon.hpp"
namespace athena::io namespace athena::io {
{
class YAMLDocReader class YAMLDocReader {
{
std::unique_ptr<YAMLNode> m_rootNode; std::unique_ptr<YAMLNode> m_rootNode;
std::vector<YAMLNode*> m_subStack; std::vector<YAMLNode*> m_subStack;
std::vector<int> m_seqTrackerStack; std::vector<int> m_seqTrackerStack;
@ -32,57 +30,62 @@ public:
inline const YAMLNode* getCurNode() const { return m_subStack.empty() ? nullptr : m_subStack.back(); } inline const YAMLNode* getCurNode() const { return m_subStack.empty() ? nullptr : m_subStack.back(); }
std::unique_ptr<YAMLNode> releaseRootNode() { return std::move(m_rootNode); } std::unique_ptr<YAMLNode> releaseRootNode() { return std::move(m_rootNode); }
class RecordRAII class RecordRAII {
{
friend class YAMLDocReader; friend class YAMLDocReader;
YAMLDocReader* m_r = nullptr; YAMLDocReader* m_r = nullptr;
RecordRAII(YAMLDocReader* r) : m_r(r) {} RecordRAII(YAMLDocReader* r) : m_r(r) {}
RecordRAII() = default; RecordRAII() = default;
public: public:
operator bool() const { return m_r != nullptr; } operator bool() const { return m_r != nullptr; }
void leave() { if (m_r) {m_r->_leaveSubRecord(); m_r = nullptr;} } void leave() {
~RecordRAII() { if (m_r) m_r->_leaveSubRecord(); } if (m_r) {
m_r->_leaveSubRecord();
m_r = nullptr;
}
}
~RecordRAII() {
if (m_r)
m_r->_leaveSubRecord();
}
}; };
friend class RecordRAII; friend class RecordRAII;
RecordRAII enterSubRecord(const char* name); RecordRAII enterSubRecord(const char* name);
template <class T> template <class T>
void enumerate(const char* name, T& record, void enumerate(const char* name, T& record, typename std::enable_if_t<__IsDNARecord_v<T>>* = 0) {
typename std::enable_if_t<__IsDNARecord_v<T>>* = 0)
{
if (auto rec = enterSubRecord(name)) if (auto rec = enterSubRecord(name))
record.read(*this); record.read(*this);
} }
class VectorRAII class VectorRAII {
{
friend class YAMLDocReader; friend class YAMLDocReader;
YAMLDocReader* m_r = nullptr; YAMLDocReader* m_r = nullptr;
VectorRAII(YAMLDocReader* r) : m_r(r) {} VectorRAII(YAMLDocReader* r) : m_r(r) {}
VectorRAII() = default; VectorRAII() = default;
public: public:
operator bool() const { return m_r != nullptr; } operator bool() const { return m_r != nullptr; }
~VectorRAII() { if (m_r) m_r->_leaveSubVector(); } ~VectorRAII() {
if (m_r)
m_r->_leaveSubVector();
}
}; };
friend class VectorRAII; friend class VectorRAII;
VectorRAII enterSubVector(const char* name, size_t& countOut); VectorRAII enterSubVector(const char* name, size_t& countOut);
template <class T> template <class T>
size_t enumerate(const char* name, std::vector<T>& vector, size_t
typename std::enable_if_t<!std::is_arithmetic<T>::value && enumerate(const char* name, std::vector<T>& vector,
!std::is_same<T, atVec2f>::value && typename std::enable_if_t<!std::is_arithmetic<T>::value && !std::is_same<T, atVec2f>::value &&
!std::is_same<T, atVec3f>::value && !std::is_same<T, atVec3f>::value && !std::is_same<T, atVec4f>::value>* = 0) {
!std::is_same<T, atVec4f>::value>* = 0)
{
size_t countOut; size_t countOut;
if (auto v = enterSubVector(name, countOut)) if (auto v = enterSubVector(name, countOut)) {
{
vector.clear(); vector.clear();
vector.reserve(countOut); vector.reserve(countOut);
for (size_t i=0 ; i<countOut ; ++i) for (size_t i = 0; i < countOut; ++i) {
{
vector.emplace_back(); vector.emplace_back();
if (auto rec = enterSubRecord(nullptr)) if (auto rec = enterSubRecord(nullptr))
vector.back().read(*this); vector.back().read(*this);
@ -93,33 +96,25 @@ public:
template <class T> template <class T>
size_t enumerate(const char* name, std::vector<T>& vector, size_t enumerate(const char* name, std::vector<T>& vector,
typename std::enable_if_t<std::is_arithmetic<T>::value || typename std::enable_if_t<std::is_arithmetic<T>::value || std::is_same<T, atVec2f>::value ||
std::is_same<T, atVec2f>::value || std::is_same<T, atVec3f>::value || std::is_same<T, atVec4f>::value>* = 0) {
std::is_same<T, atVec3f>::value ||
std::is_same<T, atVec4f>::value>* = 0)
{
size_t countOut; size_t countOut;
if (auto v = enterSubVector(name, countOut)) if (auto v = enterSubVector(name, countOut)) {
{
vector.clear(); vector.clear();
vector.reserve(countOut); vector.reserve(countOut);
for (size_t i=0 ; i<countOut ; ++i) for (size_t i = 0; i < countOut; ++i)
vector.push_back(readVal<T>(name)); vector.push_back(readVal<T>(name));
} }
return countOut; return countOut;
} }
template <class T> template <class T>
size_t enumerate(const char* name, std::vector<T>& vector, size_t enumerate(const char* name, std::vector<T>& vector, std::function<void(YAMLDocReader&, T&)> readf) {
std::function<void(YAMLDocReader&, T&)> readf)
{
size_t countOut; size_t countOut;
if (auto v = enterSubVector(name, countOut)) if (auto v = enterSubVector(name, countOut)) {
{
vector.clear(); vector.clear();
vector.reserve(countOut); vector.reserve(countOut);
for (size_t i=0 ; i<countOut ; ++i) for (size_t i = 0; i < countOut; ++i) {
{
vector.emplace_back(); vector.emplace_back();
if (auto rec = enterSubRecord(nullptr)) if (auto rec = enterSubRecord(nullptr))
readf(*this, vector.back()); readf(*this, vector.back());
@ -128,10 +123,8 @@ public:
return countOut; return countOut;
} }
bool hasVal(const char* name) const bool hasVal(const char* name) const {
{ if (m_subStack.size()) {
if (m_subStack.size())
{
const YAMLNode* mnode = m_subStack.back(); const YAMLNode* mnode = m_subStack.back();
if (mnode->m_type == YAML_MAPPING_NODE && name) if (mnode->m_type == YAML_MAPPING_NODE && name)
for (const auto& item : mnode->m_mapChildren) for (const auto& item : mnode->m_mapChildren)
@ -165,5 +158,4 @@ public:
std::wstring readWString(const char* name); std::wstring readWString(const char* name);
}; };
} } // namespace athena::io

View File

@ -2,17 +2,16 @@
#include "YAMLCommon.hpp" #include "YAMLCommon.hpp"
namespace athena::io namespace athena::io {
{
class YAMLDocWriter class YAMLDocWriter {
{
std::unique_ptr<YAMLNode> m_rootNode; std::unique_ptr<YAMLNode> m_rootNode;
std::vector<YAMLNode*> m_subStack; std::vector<YAMLNode*> m_subStack;
yaml_emitter_t m_emitter; yaml_emitter_t m_emitter;
static bool RecursiveFinish(yaml_emitter_t* doc, const YAMLNode& node); static bool RecursiveFinish(yaml_emitter_t* doc, const YAMLNode& node);
void _leaveSubRecord(); void _leaveSubRecord();
void _leaveSubVector(); void _leaveSubVector();
public: public:
YAMLDocWriter(const char* classType, athena::io::IStreamReader* reader = nullptr); YAMLDocWriter(const char* classType, athena::io::IStreamReader* reader = nullptr);
~YAMLDocWriter(); ~YAMLDocWriter();
@ -23,37 +22,41 @@ public:
inline YAMLNode* getCurNode() const { return m_subStack.empty() ? nullptr : m_subStack.back(); } inline YAMLNode* getCurNode() const { return m_subStack.empty() ? nullptr : m_subStack.back(); }
class RecordRAII class RecordRAII {
{
friend class YAMLDocWriter; friend class YAMLDocWriter;
YAMLDocWriter* m_w = nullptr; YAMLDocWriter* m_w = nullptr;
RecordRAII(YAMLDocWriter* w) : m_w(w) {} RecordRAII(YAMLDocWriter* w) : m_w(w) {}
RecordRAII() = default; RecordRAII() = default;
public: public:
operator bool() const { return m_w != nullptr; } operator bool() const { return m_w != nullptr; }
~RecordRAII() { if (m_w) m_w->_leaveSubRecord(); } ~RecordRAII() {
if (m_w)
m_w->_leaveSubRecord();
}
}; };
friend class RecordRAII; friend class RecordRAII;
RecordRAII enterSubRecord(const char* name); RecordRAII enterSubRecord(const char* name);
template <class T> template <class T>
void enumerate(const char* name, T& record, void enumerate(const char* name, T& record, typename std::enable_if_t<__IsDNARecord_v<T>>* = 0) {
typename std::enable_if_t<__IsDNARecord_v<T>>* = 0)
{
if (auto rec = enterSubRecord(name)) if (auto rec = enterSubRecord(name))
record.write(*this); record.write(*this);
} }
class VectorRAII class VectorRAII {
{
friend class YAMLDocWriter; friend class YAMLDocWriter;
YAMLDocWriter* m_w = nullptr; YAMLDocWriter* m_w = nullptr;
VectorRAII(YAMLDocWriter* w) : m_w(w) {} VectorRAII(YAMLDocWriter* w) : m_w(w) {}
VectorRAII() = default; VectorRAII() = default;
public: public:
operator bool() const { return m_w != nullptr; } operator bool() const { return m_w != nullptr; }
~VectorRAII() { if (m_w) m_w->_leaveSubVector(); } ~VectorRAII() {
if (m_w)
m_w->_leaveSubVector();
}
}; };
friend class VectorRAII; friend class VectorRAII;
@ -61,14 +64,10 @@ public:
template <class T> template <class T>
void enumerate(const char* name, const std::vector<T>& vector, void enumerate(const char* name, const std::vector<T>& vector,
typename std::enable_if_t<!std::is_arithmetic<T>::value && typename std::enable_if_t<!std::is_arithmetic<T>::value && !std::is_same<T, atVec2f>::value &&
!std::is_same<T, atVec2f>::value && !std::is_same<T, atVec3f>::value && !std::is_same<T, atVec4f>::value &&
!std::is_same<T, atVec3f>::value && !std::is_same<T, atVec2d>::value && !std::is_same<T, atVec3d>::value &&
!std::is_same<T, atVec4f>::value && !std::is_same<T, atVec4d>::value>* = 0) {
!std::is_same<T, atVec2d>::value &&
!std::is_same<T, atVec3d>::value &&
!std::is_same<T, atVec4d>::value>* = 0)
{
if (auto v = enterSubVector(name)) if (auto v = enterSubVector(name))
for (const T& item : vector) for (const T& item : vector)
if (auto rec = enterSubRecord(nullptr)) if (auto rec = enterSubRecord(nullptr))
@ -77,23 +76,17 @@ public:
template <class T> template <class T>
void enumerate(const char* name, const std::vector<T>& vector, void enumerate(const char* name, const std::vector<T>& vector,
typename std::enable_if_t<std::is_arithmetic<T>::value || typename std::enable_if_t<std::is_arithmetic<T>::value || std::is_same<T, atVec2f>::value ||
std::is_same<T, atVec2f>::value || std::is_same<T, atVec3f>::value || std::is_same<T, atVec4f>::value ||
std::is_same<T, atVec3f>::value || std::is_same<T, atVec2d>::value || std::is_same<T, atVec3d>::value ||
std::is_same<T, atVec4f>::value || std::is_same<T, atVec4d>::value>* = 0) {
std::is_same<T, atVec2d>::value ||
std::is_same<T, atVec3d>::value ||
std::is_same<T, atVec4d>::value>* = 0)
{
if (auto v = enterSubVector(name)) if (auto v = enterSubVector(name))
for (T item : vector) for (T item : vector)
writeVal<T>(nullptr, item); writeVal<T>(nullptr, item);
} }
template <class T> template <class T>
void enumerate(const char* name, const std::vector<T>& vector, void enumerate(const char* name, const std::vector<T>& vector, std::function<void(YAMLDocWriter&, const T&)> writef) {
std::function<void(YAMLDocWriter&, const T&)> writef)
{
if (auto v = enterSubVector(name)) if (auto v = enterSubVector(name))
for (const T& item : vector) for (const T& item : vector)
if (auto rec = enterSubRecord(nullptr)) if (auto rec = enterSubRecord(nullptr))
@ -130,5 +123,4 @@ public:
void setStyle(YAMLNodeStyle s); void setStyle(YAMLNodeStyle s);
}; };
} } // namespace athena::io

View File

@ -2,22 +2,18 @@
#ifndef ZQUEST_HPP #ifndef ZQUEST_HPP
#define ZQUEST_HPP #define ZQUEST_HPP
#include "athena/Global.hpp" #include "athena/Global.hpp"
#include <string> #include <string>
#include <vector> #include <vector>
#include <memory> #include <memory>
#define ZQUEST_VERSION_CHECK(major, minor, revision) \ #define ZQUEST_VERSION_CHECK(major, minor, revision) (major | (minor << 8) | (revision << 16))
(major | (minor << 8) | (revision << 16))
namespace athena namespace athena {
{
/*! /*!
* \brief ZQuestFile is an export format for save data. * \brief ZQuestFile is an export format for save data.
*/ */
class ZQuestFile class ZQuestFile {
{
public: public:
/*! /*!
* \brief The current major version of the ZQuest format * \brief The current major version of the ZQuest format
@ -45,8 +41,7 @@ public:
* \enum Game * \enum Game
* \brief The list of games currently supported by ZQuest * \brief The list of games currently supported by ZQuest
*/ */
enum Game enum Game {
{
NoGame, //!< None or Unsupported NoGame, //!< None or Unsupported
LoZ, //!< Legend of Zelda LoZ, //!< Legend of Zelda
AoL, //!< Adventure of Link AoL, //!< Adventure of Link
@ -84,7 +79,8 @@ public:
* \param data * \param data
* \param length * \param length
*/ */
ZQuestFile(Game game, Endian endian, std::unique_ptr<atUint8[]>&& data, atUint32 length, const std::string& gameString = std::string()); ZQuestFile(Game game, Endian endian, std::unique_ptr<atUint8[]>&& data, atUint32 length,
const std::string& gameString = std::string());
/*! /*!
* \brief setGame * \brief setGame
@ -137,6 +133,7 @@ public:
std::string gameString() const; std::string gameString() const;
static const std::vector<std::string> gameStringList(); static const std::vector<std::string> gameStringList();
protected: protected:
Game m_game; Game m_game;
std::string m_gameString; std::string m_gameString;
@ -146,7 +143,7 @@ protected:
// Game strings support // Game strings support
}; };
} // zelda } // namespace athena
#endif // ZQUEST_HPP #endif // ZQUEST_HPP
#endif // ATHENA_NO_ZQUEST #endif // ATHENA_NO_ZQUEST

View File

@ -4,18 +4,15 @@
#include "athena/MemoryReader.hpp" #include "athena/MemoryReader.hpp"
namespace athena namespace athena {
{
class ZQuestFile; class ZQuestFile;
namespace io namespace io {
{
/*! /*!
* \brief The ZQuestFileReader class * \brief The ZQuestFileReader class
*/ */
class ZQuestFileReader : protected MemoryCopyReader class ZQuestFileReader : protected MemoryCopyReader {
{
public: public:
/*! /*!
@ -38,8 +35,8 @@ public:
ZQuestFile* read(); ZQuestFile* read();
}; };
} // io } // namespace io
} // zelda } // namespace athena
#endif // __ZQUESTFILEREADER_HPP__ #endif // __ZQUESTFILEREADER_HPP__

View File

@ -4,18 +4,15 @@
#include "athena/MemoryWriter.hpp" #include "athena/MemoryWriter.hpp"
namespace athena namespace athena {
{
class ZQuestFile; class ZQuestFile;
namespace io namespace io {
{
/*! /*!
* \brief The ZQuestFileWriter class * \brief The ZQuestFileWriter class
*/ */
class ZQuestFileWriter : protected MemoryCopyWriter class ZQuestFileWriter : protected MemoryCopyWriter {
{
public: public:
/*! /*!
* \brief ZQuestFileWriter * \brief ZQuestFileWriter
@ -38,8 +35,8 @@ public:
void write(ZQuestFile* quest, bool compress = true); void write(ZQuestFile* quest, bool compress = true);
}; };
} // io } // namespace io
} // zelda } // namespace athena
#endif // __ZQUESTFILEWRITER_HPP__ #endif // __ZQUESTFILEWRITER_HPP__
#endif // ATHENA_NO_ZQUEST #endif // ATHENA_NO_ZQUEST

View File

@ -688,21 +688,16 @@ class __simd_storage<_Tp, __simd_abi<_StorageKind::_Scalar, 1>> {
public: public:
_Tp __get(size_t __index) const noexcept { return (&__storage_)[__index]; }; _Tp __get(size_t __index) const noexcept { return (&__storage_)[__index]; };
void __set(size_t __index, _Tp __val) noexcept { void __set(size_t __index, _Tp __val) noexcept { (&__storage_)[__index] = __val; }
(&__storage_)[__index] = __val;
}
}; };
#ifndef _LIBCPP_HAS_NO_VECTOR_EXTENSION #ifndef _LIBCPP_HAS_NO_VECTOR_EXTENSION
constexpr size_t __floor_pow_of_2(size_t __val) { constexpr size_t __floor_pow_of_2(size_t __val) {
return ((__val - 1) & __val) == 0 ? __val return ((__val - 1) & __val) == 0 ? __val : __floor_pow_of_2((__val - 1) & __val);
: __floor_pow_of_2((__val - 1) & __val);
} }
constexpr size_t __ceil_pow_of_2(size_t __val) { constexpr size_t __ceil_pow_of_2(size_t __val) { return __val == 1 ? 1 : __floor_pow_of_2(__val - 1) << 1; }
return __val == 1 ? 1 : __floor_pow_of_2(__val - 1) << 1;
}
template <class _Tp, size_t __bytes> template <class _Tp, size_t __bytes>
struct __vec_ext_traits { struct __vec_ext_traits {
@ -715,8 +710,7 @@ struct __vec_ext_traits {
#define _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, _NUM_ELEMENT) \ #define _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, _NUM_ELEMENT) \
template <> \ template <> \
struct __vec_ext_traits<_TYPE, sizeof(_TYPE) * _NUM_ELEMENT> { \ struct __vec_ext_traits<_TYPE, sizeof(_TYPE) * _NUM_ELEMENT> { \
using type = \ using type = _TYPE __attribute__((vector_size(sizeof(_TYPE) * _NUM_ELEMENT))); \
_TYPE __attribute__((vector_size(sizeof(_TYPE) * _NUM_ELEMENT))); \
} }
#define _LIBCPP_SPECIALIZE_VEC_EXT_32(_TYPE) \ #define _LIBCPP_SPECIALIZE_VEC_EXT_32(_TYPE) \
@ -777,8 +771,7 @@ _LIBCPP_SPECIALIZE_VEC_EXT_32(long double);
template <class _Tp, int __num_element> template <class _Tp, int __num_element>
class __simd_storage<_Tp, __simd_abi<_StorageKind::_VecExt, __num_element>> { class __simd_storage<_Tp, __simd_abi<_StorageKind::_VecExt, __num_element>> {
using _StorageType = using _StorageType = typename __vec_ext_traits<_Tp, sizeof(_Tp) * __num_element>::type;
typename __vec_ext_traits<_Tp, sizeof(_Tp) * __num_element>::type;
_StorageType __storage_; _StorageType __storage_;
@ -790,9 +783,7 @@ class __simd_storage<_Tp, __simd_abi<_StorageKind::_VecExt, __num_element>> {
public: public:
_Tp __get(size_t __index) const noexcept { return __storage_[__index]; }; _Tp __get(size_t __index) const noexcept { return __storage_[__index]; };
void __set(size_t __index, _Tp __val) noexcept { void __set(size_t __index, _Tp __val) noexcept { __storage_[__index] = __val; }
__storage_[__index] = __val;
}
}; };
#endif // _LIBCPP_HAS_NO_VECTOR_EXTENSION #endif // _LIBCPP_HAS_NO_VECTOR_EXTENSION
@ -810,8 +801,7 @@ class __simd_reference {
__simd_storage<_Tp, _Abi>* __ptr_; __simd_storage<_Tp, _Abi>* __ptr_;
size_t __index_; size_t __index_;
__simd_reference(__simd_storage<_Tp, _Abi>* __ptr, size_t __index) __simd_reference(__simd_storage<_Tp, _Abi>* __ptr, size_t __index) : __ptr_(__ptr), __index_(__index) {}
: __ptr_(__ptr), __index_(__index) {}
__simd_reference(const __simd_reference&) = default; __simd_reference(const __simd_reference&) = default;
@ -826,9 +816,7 @@ public:
return *this; return *this;
} }
__simd_reference operator++() && { __simd_reference operator++() && { return std::move(*this) = __ptr_->__get(__index_) + 1; }
return std::move(*this) = __ptr_->__get(__index_) + 1;
}
_Vp operator++(int) && { _Vp operator++(int) && {
auto __val = __ptr_->__get(__index_); auto __val = __ptr_->__get(__index_);
@ -836,9 +824,7 @@ public:
return __val; return __val;
} }
__simd_reference operator--() && { __simd_reference operator--() && { return std::move(*this) = __ptr_->__get(__index_) - 1; }
return std::move(*this) = __ptr_->__get(__index_) - 1;
}
_Vp operator--(int) && { _Vp operator--(int) && {
auto __val = __ptr_->__get(__index_); auto __val = __ptr_->__get(__index_);
@ -846,69 +832,37 @@ public:
return __val; return __val;
} }
__simd_reference operator+=(_Vp __value) && { __simd_reference operator+=(_Vp __value) && { return std::move(*this) = __ptr_->__get(__index_) + __value; }
return std::move(*this) = __ptr_->__get(__index_) + __value;
}
__simd_reference operator-=(_Vp __value) && { __simd_reference operator-=(_Vp __value) && { return std::move(*this) = __ptr_->__get(__index_) - __value; }
return std::move(*this) = __ptr_->__get(__index_) - __value;
}
__simd_reference operator*=(_Vp __value) && { __simd_reference operator*=(_Vp __value) && { return std::move(*this) = __ptr_->__get(__index_) * __value; }
return std::move(*this) = __ptr_->__get(__index_) * __value;
}
__simd_reference operator/=(_Vp __value) && { __simd_reference operator/=(_Vp __value) && { return std::move(*this) = __ptr_->__get(__index_) / __value; }
return std::move(*this) = __ptr_->__get(__index_) / __value;
}
__simd_reference operator%=(_Vp __value) && { __simd_reference operator%=(_Vp __value) && { return std::move(*this) = __ptr_->__get(__index_) % __value; }
return std::move(*this) = __ptr_->__get(__index_) % __value;
}
__simd_reference operator>>=(_Vp __value) && { __simd_reference operator>>=(_Vp __value) && { return std::move(*this) = __ptr_->__get(__index_) >> __value; }
return std::move(*this) = __ptr_->__get(__index_) >> __value;
}
__simd_reference operator<<=(_Vp __value) && { __simd_reference operator<<=(_Vp __value) && { return std::move(*this) = __ptr_->__get(__index_) << __value; }
return std::move(*this) = __ptr_->__get(__index_) << __value;
}
__simd_reference operator&=(_Vp __value) && { __simd_reference operator&=(_Vp __value) && { return std::move(*this) = __ptr_->__get(__index_) & __value; }
return std::move(*this) = __ptr_->__get(__index_) & __value;
}
__simd_reference operator|=(_Vp __value) && { __simd_reference operator|=(_Vp __value) && { return std::move(*this) = __ptr_->__get(__index_) | __value; }
return std::move(*this) = __ptr_->__get(__index_) | __value;
}
__simd_reference operator^=(_Vp __value) && { __simd_reference operator^=(_Vp __value) && { return std::move(*this) = __ptr_->__get(__index_) ^ __value; }
return std::move(*this) = __ptr_->__get(__index_) ^ __value;
}
bool operator<(_Vp __value) const { bool operator<(_Vp __value) const { return __ptr_->__get(__index_) < __value; }
return __ptr_->__get(__index_) < __value;
}
bool operator<=(_Vp __value) const { bool operator<=(_Vp __value) const { return __ptr_->__get(__index_) <= __value; }
return __ptr_->__get(__index_) <= __value;
}
bool operator>(_Vp __value) const { bool operator>(_Vp __value) const { return __ptr_->__get(__index_) > __value; }
return __ptr_->__get(__index_) > __value;
}
bool operator>=(_Vp __value) const { bool operator>=(_Vp __value) const { return __ptr_->__get(__index_) >= __value; }
return __ptr_->__get(__index_) >= __value;
}
bool operator==(_Vp __value) const { bool operator==(_Vp __value) const { return __ptr_->__get(__index_) == __value; }
return __ptr_->__get(__index_) == __value;
}
bool operator!=(_Vp __value) const { bool operator!=(_Vp __value) const { return __ptr_->__get(__index_) != __value; }
return __ptr_->__get(__index_) != __value;
}
}; };
template <class _Tp, class _Abi> template <class _Tp, class _Abi>
@ -922,8 +876,7 @@ class __simd_mask_reference {
__simd_mask_storage<_Tp, _Abi>* __ptr_; __simd_mask_storage<_Tp, _Abi>* __ptr_;
size_t __index_; size_t __index_;
__simd_mask_reference(__simd_mask_storage<_Tp, _Abi>* __ptr, size_t __index) __simd_mask_reference(__simd_mask_storage<_Tp, _Abi>* __ptr, size_t __index) : __ptr_(__ptr), __index_(__index) {}
: __ptr_(__ptr), __index_(__index) {}
__simd_mask_reference(const __simd_mask_reference&) = default; __simd_mask_reference(const __simd_mask_reference&) = default;
@ -940,8 +893,7 @@ public:
}; };
template <class _To, class _From> template <class _To, class _From>
constexpr decltype(_To{std::declval<_From>()}, true) constexpr decltype(_To{std::declval<_From>()}, true) __is_non_narrowing_convertible_impl(_From) {
__is_non_narrowing_convertible_impl(_From) {
return true; return true;
} }
@ -951,17 +903,13 @@ constexpr bool __is_non_narrowing_convertible_impl(...) {
} }
template <class _From, class _To> template <class _From, class _To>
constexpr typename std::enable_if<std::is_arithmetic<_To>::value && constexpr typename std::enable_if<std::is_arithmetic<_To>::value && std::is_arithmetic<_From>::value, bool>::type
std::is_arithmetic<_From>::value,
bool>::type
__is_non_narrowing_arithmetic_convertible() { __is_non_narrowing_arithmetic_convertible() {
return __is_non_narrowing_convertible_impl<_To>(_From{}); return __is_non_narrowing_convertible_impl<_To>(_From{});
} }
template <class _From, class _To> template <class _From, class _To>
constexpr typename std::enable_if<!(std::is_arithmetic<_To>::value && constexpr typename std::enable_if<!(std::is_arithmetic<_To>::value && std::is_arithmetic<_From>::value), bool>::type
std::is_arithmetic<_From>::value),
bool>::type
__is_non_narrowing_arithmetic_convertible() { __is_non_narrowing_arithmetic_convertible() {
return false; return false;
} }
@ -983,11 +931,11 @@ struct __nodeduce {
template <class _Tp> template <class _Tp>
constexpr bool __vectorizable() { constexpr bool __vectorizable() {
return std::is_arithmetic<_Tp>::value && !std::is_const<_Tp>::value && return std::is_arithmetic<_Tp>::value && !std::is_const<_Tp>::value && !std::is_volatile<_Tp>::value &&
!std::is_volatile<_Tp>::value && !std::is_same<_Tp, bool>::value; !std::is_same<_Tp, bool>::value;
} }
} } // namespace athena::_simd
namespace athena::_simd::simd_abi { namespace athena::_simd::simd_abi {
using scalar = __simd_abi<_StorageKind::_Scalar, 1>; using scalar = __simd_abi<_StorageKind::_Scalar, 1>;
@ -1006,11 +954,10 @@ template <class _Tp>
using native = __simd_abi<_StorageKind::_VecExt, 16 / sizeof(_Tp)>; using native = __simd_abi<_StorageKind::_VecExt, 16 / sizeof(_Tp)>;
#else #else
template <class _Tp> template <class _Tp>
using native = using native = fixed_size<_Tp, 16 / sizeof(_Tp)>;
fixed_size<_Tp, 16 / sizeof(_Tp)>;
#endif // _LIBCPP_HAS_NO_VECTOR_EXTENSION #endif // _LIBCPP_HAS_NO_VECTOR_EXTENSION
} } // namespace athena::_simd::simd_abi
namespace athena::_simd { namespace athena::_simd {
template <class _Tp, class _Abi = simd_abi::compatible<_Tp>> template <class _Tp, class _Abi = simd_abi::compatible<_Tp>>
@ -1032,8 +979,7 @@ template <class _Tp>
struct is_abi_tag : std::integral_constant<bool, false> {}; struct is_abi_tag : std::integral_constant<bool, false> {};
template <_StorageKind __kind, int _Np> template <_StorageKind __kind, int _Np>
struct is_abi_tag<__simd_abi<__kind, _Np>> struct is_abi_tag<__simd_abi<__kind, _Np>> : std::integral_constant<bool, true> {};
: std::integral_constant<bool, true> {};
template <class _Tp> template <class _Tp>
struct is_simd : std::integral_constant<bool, false> {}; struct is_simd : std::integral_constant<bool, false> {};
@ -1045,23 +991,19 @@ template <class _Tp>
struct is_simd_mask : std::integral_constant<bool, false> {}; struct is_simd_mask : std::integral_constant<bool, false> {};
template <class _Tp, class _Abi> template <class _Tp, class _Abi>
struct is_simd_mask<simd_mask<_Tp, _Abi>> : std::integral_constant<bool, true> { struct is_simd_mask<simd_mask<_Tp, _Abi>> : std::integral_constant<bool, true> {};
};
template <class _Tp> template <class _Tp>
struct is_simd_flag_type : std::integral_constant<bool, false> {}; struct is_simd_flag_type : std::integral_constant<bool, false> {};
template <> template <>
struct is_simd_flag_type<element_aligned_tag> struct is_simd_flag_type<element_aligned_tag> : std::integral_constant<bool, true> {};
: std::integral_constant<bool, true> {};
template <> template <>
struct is_simd_flag_type<vector_aligned_tag> struct is_simd_flag_type<vector_aligned_tag> : std::integral_constant<bool, true> {};
: std::integral_constant<bool, true> {};
template <size_t _Align> template <size_t _Align>
struct is_simd_flag_type<overaligned_tag<_Align>> struct is_simd_flag_type<overaligned_tag<_Align>> : std::integral_constant<bool, true> {};
: std::integral_constant<bool, true> {};
template <class _Tp> template <class _Tp>
inline constexpr bool is_abi_tag_v = is_abi_tag<_Tp>::value; inline constexpr bool is_abi_tag_v = is_abi_tag<_Tp>::value;
@ -1070,8 +1012,7 @@ inline constexpr bool is_simd_v = is_simd<_Tp>::value;
template <class _Tp> template <class _Tp>
inline constexpr bool is_simd_mask_v = is_simd_mask<_Tp>::value; inline constexpr bool is_simd_mask_v = is_simd_mask<_Tp>::value;
template <class _Tp> template <class _Tp>
inline constexpr bool is_simd_flag_type_v = inline constexpr bool is_simd_flag_type_v = is_simd_flag_type<_Tp>::value;
is_simd_flag_type<_Tp>::value;
template <class _Tp, size_t _Np> template <class _Tp, size_t _Np>
struct abi_for_size { struct abi_for_size {
using type = simd_abi::fixed_size<_Np>; using type = simd_abi::fixed_size<_Np>;
@ -1083,11 +1024,8 @@ template <class _Tp, class _Abi = simd_abi::compatible<_Tp>>
struct simd_size; struct simd_size;
template <class _Tp, _StorageKind __kind, int _Np> template <class _Tp, _StorageKind __kind, int _Np>
struct simd_size<_Tp, __simd_abi<__kind, _Np>> struct simd_size<_Tp, __simd_abi<__kind, _Np>> : std::integral_constant<size_t, _Np> {
: std::integral_constant<size_t, _Np> { static_assert(std::is_arithmetic<_Tp>::value && !std::is_same<typename std::remove_const<_Tp>::type, bool>::value,
static_assert(
std::is_arithmetic<_Tp>::value &&
!std::is_same<typename std::remove_const<_Tp>::type, bool>::value,
"Element type should be vectorizable"); "Element type should be vectorizable");
}; };
@ -1099,8 +1037,7 @@ template <class _Tp, class _Abi = simd_abi::compatible<_Tp>>
inline constexpr size_t simd_size_v = simd_size<_Tp, _Abi>::value; inline constexpr size_t simd_size_v = simd_size<_Tp, _Abi>::value;
template <class _Tp, class _Up = typename _Tp::value_type> template <class _Tp, class _Up = typename _Tp::value_type>
inline constexpr size_t memory_alignment_v = inline constexpr size_t memory_alignment_v = memory_alignment<_Tp, _Up>::value;
memory_alignment<_Tp, _Up>::value;
// class template simd [simd.class] // class template simd [simd.class]
template <class _Tp> template <class _Tp>
@ -1125,50 +1062,41 @@ struct __static_simd_cast_traits {
template <class _Tp, class _NewAbi> template <class _Tp, class _NewAbi>
struct __static_simd_cast_traits<simd<_Tp, _NewAbi>> { struct __static_simd_cast_traits<simd<_Tp, _NewAbi>> {
template <class _Up, class _Abi> template <class _Up, class _Abi>
static typename std::enable_if<simd<_Up, _Abi>::size() == static typename std::enable_if<simd<_Up, _Abi>::size() == simd<_Tp, _NewAbi>::size(), simd<_Tp, _NewAbi>>::type
simd<_Tp, _NewAbi>::size(),
simd<_Tp, _NewAbi>>::type
__apply(const simd<_Up, _Abi>& __v); __apply(const simd<_Up, _Abi>& __v);
}; };
template <class _Tp> template <class _Tp>
struct __simd_cast_traits { struct __simd_cast_traits {
template <class _Up, class _Abi> template <class _Up, class _Abi>
static typename std::enable_if< static typename std::enable_if<__is_non_narrowing_arithmetic_convertible<_Up, _Tp>(), simd<_Tp, _Abi>>::type
__is_non_narrowing_arithmetic_convertible<_Up, _Tp>(),
simd<_Tp, _Abi>>::type
__apply(const simd<_Up, _Abi>& __v); __apply(const simd<_Up, _Abi>& __v);
}; };
template <class _Tp, class _NewAbi> template <class _Tp, class _NewAbi>
struct __simd_cast_traits<simd<_Tp, _NewAbi>> { struct __simd_cast_traits<simd<_Tp, _NewAbi>> {
template <class _Up, class _Abi> template <class _Up, class _Abi>
static typename std::enable_if< static typename std::enable_if<__is_non_narrowing_arithmetic_convertible<_Up, _Tp>() &&
__is_non_narrowing_arithmetic_convertible<_Up, _Tp>() &&
simd<_Up, _Abi>::size() == simd<_Tp, _NewAbi>::size(), simd<_Up, _Abi>::size() == simd<_Tp, _NewAbi>::size(),
simd<_Tp, _NewAbi>>::type simd<_Tp, _NewAbi>>::type
__apply(const simd<_Up, _Abi>& __v); __apply(const simd<_Up, _Abi>& __v);
}; };
template <class _Tp, class _Up, class _Abi> template <class _Tp, class _Up, class _Abi>
auto simd_cast(const simd<_Up, _Abi>& __v) auto simd_cast(const simd<_Up, _Abi>& __v) -> decltype(__simd_cast_traits<_Tp>::__apply(__v)) {
-> decltype(__simd_cast_traits<_Tp>::__apply(__v)) {
return __simd_cast_traits<_Tp>::__apply(__v); return __simd_cast_traits<_Tp>::__apply(__v);
} }
template <class _Tp, class _Up, class _Abi> template <class _Tp, class _Up, class _Abi>
auto static_simd_cast(const simd<_Up, _Abi>& __v) auto static_simd_cast(const simd<_Up, _Abi>& __v) -> decltype(__static_simd_cast_traits<_Tp>::__apply(__v)) {
-> decltype(__static_simd_cast_traits<_Tp>::__apply(__v)) {
return __static_simd_cast_traits<_Tp>::__apply(__v); return __static_simd_cast_traits<_Tp>::__apply(__v);
} }
template <class _Tp, class _Abi> template <class _Tp, class _Abi>
fixed_size_simd<_Tp, simd_size<_Tp, _Abi>::value> fixed_size_simd<_Tp, simd_size<_Tp, _Abi>::value> to_fixed_size(const simd<_Tp, _Abi>&) noexcept;
to_fixed_size(const simd<_Tp, _Abi>&) noexcept;
template <class _Tp, class _Abi> template <class _Tp, class _Abi>
fixed_size_simd_mask<_Tp, simd_size<_Tp, _Abi>::value> fixed_size_simd_mask<_Tp, simd_size<_Tp, _Abi>::value> to_fixed_size(const simd_mask<_Tp, _Abi>&) noexcept;
to_fixed_size(const simd_mask<_Tp, _Abi>&) noexcept;
template <class _Tp, size_t _Np> template <class _Tp, size_t _Np>
native_simd<_Tp> to_native(const fixed_size_simd<_Tp, _Np>&) noexcept; native_simd<_Tp> to_native(const fixed_size_simd<_Tp, _Np>&) noexcept;
@ -1186,26 +1114,21 @@ template <size_t... __sizes, class _Tp, class _Abi>
tuple<simd<_Tp, abi_for_size_t<_Tp, __sizes>>...> split(const simd<_Tp, _Abi>&); tuple<simd<_Tp, abi_for_size_t<_Tp, __sizes>>...> split(const simd<_Tp, _Abi>&);
template <size_t... __sizes, class _Tp, class _Abi> template <size_t... __sizes, class _Tp, class _Abi>
tuple<simd_mask<_Tp, abi_for_size_t<_Tp, __sizes>>...> tuple<simd_mask<_Tp, abi_for_size_t<_Tp, __sizes>>...> split(const simd_mask<_Tp, _Abi>&);
split(const simd_mask<_Tp, _Abi>&);
template <class _SimdType, class _Abi> template <class _SimdType, class _Abi>
array<_SimdType, simd_size<typename _SimdType::value_type, _Abi>::value / array<_SimdType, simd_size<typename _SimdType::value_type, _Abi>::value / _SimdType::size()>
_SimdType::size()>
split(const simd<typename _SimdType::value_type, _Abi>&); split(const simd<typename _SimdType::value_type, _Abi>&);
template <class _SimdType, class _Abi> template <class _SimdType, class _Abi>
array<_SimdType, simd_size<typename _SimdType::value_type, _Abi>::value / array<_SimdType, simd_size<typename _SimdType::value_type, _Abi>::value / _SimdType::size()>
_SimdType::size()>
split(const simd_mask<typename _SimdType::value_type, _Abi>&); split(const simd_mask<typename _SimdType::value_type, _Abi>&);
template <class _Tp, class... _Abis> template <class _Tp, class... _Abis>
simd<_Tp, abi_for_size_t<_Tp, __variadic_sum(simd_size<_Tp, _Abis>::value...)>> simd<_Tp, abi_for_size_t<_Tp, __variadic_sum(simd_size<_Tp, _Abis>::value...)>> concat(const simd<_Tp, _Abis>&...);
concat(const simd<_Tp, _Abis>&...);
template <class _Tp, class... _Abis> template <class _Tp, class... _Abis>
simd_mask<_Tp, simd_mask<_Tp, abi_for_size_t<_Tp, __variadic_sum(simd_size<_Tp, _Abis>::value...)>>
abi_for_size_t<_Tp, __variadic_sum(simd_size<_Tp, _Abis>::value...)>>
concat(const simd_mask<_Tp, _Abis>&...); concat(const simd_mask<_Tp, _Abis>&...);
// reductions [simd.mask.reductions] // reductions [simd.mask.reductions]
@ -1239,23 +1162,20 @@ class where_expression;
// masked assignment [simd.mask.where] // masked assignment [simd.mask.where]
template <class _Tp, class _Abi> template <class _Tp, class _Abi>
where_expression<simd_mask<_Tp, _Abi>, simd<_Tp, _Abi>> where_expression<simd_mask<_Tp, _Abi>, simd<_Tp, _Abi>> where(const typename simd<_Tp, _Abi>::mask_type&,
where(const typename simd<_Tp, _Abi>::mask_type&, simd<_Tp, _Abi>&) noexcept; simd<_Tp, _Abi>&) noexcept;
template <class _Tp, class _Abi> template <class _Tp, class _Abi>
const_where_expression<simd_mask<_Tp, _Abi>, const simd<_Tp, _Abi>> const_where_expression<simd_mask<_Tp, _Abi>, const simd<_Tp, _Abi>> where(const typename simd<_Tp, _Abi>::mask_type&,
where(const typename simd<_Tp, _Abi>::mask_type&,
const simd<_Tp, _Abi>&) noexcept; const simd<_Tp, _Abi>&) noexcept;
template <class _Tp, class _Abi> template <class _Tp, class _Abi>
where_expression<simd_mask<_Tp, _Abi>, simd_mask<_Tp, _Abi>> where_expression<simd_mask<_Tp, _Abi>, simd_mask<_Tp, _Abi>>
where(const typename __nodeduce<simd_mask<_Tp, _Abi>>::type&, where(const typename __nodeduce<simd_mask<_Tp, _Abi>>::type&, simd_mask<_Tp, _Abi>&) noexcept;
simd_mask<_Tp, _Abi>&) noexcept;
template <class _Tp, class _Abi> template <class _Tp, class _Abi>
const_where_expression<simd_mask<_Tp, _Abi>, const simd_mask<_Tp, _Abi>> const_where_expression<simd_mask<_Tp, _Abi>, const simd_mask<_Tp, _Abi>>
where(const typename __nodeduce<simd_mask<_Tp, _Abi>>::type&, where(const typename __nodeduce<simd_mask<_Tp, _Abi>>::type&, const simd_mask<_Tp, _Abi>&) noexcept;
const simd_mask<_Tp, _Abi>&) noexcept;
template <class _Tp> template <class _Tp>
where_expression<bool, _Tp> where(bool, _Tp&) noexcept; where_expression<bool, _Tp> where(bool, _Tp&) noexcept;
@ -1268,45 +1188,37 @@ template <class _Tp, class _Abi, class _BinaryOp = std::plus<_Tp>>
_Tp reduce(const simd<_Tp, _Abi>&, _BinaryOp = _BinaryOp()); _Tp reduce(const simd<_Tp, _Abi>&, _BinaryOp = _BinaryOp());
template <class _MaskType, class _SimdType, class _BinaryOp> template <class _MaskType, class _SimdType, class _BinaryOp>
typename _SimdType::value_type typename _SimdType::value_type reduce(const const_where_expression<_MaskType, _SimdType>&,
reduce(const const_where_expression<_MaskType, _SimdType>&,
typename _SimdType::value_type neutral_element, _BinaryOp binary_op); typename _SimdType::value_type neutral_element, _BinaryOp binary_op);
template <class _MaskType, class _SimdType> template <class _MaskType, class _SimdType>
typename _SimdType::value_type typename _SimdType::value_type reduce(const const_where_expression<_MaskType, _SimdType>&,
reduce(const const_where_expression<_MaskType, _SimdType>&,
plus<typename _SimdType::value_type> binary_op = {}); plus<typename _SimdType::value_type> binary_op = {});
template <class _MaskType, class _SimdType> template <class _MaskType, class _SimdType>
typename _SimdType::value_type typename _SimdType::value_type reduce(const const_where_expression<_MaskType, _SimdType>&,
reduce(const const_where_expression<_MaskType, _SimdType>&,
multiplies<typename _SimdType::value_type> binary_op); multiplies<typename _SimdType::value_type> binary_op);
template <class _MaskType, class _SimdType> template <class _MaskType, class _SimdType>
typename _SimdType::value_type typename _SimdType::value_type reduce(const const_where_expression<_MaskType, _SimdType>&,
reduce(const const_where_expression<_MaskType, _SimdType>&,
bit_and<typename _SimdType::value_type> binary_op); bit_and<typename _SimdType::value_type> binary_op);
template <class _MaskType, class _SimdType> template <class _MaskType, class _SimdType>
typename _SimdType::value_type typename _SimdType::value_type reduce(const const_where_expression<_MaskType, _SimdType>&,
reduce(const const_where_expression<_MaskType, _SimdType>&,
bit_or<typename _SimdType::value_type> binary_op); bit_or<typename _SimdType::value_type> binary_op);
template <class _MaskType, class _SimdType> template <class _MaskType, class _SimdType>
typename _SimdType::value_type typename _SimdType::value_type reduce(const const_where_expression<_MaskType, _SimdType>&,
reduce(const const_where_expression<_MaskType, _SimdType>&,
bit_xor<typename _SimdType::value_type> binary_op); bit_xor<typename _SimdType::value_type> binary_op);
template <class _Tp, class _Abi> template <class _Tp, class _Abi>
_Tp hmin(const simd<_Tp, _Abi>&); _Tp hmin(const simd<_Tp, _Abi>&);
template <class _MaskType, class _SimdType> template <class _MaskType, class _SimdType>
typename _SimdType::value_type typename _SimdType::value_type hmin(const const_where_expression<_MaskType, _SimdType>&);
hmin(const const_where_expression<_MaskType, _SimdType>&);
template <class _Tp, class _Abi> template <class _Tp, class _Abi>
_Tp hmax(const simd<_Tp, _Abi>&); _Tp hmax(const simd<_Tp, _Abi>&);
template <class _MaskType, class _SimdType> template <class _MaskType, class _SimdType>
typename _SimdType::value_type typename _SimdType::value_type hmax(const const_where_expression<_MaskType, _SimdType>&);
hmax(const const_where_expression<_MaskType, _SimdType>&);
// algorithms [simd.alg] // algorithms [simd.alg]
template <class _Tp, class _Abi> template <class _Tp, class _Abi>
@ -1316,12 +1228,10 @@ template <class _Tp, class _Abi>
simd<_Tp, _Abi> max(const simd<_Tp, _Abi>&, const simd<_Tp, _Abi>&) noexcept; simd<_Tp, _Abi> max(const simd<_Tp, _Abi>&, const simd<_Tp, _Abi>&) noexcept;
template <class _Tp, class _Abi> template <class _Tp, class _Abi>
std::pair<simd<_Tp, _Abi>, simd<_Tp, _Abi>> std::pair<simd<_Tp, _Abi>, simd<_Tp, _Abi>> minmax(const simd<_Tp, _Abi>&, const simd<_Tp, _Abi>&) noexcept;
minmax(const simd<_Tp, _Abi>&, const simd<_Tp, _Abi>&) noexcept;
template <class _Tp, class _Abi> template <class _Tp, class _Abi>
simd<_Tp, _Abi> clamp(const simd<_Tp, _Abi>&, const simd<_Tp, _Abi>&, simd<_Tp, _Abi> clamp(const simd<_Tp, _Abi>&, const simd<_Tp, _Abi>&, const simd<_Tp, _Abi>&);
const simd<_Tp, _Abi>&);
// [simd.whereexpr] // [simd.whereexpr]
// TODO implement where expressions. // TODO implement where expressions.
@ -1387,6 +1297,7 @@ public:
auto end() { return std::end(__data_); } auto end() { return std::end(__data_); }
auto begin() const { return std::begin(__data_); } auto begin() const { return std::begin(__data_); }
auto end() const { return std::end(__data_); } auto end() const { return std::end(__data_); }
private: private:
value_type __data_[_Simd::size()]; value_type __data_[_Simd::size()];
}; };
@ -1396,6 +1307,7 @@ template <class _Tp, class _Abi>
class simd { class simd {
template <class _Up, class _UAbi> template <class _Up, class _UAbi>
friend class simd; friend class simd;
public: public:
using value_type = _Tp; using value_type = _Tp;
using reference = __simd_reference<_Tp, _Tp, _Abi>; using reference = __simd_reference<_Tp, _Tp, _Abi>;
@ -1406,34 +1318,25 @@ public:
simd(const simd&) = default; simd(const simd&) = default;
simd& operator=(const simd&) = default; simd& operator=(const simd&) = default;
static constexpr size_t size() noexcept { static constexpr size_t size() noexcept { return simd_size<_Tp, _Abi>::value; }
return simd_size<_Tp, _Abi>::value;
}
private: private:
__simd_storage<_Tp, _Abi> __s_; __simd_storage<_Tp, _Abi> __s_;
template <class _Up> template <class _Up>
static constexpr bool __can_broadcast() { static constexpr bool __can_broadcast() {
return (std::is_arithmetic<_Up>::value && return (std::is_arithmetic<_Up>::value && __is_non_narrowing_arithmetic_convertible<_Up, _Tp>()) ||
__is_non_narrowing_arithmetic_convertible<_Up, _Tp>()) || (!std::is_arithmetic<_Up>::value && std::is_convertible<_Up, _Tp>::value) ||
(!std::is_arithmetic<_Up>::value &&
std::is_convertible<_Up, _Tp>::value) ||
std::is_same<typename std::remove_const<_Up>::type, int>::value || std::is_same<typename std::remove_const<_Up>::type, int>::value ||
(std::is_same<typename std::remove_const<_Up>::type, (std::is_same<typename std::remove_const<_Up>::type, unsigned int>::value && std::is_unsigned<_Tp>::value);
unsigned int>::value &&
std::is_unsigned<_Tp>::value);
} }
template <class _Generator, size_t... __indicies> template <class _Generator, size_t... __indicies>
static constexpr decltype( static constexpr decltype(
std::forward_as_tuple(std::declval<_Generator>()( std::forward_as_tuple(std::declval<_Generator>()(std::integral_constant<size_t, __indicies>())...), bool())
std::integral_constant<size_t, __indicies>())...),
bool())
__can_generate(std::index_sequence<__indicies...>) { __can_generate(std::index_sequence<__indicies...>) {
return !__variadic_sum<bool>( return !__variadic_sum<bool>(
!__can_broadcast<decltype(std::declval<_Generator>()( !__can_broadcast<decltype(std::declval<_Generator>()(std::integral_constant<size_t, __indicies>()))>()...);
std::integral_constant<size_t, __indicies>()))>()...);
} }
template <class _Generator> template <class _Generator>
@ -1443,9 +1346,7 @@ private:
template <class _Generator, size_t... __indicies> template <class _Generator, size_t... __indicies>
void __generator_init(_Generator&& __g, std::index_sequence<__indicies...>) { void __generator_init(_Generator&& __g, std::index_sequence<__indicies...>) {
int __not_used[]{((*this)[__indicies] = int __not_used[]{((*this)[__indicies] = __g(std::integral_constant<size_t, __indicies>()), 0)...};
__g(std::integral_constant<size_t, __indicies>()),
0)...};
(void)__not_used; (void)__not_used;
} }
@ -1466,8 +1367,8 @@ public:
#endif #endif
// implicit type conversion constructor // implicit type conversion constructor
template <class _Up, class _UAbi, template <class _Up, class _UAbi,
class = typename std::enable_if<std::is_constructible< class = typename std::enable_if<
__simd_storage<_Tp, _Abi>, __simd_storage<_Up, _UAbi>>::value>> std::is_constructible<__simd_storage<_Tp, _Abi>, __simd_storage<_Up, _UAbi>>::value>>
simd(const simd<_Up, _UAbi>& __v) : __s_(__v.__s_) {} simd(const simd<_Up, _UAbi>& __v) : __s_(__v.__s_) {}
#if 0 #if 0
@ -1489,28 +1390,19 @@ public:
__s_.__broadcast(v); __s_.__broadcast(v);
} }
#endif #endif
simd(_Tp __rv) { simd(_Tp __rv) { __s_.__broadcast(__rv); }
__s_.__broadcast(__rv);
}
simd(_Tp a, _Tp b, _Tp c = {}, _Tp d = {}) { simd(_Tp a, _Tp b, _Tp c = {}, _Tp d = {}) { __s_.__set4(a, b, c, d); }
__s_.__set4(a, b, c, d);
}
// generator constructor // generator constructor
template <class _Generator, template <class _Generator,
int = typename std::enable_if< int = typename std::enable_if<__can_generate<_Generator>(std::make_index_sequence<size()>()), int>::type()>
__can_generate<_Generator>(std::make_index_sequence<size()>()),
int>::type()>
explicit simd(_Generator&& __g) { explicit simd(_Generator&& __g) {
__generator_init(std::forward<_Generator>(__g), __generator_init(std::forward<_Generator>(__g), std::make_index_sequence<size()>());
std::make_index_sequence<size()>());
} }
// load constructor // load constructor
template < template <class _Up, class _Flags, class = typename std::enable_if<__vectorizable<_Up>()>::type,
class _Up, class _Flags,
class = typename std::enable_if<__vectorizable<_Up>()>::type,
class = typename std::enable_if<is_simd_flag_type<_Flags>::value>::type> class = typename std::enable_if<is_simd_flag_type<_Flags>::value>::type>
simd(const _Up* __buffer, _Flags) { simd(const _Up* __buffer, _Flags) {
// TODO: optimize for overaligned flags // TODO: optimize for overaligned flags
@ -1529,9 +1421,7 @@ public:
} }
#endif #endif
// loads [simd.load] // loads [simd.load]
void copy_from(const simd_data<simd>& __buffer) { void copy_from(const simd_data<simd>& __buffer) { __s_.__copy_from(__buffer); }
__s_.__copy_from(__buffer);
}
#if 0 #if 0
// stores [simd.store] // stores [simd.store]
@ -1546,9 +1436,7 @@ public:
} }
#endif #endif
// stores [simd.store] // stores [simd.store]
void copy_to(simd_data<simd>& __buffer) const { void copy_to(simd_data<simd>& __buffer) const { __s_.__copy_to(__buffer); }
__s_.__copy_to(__buffer);
}
// scalar access [simd.subscr] // scalar access [simd.subscr]
reference operator[](size_t __i) { return reference(&__s_, __i); } reference operator[](size_t __i) { return reference(&__s_, __i); }
@ -1606,7 +1494,7 @@ public:
value_type dot3(const simd& other) const { return __s_.__dot3(other.__s_); } value_type dot3(const simd& other) const { return __s_.__dot3(other.__s_); }
value_type dot4(const simd& other) const { return __s_.__dot4(other.__s_); } value_type dot4(const simd& other) const { return __s_.__dot4(other.__s_); }
template<int x, int y, int z, int w> template <int x, int y, int z, int w>
simd shuffle() const { simd shuffle() const {
simd s; simd s;
s.__s_ = __s_.template __shuffle<x, y, z, w>(); s.__s_ = __s_.template __shuffle<x, y, z, w>();
@ -1624,9 +1512,7 @@ public:
using reference = __simd_mask_reference<_Tp, _Abi>; using reference = __simd_mask_reference<_Tp, _Abi>;
using simd_type = simd<_Tp, _Abi>; using simd_type = simd<_Tp, _Abi>;
using abi_type = _Abi; using abi_type = _Abi;
static constexpr size_t size() noexcept { static constexpr size_t size() noexcept { return simd_size<_Tp, _Abi>::value; }
return simd_size<_Tp, _Abi>::value;
}
simd_mask() = default; simd_mask() = default;
// broadcast constructor // broadcast constructor
@ -1683,12 +1569,15 @@ public:
}; };
template <class _Simd> template <class _Simd>
inline simd_data<_Simd>::simd_data(const _Simd& s) { s.copy_to(*this); } inline simd_data<_Simd>::simd_data(const _Simd& s) {
s.copy_to(*this);
}
template <class _Tp, int __num_element> template <class _Tp, int __num_element>
class __simd_storage<_Tp, __simd_abi<_StorageKind::_Array, __num_element>> { class __simd_storage<_Tp, __simd_abi<_StorageKind::_Array, __num_element>> {
public: public:
using storage_type = std::array<_Tp, __num_element>; using storage_type = std::array<_Tp, __num_element>;
private: private:
storage_type __storage_; storage_type __storage_;
@ -1700,34 +1589,26 @@ private:
public: public:
_Tp __get(size_t __index) const noexcept { return __storage_[__index]; }; _Tp __get(size_t __index) const noexcept { return __storage_[__index]; };
void __set(size_t __index, _Tp __val) noexcept { void __set(size_t __index, _Tp __val) noexcept { __storage_[__index] = __val; }
__storage_[__index] = __val;
}
std::enable_if_t<__num_element >= 4> __set4(float a, float b, float c, float d) noexcept { std::enable_if_t<__num_element >= 4> __set4(float a, float b, float c, float d) noexcept {
__storage_[0] = a; __storage_[0] = a;
__storage_[1] = b; __storage_[1] = b;
__storage_[2] = c; __storage_[2] = c;
__storage_[3] = d; __storage_[3] = d;
} }
void __broadcast(float __val) noexcept { void __broadcast(float __val) noexcept { std::fill(__storage_.begin(), __storage_.end(), __val); }
std::fill(__storage_.begin(), __storage_.end(), __val);
}
std::enable_if_t<__num_element >= 2, _Tp> __dot2(const __simd_storage& other) const noexcept { std::enable_if_t<__num_element >= 2, _Tp> __dot2(const __simd_storage& other) const noexcept {
return __storage_[0] * other.__storage_[0] + return __storage_[0] * other.__storage_[0] + __storage_[1] * other.__storage_[1];
__storage_[1] * other.__storage_[1];
} }
std::enable_if_t<__num_element >= 3, _Tp> __dot3(const __simd_storage& other) const noexcept { std::enable_if_t<__num_element >= 3, _Tp> __dot3(const __simd_storage& other) const noexcept {
return __storage_[0] * other.__storage_[0] + return __storage_[0] * other.__storage_[0] + __storage_[1] * other.__storage_[1] +
__storage_[1] * other.__storage_[1] +
__storage_[2] * other.__storage_[2]; __storage_[2] * other.__storage_[2];
} }
std::enable_if_t<__num_element >= 4, _Tp> __dot4(const __simd_storage& other) const noexcept { std::enable_if_t<__num_element >= 4, _Tp> __dot4(const __simd_storage& other) const noexcept {
return __storage_[0] * other.__storage_[0] + return __storage_[0] * other.__storage_[0] + __storage_[1] * other.__storage_[1] +
__storage_[1] * other.__storage_[1] + __storage_[2] * other.__storage_[2] + __storage_[3] * other.__storage_[3];
__storage_[2] * other.__storage_[2] +
__storage_[3] * other.__storage_[3];
} }
template<int x, int y, int z, int w> template <int x, int y, int z, int w>
std::enable_if_t<__num_element >= 4, __simd_storage> __shuffle() const noexcept { std::enable_if_t<__num_element >= 4, __simd_storage> __shuffle() const noexcept {
__simd_storage s; __simd_storage s;
s.__storage_[0] = __storage_[x]; s.__storage_[0] = __storage_[x];
@ -1756,13 +1637,10 @@ public:
template <class _Tp, int __num_element> template <class _Tp, int __num_element>
class __simd_mask_storage<_Tp, __simd_abi<_StorageKind::_Array, __num_element>> { class __simd_mask_storage<_Tp, __simd_abi<_StorageKind::_Array, __num_element>> {
std::bitset<__num_element> __storage_; std::bitset<__num_element> __storage_;
public: public:
bool __get(size_t __index) const noexcept { bool __get(size_t __index) const noexcept { return __storage_.test(__index); }
return __storage_.test(__index); void __set(size_t __index, bool __val) noexcept { __storage_.set(__index, __val); }
}
void __set(size_t __index, bool __val) noexcept {
__storage_.set(__index, __val);
}
}; };
} } // namespace athena::_simd

View File

@ -1,6 +1,8 @@
#pragma once #pragma once
#define _ATHENA_SIMD_INCLUDED #define _ATHENA_SIMD_INCLUDED
namespace athena::_simd { using namespace std; } namespace athena::_simd {
using namespace std;
}
#include "parallelism_v2_simd.hpp" #include "parallelism_v2_simd.hpp"
#if _M_IX86_FP >= 1 || _M_X64 #if _M_IX86_FP >= 1 || _M_X64
#define __SSE__ 1 #define __SSE__ 1
@ -11,16 +13,23 @@ namespace athena::_simd { using namespace std; }
#include "simd_sse.hpp" #include "simd_sse.hpp"
#else #else
namespace simd_abi { namespace simd_abi {
template<typename T> struct athena_native {}; template <typename T>
template<> struct athena_native<float> { using type = fixed_size<4>; }; struct athena_native {};
template<> struct athena_native<double> { using type = fixed_size<4>; }; template <>
} struct athena_native<float> {
using type = fixed_size<4>;
};
template <>
struct athena_native<double> {
using type = fixed_size<4>;
};
} // namespace simd_abi
#endif #endif
namespace athena { namespace athena {
template<typename T> using simd = _simd::simd<T, template <typename T>
typename _simd::simd_abi::athena_native<T>::type>; using simd = _simd::simd<T, typename _simd::simd_abi::athena_native<T>::type>;
template<typename T> template <typename T>
using simd_values = _simd::simd_data<simd<T>>; using simd_values = _simd::simd_data<simd<T>>;
using simd_floats = simd_values<float>; using simd_floats = simd_values<float>;
using simd_doubles = simd_values<double>; using simd_doubles = simd_values<double>;
} } // namespace athena

View File

@ -6,7 +6,7 @@
#include <immintrin.h> #include <immintrin.h>
namespace athena::_simd { namespace athena::_simd {
// __m256d storage for AVX // __m256d storage for AVX
template<> template <>
class __simd_storage<double, m256d_abi> { class __simd_storage<double, m256d_abi> {
public: public:
using storage_type = __m256d; using storage_type = __m256d;
@ -22,12 +22,8 @@ public:
sse_data[__index] = __val; sse_data[__index] = __val;
__storage_ = _mm256_load_pd(sse_data.data()); __storage_ = _mm256_load_pd(sse_data.data());
} }
void __set4(double a, double b, double c, double d) noexcept { void __set4(double a, double b, double c, double d) noexcept { __storage_ = _mm256_set_pd(d, c, b, a); }
__storage_ = _mm256_set_pd(d, c, b, a); void __broadcast(double __val) noexcept { __storage_ = _mm256_set1_pd(__val); }
}
void __broadcast(double __val) noexcept {
__storage_ = _mm256_set1_pd(__val);
}
double __dot2(const __simd_storage<double, m256d_abi>& other) const noexcept { double __dot2(const __simd_storage<double, m256d_abi>& other) const noexcept {
alignas(32) std::array<double, 4> sse_data; alignas(32) std::array<double, 4> sse_data;
_mm256_store_pd(sse_data.data(), _mm256_mul_pd(__storage_, other.__storage_)); _mm256_store_pd(sse_data.data(), _mm256_mul_pd(__storage_, other.__storage_));
@ -61,7 +57,7 @@ public:
const storage_type& __native() const { return __storage_; } const storage_type& __native() const { return __storage_; }
}; };
// __m256d mask storage for AVX // __m256d mask storage for AVX
template<> template <>
class __simd_mask_storage<double, m256d_abi> : public __simd_storage<double, m256d_abi> { class __simd_mask_storage<double, m256d_abi> : public __simd_storage<double, m256d_abi> {
public: public:
bool __get(size_t __index) const noexcept { bool __get(size_t __index) const noexcept {
@ -83,95 +79,87 @@ inline simd<double, m256d_abi> simd<double, m256d_abi>::operator-() const {
return _mm256_xor_pd(__s_.__storage_, _mm256_set1_pd(-0.0)); return _mm256_xor_pd(__s_.__storage_, _mm256_set1_pd(-0.0));
} }
inline simd<double, m256d_abi> inline simd<double, m256d_abi> operator+(const simd<double, m256d_abi>& a, const simd<double, m256d_abi>& b) {
operator+(const simd<double, m256d_abi>& a, const simd<double, m256d_abi>& b) {
simd<double, m256d_abi> ret; simd<double, m256d_abi> ret;
ret.__s_.__storage_ = _mm256_add_pd(a.__s_.__storage_, b.__s_.__storage_); ret.__s_.__storage_ = _mm256_add_pd(a.__s_.__storage_, b.__s_.__storage_);
return ret; return ret;
} }
inline simd<double, m256d_abi> inline simd<double, m256d_abi> operator-(const simd<double, m256d_abi>& a, const simd<double, m256d_abi>& b) {
operator-(const simd<double, m256d_abi>& a, const simd<double, m256d_abi>& b) {
simd<double, m256d_abi> ret; simd<double, m256d_abi> ret;
ret.__s_.__storage_ = _mm256_sub_pd(a.__s_.__storage_, b.__s_.__storage_); ret.__s_.__storage_ = _mm256_sub_pd(a.__s_.__storage_, b.__s_.__storage_);
return ret; return ret;
} }
inline simd<double, m256d_abi> inline simd<double, m256d_abi> operator*(const simd<double, m256d_abi>& a, const simd<double, m256d_abi>& b) {
operator*(const simd<double, m256d_abi>& a, const simd<double, m256d_abi>& b) {
simd<double, m256d_abi> ret; simd<double, m256d_abi> ret;
ret.__s_.__storage_ = _mm256_mul_pd(a.__s_.__storage_, b.__s_.__storage_); ret.__s_.__storage_ = _mm256_mul_pd(a.__s_.__storage_, b.__s_.__storage_);
return ret; return ret;
} }
inline simd<double, m256d_abi> inline simd<double, m256d_abi> operator/(const simd<double, m256d_abi>& a, const simd<double, m256d_abi>& b) {
operator/(const simd<double, m256d_abi>& a, const simd<double, m256d_abi>& b) {
simd<double, m256d_abi> ret; simd<double, m256d_abi> ret;
ret.__s_.__storage_ = _mm256_div_pd(a.__s_.__storage_, b.__s_.__storage_); ret.__s_.__storage_ = _mm256_div_pd(a.__s_.__storage_, b.__s_.__storage_);
return ret; return ret;
} }
inline simd<double, m256d_abi>& inline simd<double, m256d_abi>& operator+=(simd<double, m256d_abi>& a, const simd<double, m256d_abi>& b) {
operator+=(simd<double, m256d_abi>& a, const simd<double, m256d_abi>& b) {
a.__s_.__storage_ = _mm256_add_pd(a.__s_.__storage_, b.__s_.__storage_); a.__s_.__storage_ = _mm256_add_pd(a.__s_.__storage_, b.__s_.__storage_);
return a; return a;
} }
inline simd<double, m256d_abi>& inline simd<double, m256d_abi>& operator-=(simd<double, m256d_abi>& a, const simd<double, m256d_abi>& b) {
operator-=(simd<double, m256d_abi>& a, const simd<double, m256d_abi>& b) {
a.__s_.__storage_ = _mm256_sub_pd(a.__s_.__storage_, b.__s_.__storage_); a.__s_.__storage_ = _mm256_sub_pd(a.__s_.__storage_, b.__s_.__storage_);
return a; return a;
} }
inline simd<double, m256d_abi>& inline simd<double, m256d_abi>& operator*=(simd<double, m256d_abi>& a, const simd<double, m256d_abi>& b) {
operator*=(simd<double, m256d_abi>& a, const simd<double, m256d_abi>& b) {
a.__s_.__storage_ = _mm256_mul_pd(a.__s_.__storage_, b.__s_.__storage_); a.__s_.__storage_ = _mm256_mul_pd(a.__s_.__storage_, b.__s_.__storage_);
return a; return a;
} }
inline simd<double, m256d_abi>& inline simd<double, m256d_abi>& operator/=(simd<double, m256d_abi>& a, const simd<double, m256d_abi>& b) {
operator/=(simd<double, m256d_abi>& a, const simd<double, m256d_abi>& b) {
a.__s_.__storage_ = _mm256_div_pd(a.__s_.__storage_, b.__s_.__storage_); a.__s_.__storage_ = _mm256_div_pd(a.__s_.__storage_, b.__s_.__storage_);
return a; return a;
} }
inline simd<double, m256d_abi>::mask_type inline simd<double, m256d_abi>::mask_type operator==(const simd<double, m256d_abi>& a,
operator==(const simd<double, m256d_abi>& a, const simd<double, m256d_abi>& b) { const simd<double, m256d_abi>& b) {
simd<double, m256d_abi>::mask_type ret; simd<double, m256d_abi>::mask_type ret;
ret.__s_.__storage_ = _mm256_cmp_pd(a.__s_.__storage_, b.__s_.__storage_, _CMP_EQ_OQ); ret.__s_.__storage_ = _mm256_cmp_pd(a.__s_.__storage_, b.__s_.__storage_, _CMP_EQ_OQ);
return ret; return ret;
} }
inline simd<double, m256d_abi>::mask_type inline simd<double, m256d_abi>::mask_type operator!=(const simd<double, m256d_abi>& a,
operator!=(const simd<double, m256d_abi>& a, const simd<double, m256d_abi>& b) { const simd<double, m256d_abi>& b) {
simd<double, m256d_abi>::mask_type ret; simd<double, m256d_abi>::mask_type ret;
ret.__s_.__storage_ = _mm256_cmp_pd(a.__s_.__storage_, b.__s_.__storage_, _CMP_NEQ_OQ); ret.__s_.__storage_ = _mm256_cmp_pd(a.__s_.__storage_, b.__s_.__storage_, _CMP_NEQ_OQ);
return ret; return ret;
} }
inline simd<double, m256d_abi>::mask_type inline simd<double, m256d_abi>::mask_type operator>=(const simd<double, m256d_abi>& a,
operator>=(const simd<double, m256d_abi>& a, const simd<double, m256d_abi>& b) { const simd<double, m256d_abi>& b) {
simd<double, m256d_abi>::mask_type ret; simd<double, m256d_abi>::mask_type ret;
ret.__s_.__storage_ = _mm256_cmp_pd(a.__s_.__storage_, b.__s_.__storage_, _CMP_GE_OQ); ret.__s_.__storage_ = _mm256_cmp_pd(a.__s_.__storage_, b.__s_.__storage_, _CMP_GE_OQ);
return ret; return ret;
} }
inline simd<double, m256d_abi>::mask_type inline simd<double, m256d_abi>::mask_type operator<=(const simd<double, m256d_abi>& a,
operator<=(const simd<double, m256d_abi>& a, const simd<double, m256d_abi>& b) { const simd<double, m256d_abi>& b) {
simd<double, m256d_abi>::mask_type ret; simd<double, m256d_abi>::mask_type ret;
ret.__s_.__storage_ = _mm256_cmp_pd(a.__s_.__storage_, b.__s_.__storage_, _CMP_LE_OQ); ret.__s_.__storage_ = _mm256_cmp_pd(a.__s_.__storage_, b.__s_.__storage_, _CMP_LE_OQ);
return ret; return ret;
} }
inline simd<double, m256d_abi>::mask_type inline simd<double, m256d_abi>::mask_type operator>(const simd<double, m256d_abi>& a,
operator>(const simd<double, m256d_abi>& a, const simd<double, m256d_abi>& b) { const simd<double, m256d_abi>& b) {
simd<double, m256d_abi>::mask_type ret; simd<double, m256d_abi>::mask_type ret;
ret.__s_.__storage_ = _mm256_cmp_pd(a.__s_.__storage_, b.__s_.__storage_, _CMP_GT_OQ); ret.__s_.__storage_ = _mm256_cmp_pd(a.__s_.__storage_, b.__s_.__storage_, _CMP_GT_OQ);
return ret; return ret;
} }
inline simd<double, m256d_abi>::mask_type inline simd<double, m256d_abi>::mask_type operator<(const simd<double, m256d_abi>& a,
operator<(const simd<double, m256d_abi>& a, const simd<double, m256d_abi>& b) { const simd<double, m256d_abi>& b) {
simd<double, m256d_abi>::mask_type ret; simd<double, m256d_abi>::mask_type ret;
ret.__s_.__storage_ = _mm256_cmp_pd(a.__s_.__storage_, b.__s_.__storage_, _CMP_LT_OQ); ret.__s_.__storage_ = _mm256_cmp_pd(a.__s_.__storage_, b.__s_.__storage_, _CMP_LT_OQ);
return ret; return ret;
@ -182,7 +170,10 @@ inline __simd_storage<float, m128_abi>::__simd_storage(const __simd_storage<doub
} }
namespace simd_abi { namespace simd_abi {
template<> struct athena_native<double> { using type = m256d_abi; }; template <>
struct athena_native<double> {
using type = m256d_abi;
};
} // namespace simd_abi } // namespace simd_abi
} // namespace athena::_simd } // namespace athena::_simd

View File

@ -40,12 +40,8 @@ public:
sse_data[__index] = __val; sse_data[__index] = __val;
__storage_ = _mm_load_ps(sse_data.data()); __storage_ = _mm_load_ps(sse_data.data());
} }
void __set4(float a, float b, float c, float d) noexcept { void __set4(float a, float b, float c, float d) noexcept { __storage_ = _mm_set_ps(d, c, b, a); }
__storage_ = _mm_set_ps(d, c, b, a); void __broadcast(float __val) noexcept { __storage_ = _mm_set1_ps(__val); }
}
void __broadcast(float __val) noexcept {
__storage_ = _mm_set1_ps(__val);
}
float __dot2(const __simd_storage<float, m128_abi>& other) const noexcept { float __dot2(const __simd_storage<float, m128_abi>& other) const noexcept {
#if __SSE4_1__ #if __SSE4_1__
float ret; float ret;
@ -79,7 +75,7 @@ public:
return sse_data[0] + sse_data[1] + sse_data[2] + sse_data[3]; return sse_data[0] + sse_data[1] + sse_data[2] + sse_data[3];
#endif #endif
} }
template<int x, int y, int z, int w> template <int x, int y, int z, int w>
__simd_storage __shuffle() const noexcept { __simd_storage __shuffle() const noexcept {
__simd_storage s; __simd_storage s;
s.__storage_ = _mm_shuffle_ps(__storage_, __storage_, _MM_SHUFFLE(w, z, y, x)); s.__storage_ = _mm_shuffle_ps(__storage_, __storage_, _MM_SHUFFLE(w, z, y, x));
@ -105,8 +101,7 @@ public:
}; };
// __m128 mask storage for SSE2+ // __m128 mask storage for SSE2+
template <> template <>
class __simd_mask_storage<float, m128_abi> : public __simd_storage<float, m128_abi> class __simd_mask_storage<float, m128_abi> : public __simd_storage<float, m128_abi> {
{
public: public:
bool __get(size_t __index) const noexcept { bool __get(size_t __index) const noexcept {
alignas(16) uint32_t sse_data[4]; alignas(16) uint32_t sse_data[4];
@ -126,95 +121,81 @@ inline simd<float, m128_abi> simd<float, m128_abi>::operator-() const {
return _mm_xor_ps(__s_.__storage_, _mm_set1_ps(-0.f)); return _mm_xor_ps(__s_.__storage_, _mm_set1_ps(-0.f));
} }
inline simd<float, m128_abi> inline simd<float, m128_abi> operator+(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
operator+(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
simd<float, m128_abi> ret; simd<float, m128_abi> ret;
ret.__s_.__storage_ = _mm_add_ps(a.__s_.__storage_, b.__s_.__storage_); ret.__s_.__storage_ = _mm_add_ps(a.__s_.__storage_, b.__s_.__storage_);
return ret; return ret;
} }
inline simd<float, m128_abi> inline simd<float, m128_abi> operator-(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
operator-(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
simd<float, m128_abi> ret; simd<float, m128_abi> ret;
ret.__s_.__storage_ = _mm_sub_ps(a.__s_.__storage_, b.__s_.__storage_); ret.__s_.__storage_ = _mm_sub_ps(a.__s_.__storage_, b.__s_.__storage_);
return ret; return ret;
} }
inline simd<float, m128_abi> inline simd<float, m128_abi> operator*(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
operator*(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
simd<float, m128_abi> ret; simd<float, m128_abi> ret;
ret.__s_.__storage_ = _mm_mul_ps(a.__s_.__storage_, b.__s_.__storage_); ret.__s_.__storage_ = _mm_mul_ps(a.__s_.__storage_, b.__s_.__storage_);
return ret; return ret;
} }
inline simd<float, m128_abi> inline simd<float, m128_abi> operator/(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
operator/(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
simd<float, m128_abi> ret; simd<float, m128_abi> ret;
ret.__s_.__storage_ = _mm_div_ps(a.__s_.__storage_, b.__s_.__storage_); ret.__s_.__storage_ = _mm_div_ps(a.__s_.__storage_, b.__s_.__storage_);
return ret; return ret;
} }
inline simd<float, m128_abi>& inline simd<float, m128_abi>& operator+=(simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
operator+=(simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
a.__s_.__storage_ = _mm_add_ps(a.__s_.__storage_, b.__s_.__storage_); a.__s_.__storage_ = _mm_add_ps(a.__s_.__storage_, b.__s_.__storage_);
return a; return a;
} }
inline simd<float, m128_abi>& inline simd<float, m128_abi>& operator-=(simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
operator-=(simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
a.__s_.__storage_ = _mm_sub_ps(a.__s_.__storage_, b.__s_.__storage_); a.__s_.__storage_ = _mm_sub_ps(a.__s_.__storage_, b.__s_.__storage_);
return a; return a;
} }
inline simd<float, m128_abi>& inline simd<float, m128_abi>& operator*=(simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
operator*=(simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
a.__s_.__storage_ = _mm_mul_ps(a.__s_.__storage_, b.__s_.__storage_); a.__s_.__storage_ = _mm_mul_ps(a.__s_.__storage_, b.__s_.__storage_);
return a; return a;
} }
inline simd<float, m128_abi>& inline simd<float, m128_abi>& operator/=(simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
operator/=(simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
a.__s_.__storage_ = _mm_div_ps(a.__s_.__storage_, b.__s_.__storage_); a.__s_.__storage_ = _mm_div_ps(a.__s_.__storage_, b.__s_.__storage_);
return a; return a;
} }
inline simd<float, m128_abi>::mask_type inline simd<float, m128_abi>::mask_type operator==(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
operator==(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
simd<float, m128_abi>::mask_type ret; simd<float, m128_abi>::mask_type ret;
ret.__s_.__storage_ = _mm_cmpeq_ps(a.__s_.__storage_, b.__s_.__storage_); ret.__s_.__storage_ = _mm_cmpeq_ps(a.__s_.__storage_, b.__s_.__storage_);
return ret; return ret;
} }
inline simd<float, m128_abi>::mask_type inline simd<float, m128_abi>::mask_type operator!=(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
operator!=(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
simd<float, m128_abi>::mask_type ret; simd<float, m128_abi>::mask_type ret;
ret.__s_.__storage_ = _mm_cmpneq_ps(a.__s_.__storage_, b.__s_.__storage_); ret.__s_.__storage_ = _mm_cmpneq_ps(a.__s_.__storage_, b.__s_.__storage_);
return ret; return ret;
} }
inline simd<float, m128_abi>::mask_type inline simd<float, m128_abi>::mask_type operator>=(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
operator>=(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
simd<float, m128_abi>::mask_type ret; simd<float, m128_abi>::mask_type ret;
ret.__s_.__storage_ = _mm_cmpge_ps(a.__s_.__storage_, b.__s_.__storage_); ret.__s_.__storage_ = _mm_cmpge_ps(a.__s_.__storage_, b.__s_.__storage_);
return ret; return ret;
} }
inline simd<float, m128_abi>::mask_type inline simd<float, m128_abi>::mask_type operator<=(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
operator<=(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
simd<float, m128_abi>::mask_type ret; simd<float, m128_abi>::mask_type ret;
ret.__s_.__storage_ = _mm_cmple_ps(a.__s_.__storage_, b.__s_.__storage_); ret.__s_.__storage_ = _mm_cmple_ps(a.__s_.__storage_, b.__s_.__storage_);
return ret; return ret;
} }
inline simd<float, m128_abi>::mask_type inline simd<float, m128_abi>::mask_type operator>(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
operator>(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
simd<float, m128_abi>::mask_type ret; simd<float, m128_abi>::mask_type ret;
ret.__s_.__storage_ = _mm_cmpgt_ps(a.__s_.__storage_, b.__s_.__storage_); ret.__s_.__storage_ = _mm_cmpgt_ps(a.__s_.__storage_, b.__s_.__storage_);
return ret; return ret;
} }
inline simd<float, m128_abi>::mask_type inline simd<float, m128_abi>::mask_type operator<(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
operator<(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
simd<float, m128_abi>::mask_type ret; simd<float, m128_abi>::mask_type ret;
ret.__s_.__storage_ = _mm_cmplt_ps(a.__s_.__storage_, b.__s_.__storage_); ret.__s_.__storage_ = _mm_cmplt_ps(a.__s_.__storage_, b.__s_.__storage_);
return ret; return ret;
@ -308,8 +289,7 @@ public:
}; };
// __m128d mask storage for SSE2+ // __m128d mask storage for SSE2+
template <> template <>
class __simd_mask_storage<double, m128d_abi> : public __simd_storage<double, m128d_abi> class __simd_mask_storage<double, m128d_abi> : public __simd_storage<double, m128d_abi> {
{
public: public:
bool __get(size_t __index) const noexcept { bool __get(size_t __index) const noexcept {
alignas(16) uint64_t sse_data[2]; alignas(16) uint64_t sse_data[2];
@ -332,108 +312,100 @@ inline simd<double, m128d_abi> simd<double, m128d_abi>::operator-() const {
return ret; return ret;
} }
inline simd<double, m128d_abi> inline simd<double, m128d_abi> operator+(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
operator+(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
simd<double, m128d_abi> ret; simd<double, m128d_abi> ret;
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
ret.__s_.__storage_[i] = _mm_add_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]); ret.__s_.__storage_[i] = _mm_add_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]);
return ret; return ret;
} }
inline simd<double, m128d_abi> inline simd<double, m128d_abi> operator-(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
operator-(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
simd<double, m128d_abi> ret; simd<double, m128d_abi> ret;
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
ret.__s_.__storage_[i] = _mm_sub_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]); ret.__s_.__storage_[i] = _mm_sub_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]);
return ret; return ret;
} }
inline simd<double, m128d_abi> inline simd<double, m128d_abi> operator*(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
operator*(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
simd<double, m128d_abi> ret; simd<double, m128d_abi> ret;
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
ret.__s_.__storage_[i] = _mm_mul_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]); ret.__s_.__storage_[i] = _mm_mul_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]);
return ret; return ret;
} }
inline simd<double, m128d_abi> inline simd<double, m128d_abi> operator/(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
operator/(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
simd<double, m128d_abi> ret; simd<double, m128d_abi> ret;
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
ret.__s_.__storage_[i] = _mm_div_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]); ret.__s_.__storage_[i] = _mm_div_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]);
return ret; return ret;
} }
inline simd<double, m128d_abi>& inline simd<double, m128d_abi>& operator+=(simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
operator+=(simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
a.__s_.__storage_[i] = _mm_add_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]); a.__s_.__storage_[i] = _mm_add_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]);
return a; return a;
} }
inline simd<double, m128d_abi>& inline simd<double, m128d_abi>& operator-=(simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
operator-=(simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
a.__s_.__storage_[i] = _mm_sub_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]); a.__s_.__storage_[i] = _mm_sub_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]);
return a; return a;
} }
inline simd<double, m128d_abi>& inline simd<double, m128d_abi>& operator*=(simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
operator*=(simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
a.__s_.__storage_[i] = _mm_mul_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]); a.__s_.__storage_[i] = _mm_mul_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]);
return a; return a;
} }
inline simd<double, m128d_abi>& inline simd<double, m128d_abi>& operator/=(simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
operator/=(simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
a.__s_.__storage_[i] = _mm_div_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]); a.__s_.__storage_[i] = _mm_div_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]);
return a; return a;
} }
inline simd<double, m128d_abi>::mask_type inline simd<double, m128d_abi>::mask_type operator==(const simd<double, m128d_abi>& a,
operator==(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) { const simd<double, m128d_abi>& b) {
simd<double, m128d_abi>::mask_type ret; simd<double, m128d_abi>::mask_type ret;
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
ret.__s_.__storage_[i] = _mm_cmpeq_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]); ret.__s_.__storage_[i] = _mm_cmpeq_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]);
return ret; return ret;
} }
inline simd<double, m128d_abi>::mask_type inline simd<double, m128d_abi>::mask_type operator!=(const simd<double, m128d_abi>& a,
operator!=(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) { const simd<double, m128d_abi>& b) {
simd<double, m128d_abi>::mask_type ret; simd<double, m128d_abi>::mask_type ret;
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
ret.__s_.__storage_[i] = _mm_cmpneq_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]); ret.__s_.__storage_[i] = _mm_cmpneq_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]);
return ret; return ret;
} }
inline simd<double, m128d_abi>::mask_type inline simd<double, m128d_abi>::mask_type operator>=(const simd<double, m128d_abi>& a,
operator>=(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) { const simd<double, m128d_abi>& b) {
simd<double, m128d_abi>::mask_type ret; simd<double, m128d_abi>::mask_type ret;
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
ret.__s_.__storage_[i] = _mm_cmpge_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]); ret.__s_.__storage_[i] = _mm_cmpge_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]);
return ret; return ret;
} }
inline simd<double, m128d_abi>::mask_type inline simd<double, m128d_abi>::mask_type operator<=(const simd<double, m128d_abi>& a,
operator<=(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) { const simd<double, m128d_abi>& b) {
simd<double, m128d_abi>::mask_type ret; simd<double, m128d_abi>::mask_type ret;
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
ret.__s_.__storage_[i] = _mm_cmple_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]); ret.__s_.__storage_[i] = _mm_cmple_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]);
return ret; return ret;
} }
inline simd<double, m128d_abi>::mask_type inline simd<double, m128d_abi>::mask_type operator>(const simd<double, m128d_abi>& a,
operator>(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) { const simd<double, m128d_abi>& b) {
simd<double, m128d_abi>::mask_type ret; simd<double, m128d_abi>::mask_type ret;
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
ret.__s_.__storage_[i] = _mm_cmpgt_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]); ret.__s_.__storage_[i] = _mm_cmpgt_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]);
return ret; return ret;
} }
inline simd<double, m128d_abi>::mask_type inline simd<double, m128d_abi>::mask_type operator<(const simd<double, m128d_abi>& a,
operator<(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) { const simd<double, m128d_abi>& b) {
simd<double, m128d_abi>::mask_type ret; simd<double, m128d_abi>::mask_type ret;
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
ret.__s_.__storage_[i] = _mm_cmplt_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]); ret.__s_.__storage_[i] = _mm_cmplt_pd(a.__s_.__storage_[i], b.__s_.__storage_[i]);
@ -445,10 +417,17 @@ inline __simd_storage<float, m128_abi>::__simd_storage(const __simd_storage<doub
} }
namespace simd_abi { namespace simd_abi {
template<typename T> struct athena_native {}; template <typename T>
template<> struct athena_native<float> { using type = m128_abi; }; struct athena_native {};
template <>
struct athena_native<float> {
using type = m128_abi;
};
#ifndef __AVX__ #ifndef __AVX__
template<> struct athena_native<double> { using type = m128d_abi; }; template <>
struct athena_native<double> {
using type = m128d_abi;
};
#endif #endif
} // namespace simd_abi } // namespace simd_abi

View File

@ -1,13 +1,11 @@
#pragma once #pragma once
#include "athena/Types.hpp" #include "athena/Types.hpp"
namespace bignum namespace bignum {
{
int compare(const atUint8* a, const atUint8* b, atUint32 n); int compare(const atUint8* a, const atUint8* b, atUint32 n);
void subModulus(atUint8* a, const atUint8* N, atUint32 n); void subModulus(atUint8* a, const atUint8* N, atUint32 n);
void add(atUint8* d, atUint8* a, const atUint8* b, const atUint8* N, atUint32 n); void add(atUint8* d, atUint8* a, const atUint8* b, const atUint8* N, atUint32 n);
void mul(atUint8* d, atUint8* a, const atUint8* b, const atUint8* N, atUint32 n); void mul(atUint8* d, atUint8* a, const atUint8* b, const atUint8* N, atUint32 n);
void exp(atUint8* d, const atUint8* a, const atUint8* N, atUint32 n, atUint8* e, atUint32 en); void exp(atUint8* d, const atUint8* a, const atUint8* N, atUint32 n, atUint8* e, atUint32 en);
void inv(atUint8* d, atUint8* a, const atUint8* N, atUint32 n); void inv(atUint8* d, atUint8* a, const atUint8* N, atUint32 n);
} } // namespace bignum

View File

@ -1,11 +1,8 @@
#pragma once #pragma once
#include "athena/Types.hpp" #include "athena/Types.hpp"
namespace ecc namespace ecc {
{
void checkEC(atUint8* ng, atUint8* ap, atUint8* sig, atUint8* sigHash, bool& apValid, bool& ngValid); void checkEC(atUint8* ng, atUint8* ap, atUint8* sig, atUint8* sigHash, bool& apValid, bool& ngValid);
void makeECCert(atUint8* cert, atUint8* sig, const char* signer, const char* name, atUint8* priv, atUint32 keyId); void makeECCert(atUint8* cert, atUint8* sig, const char* signer, const char* name, atUint8* priv, atUint32 keyId);
void createECDSA(atUint8* R, atUint8* S, atUint8* k, atUint8* hash); void createECDSA(atUint8* R, atUint8* S, atUint8* k, atUint8* hash);
} } // namespace ecc

File diff suppressed because it is too large Load Diff

View File

@ -1,47 +1,32 @@
#include "LZ77/LZLookupTable.hpp" #include "LZ77/LZLookupTable.hpp"
#include "LZ77/LZBase.hpp" #include "LZ77/LZBase.hpp"
LZBase::LZBase(atInt32 minimumOffset, atInt32 slidingWindow, atInt32 minimumMatch, atInt32 blockSize) LZBase::LZBase(atInt32 minimumOffset, atInt32 slidingWindow, atInt32 minimumMatch, atInt32 blockSize)
: m_slidingWindow(slidingWindow), : m_slidingWindow(slidingWindow)
m_readAheadBuffer(minimumMatch), , m_readAheadBuffer(minimumMatch)
m_minMatch(minimumMatch), , m_minMatch(minimumMatch)
m_blockSize(blockSize), , m_blockSize(blockSize)
m_minOffset(minimumOffset) , m_minOffset(minimumOffset) {}
{
}
void LZBase::setSlidingWindow(atInt32 slidingWindow) void LZBase::setSlidingWindow(atInt32 slidingWindow) { m_slidingWindow = slidingWindow; }
{
m_slidingWindow = slidingWindow;
}
atInt32 LZBase::slidingWindow() {return m_slidingWindow;} atInt32 LZBase::slidingWindow() { return m_slidingWindow; }
void LZBase::setReadAheadBuffer(atInt32 readAheadBuffer) void LZBase::setReadAheadBuffer(atInt32 readAheadBuffer) { m_readAheadBuffer = readAheadBuffer; }
{
m_readAheadBuffer = readAheadBuffer;
}
atInt32 LZBase::readAheadBuffer() {return m_readAheadBuffer;} atInt32 LZBase::readAheadBuffer() { return m_readAheadBuffer; }
void LZBase::setMinMatch(atInt32 minimumMatch) { m_minMatch = minimumMatch;} void LZBase::setMinMatch(atInt32 minimumMatch) { m_minMatch = minimumMatch; }
atInt32 LZBase::minMatch() {return m_minMatch;} atInt32 LZBase::minMatch() { return m_minMatch; }
void LZBase::setBlockSize(atInt32 blockSize) void LZBase::setBlockSize(atInt32 blockSize) { m_blockSize = blockSize; }
{
m_blockSize = blockSize ;
}
atInt32 LZBase::blockSize() {return m_blockSize;} atInt32 LZBase::blockSize() { return m_blockSize; }
void LZBase::setMinimumOffset(atUint32 minimumOffset) { m_minOffset = minimumOffset;} void LZBase::setMinimumOffset(atUint32 minimumOffset) { m_minOffset = minimumOffset; }
atUint32 LZBase::minimumOffset() atUint32 LZBase::minimumOffset() { return m_minOffset; }
{
return m_minOffset;
}
/* /*
DerricMc: DerricMc:
@ -54,20 +39,18 @@ atUint32 LZBase::minimumOffset()
and 17 bytes did match then 17 bytes match is return). and 17 bytes did match then 17 bytes match is return).
*/ */
LZLengthOffset LZBase::search(atUint8* posPtr, atUint8* dataBegin, atUint8* dataEnd) LZLengthOffset LZBase::search(atUint8* posPtr, atUint8* dataBegin, atUint8* dataEnd) {
{
LZLengthOffset results = {0, 0}; LZLengthOffset results = {0, 0};
//Returns negative 1 for Search failures since the current position is passed the size to be compressed // Returns negative 1 for Search failures since the current position is passed the size to be compressed
if (posPtr >= dataEnd) if (posPtr >= dataEnd) {
{
results.length = -1; results.length = -1;
return results; return results;
} }
atUint8* searchWindow; atUint8* searchWindow;
//LookAheadBuffer is ReadAheadBuffer Size if there are more bytes than ReadAheadBufferSize waiting // LookAheadBuffer is ReadAheadBuffer Size if there are more bytes than ReadAheadBufferSize waiting
//to be compressed else the number of remaining bytes is the LookAheadBuffer // to be compressed else the number of remaining bytes is the LookAheadBuffer
int lookAheadBuffer_len = ((int)(dataEnd - posPtr) < m_readAheadBuffer) ? (int)(dataEnd - posPtr) : m_readAheadBuffer; int lookAheadBuffer_len = ((int)(dataEnd - posPtr) < m_readAheadBuffer) ? (int)(dataEnd - posPtr) : m_readAheadBuffer;
int slidingBuffer = (int)(posPtr - dataBegin) - m_slidingWindow; int slidingBuffer = (int)(posPtr - dataBegin) - m_slidingWindow;
@ -84,11 +67,9 @@ LZLengthOffset LZBase::search(atUint8* posPtr, atUint8* dataBegin, atUint8* data
return results; return results;
} }
// Returns the full length of string2 if they are equal else
//Returns the full length of string2 if they are equal else // Return the number of characters that were equal before they weren't equal
//Return the number of characters that were equal before they weren't equal int LZBase::subMatch(const uint8_t* str1, const uint8_t* str2, const int len) {
int LZBase::subMatch(const uint8_t* str1, const uint8_t* str2, const int len)
{
for (int i = 0; i < len; ++i) for (int i = 0; i < len; ++i)
if (str1[i] != str2[i]) if (str1[i] != str2[i])
return i; return i;
@ -100,9 +81,9 @@ int LZBase::subMatch(const uint8_t* str1, const uint8_t* str2, const int len)
Normally a search for one byte is matched, then two, then three, all the way up Normally a search for one byte is matched, then two, then three, all the way up
to the size of the LookAheadBuffer. So I decided to skip the incremental search to the size of the LookAheadBuffer. So I decided to skip the incremental search
and search for the entire LookAheadBuffer and if the function doesn't find the bytes are and search for the entire LookAheadBuffer and if the function doesn't find the bytes are
equal the function return the next best match(which means if the function look for 18 bytes and they are not found, return equal the function return the next best match(which means if the function look for 18 bytes and they are not found,
the number of bytes that did match before it failed to match. The submatch is function returns the number of bytes that return the number of bytes that did match before it failed to match. The submatch is function returns the number of
were equal, which can result up to the bytes total length if both byte strings are equal. bytes that were equal, which can result up to the bytes total length if both byte strings are equal.
...[][][][][][][][][][][][]|[][][][][][][][][][][][][][] ...[][][][][][][][][][][][]|[][][][][][][][][][][][][][]
@ -112,14 +93,14 @@ Normally a search for one byte is matched, then two, then three, all the way up
Sliding Window Sliding Window
Up to 4114 bytes Up to 4114 bytes
*/ */
LZLengthOffset LZBase::windowSearch(atUint8* beginSearchPtr, atUint8* searchPosPtr, atUint8* endLABufferPtr, atUint8* startLBPtr) LZLengthOffset LZBase::windowSearch(atUint8* beginSearchPtr, atUint8* searchPosPtr, atUint8* endLABufferPtr,
{ atUint8* startLBPtr) {
atInt32 size = (atUint32)(endLABufferPtr - beginSearchPtr); //Size of the entire sliding window atInt32 size = (atUint32)(endLABufferPtr - beginSearchPtr); // Size of the entire sliding window
atInt32 n = (atUint32)(endLABufferPtr - searchPosPtr); atInt32 n = (atUint32)(endLABufferPtr - searchPosPtr);
LZLengthOffset result = {0, 0}; LZLengthOffset result = {0, 0};
atInt32 temp = 0; atInt32 temp = 0;
if (n > size) //If the string that is being looked for is bigger than the string that is being searched if (n > size) // If the string that is being looked for is bigger than the string that is being searched
return result; return result;
/*This makes sure that search for the searchPosPtr can be searched if an invalid position is given /*This makes sure that search for the searchPosPtr can be searched if an invalid position is given
@ -127,12 +108,10 @@ LZLengthOffset LZBase::windowSearch(atUint8* beginSearchPtr, atUint8* searchPosP
of searchPosPtr. In other words there has to be at least n characters left in the string of searchPosPtr. In other words there has to be at least n characters left in the string
to have a chance to find n characters*/ to have a chance to find n characters*/
do do {
{
temp = subMatch(startLBPtr, searchPosPtr, n); temp = subMatch(startLBPtr, searchPosPtr, n);
if (result.length < (atUint32)temp) if (result.length < (atUint32)temp) {
{
result.length = temp; result.length = temp;
result.offset = (atInt32)(searchPosPtr - startLBPtr); result.offset = (atInt32)(searchPosPtr - startLBPtr);
} }
@ -140,11 +119,9 @@ LZLengthOffset LZBase::windowSearch(atUint8* beginSearchPtr, atUint8* searchPosP
if (result.length == (atUint32)n) if (result.length == (atUint32)n)
return result; return result;
//ReadAheadBuffer is the maximum size of a character match // ReadAheadBuffer is the maximum size of a character match
} } while ((startLBPtr--) > beginSearchPtr);
while ((startLBPtr--) > beginSearchPtr);
return result; return result;
} }

View File

@ -1,16 +1,14 @@
#include "LZ77/LZLookupTable.hpp" #include "LZ77/LZLookupTable.hpp"
#include <algorithm> #include <algorithm>
LZLookupTable::LZLookupTable() LZLookupTable::LZLookupTable() {
{
m_minimumMatch = 3; m_minimumMatch = 3;
m_slidingWindow = 4096; m_slidingWindow = 4096;
m_lookAheadWindow = 18; m_lookAheadWindow = 18;
m_buffer.resize(m_minimumMatch); m_buffer.resize(m_minimumMatch);
} }
LZLookupTable::LZLookupTable(atInt32 minimumMatch, atInt32 slidingWindow, atInt32 lookAheadWindow) LZLookupTable::LZLookupTable(atInt32 minimumMatch, atInt32 slidingWindow, atInt32 lookAheadWindow) {
{
if (minimumMatch > 0) if (minimumMatch > 0)
m_minimumMatch = minimumMatch; m_minimumMatch = minimumMatch;
else else
@ -29,24 +27,20 @@ LZLookupTable::LZLookupTable(atInt32 minimumMatch, atInt32 slidingWindow, atInt3
m_buffer.reserve(m_minimumMatch); m_buffer.reserve(m_minimumMatch);
} }
LZLookupTable::~LZLookupTable() LZLookupTable::~LZLookupTable() {}
{}
void LZLookupTable::setLookAheadWindow(atInt32 lookAheadWindow) void LZLookupTable::setLookAheadWindow(atInt32 lookAheadWindow) {
{
if (lookAheadWindow > 0) if (lookAheadWindow > 0)
m_lookAheadWindow = lookAheadWindow; m_lookAheadWindow = lookAheadWindow;
else else
m_lookAheadWindow = 18; m_lookAheadWindow = 18;
} }
LZLengthOffset LZLookupTable::search(atUint8* curPos, const atUint8* dataBegin, const atUint8* dataEnd) LZLengthOffset LZLookupTable::search(atUint8* curPos, const atUint8* dataBegin, const atUint8* dataEnd) {
{
LZLengthOffset loPair = {0, 0}; LZLengthOffset loPair = {0, 0};
//Returns negative 1 for search failures since the current position is passed the size to be compressed // Returns negative 1 for search failures since the current position is passed the size to be compressed
if (curPos >= dataEnd) if (curPos >= dataEnd) {
{
loPair.length = -1; loPair.length = -1;
return loPair; return loPair;
} }
@ -54,76 +48,69 @@ LZLengthOffset LZLookupTable::search(atUint8* curPos, const atUint8* dataBegin,
std::copy(curPos, curPos + m_minimumMatch, m_buffer.begin()); std::copy(curPos, curPos + m_minimumMatch, m_buffer.begin());
int32_t currentOffset = static_cast<atInt32>(curPos - dataBegin); int32_t currentOffset = static_cast<atInt32>(curPos - dataBegin);
//Find code // Find code
if (currentOffset > 0 && (dataEnd - curPos) >= m_minimumMatch) if (currentOffset > 0 && (dataEnd - curPos) >= m_minimumMatch) {
{
auto elements = table.equal_range(m_buffer); auto elements = table.equal_range(m_buffer);
elements.second--; elements.second--;
elements.first--; elements.first--;
//Iterate over keys in reverse order. C++11 guarantees that the relative order of elements is maintained for the same key // Iterate over keys in reverse order. C++11 guarantees that the relative order of elements is maintained for the
for (auto iter = elements.second; iter != elements.first; iter--) // same key
{ for (auto iter = elements.second; iter != elements.first; iter--) {
int32_t matchLength = m_minimumMatch; int32_t matchLength = m_minimumMatch;
int32_t lookAheadBufferLength = ((dataEnd - curPos) < m_lookAheadWindow) ? static_cast<int32_t>(dataEnd - curPos) : m_lookAheadWindow; int32_t lookAheadBufferLength =
((dataEnd - curPos) < m_lookAheadWindow) ? static_cast<int32_t>(dataEnd - curPos) : m_lookAheadWindow;
for (; matchLength < lookAheadBufferLength; ++matchLength) for (; matchLength < lookAheadBufferLength; ++matchLength) {
{
if (*(dataBegin + iter->second + matchLength) != *(curPos + matchLength)) if (*(dataBegin + iter->second + matchLength) != *(curPos + matchLength))
break; break;
} }
//Store the longest match found so far into length_offset struct. // Store the longest match found so far into length_offset struct.
//When lengths are the same the closer offset to the lookahead buffer wins // When lengths are the same the closer offset to the lookahead buffer wins
if (loPair.length < (atUint32)matchLength) if (loPair.length < (atUint32)matchLength) {
{
loPair.length = matchLength; loPair.length = matchLength;
loPair.offset = currentOffset - iter->second; loPair.offset = currentOffset - iter->second;
} }
//Found the longest match so break out of loop // Found the longest match so break out of loop
if (loPair.length == (atUint32)m_lookAheadWindow) if (loPair.length == (atUint32)m_lookAheadWindow)
break; break;
} }
} }
//end find code // end find code
//Insert code // Insert code
table.insert(std::make_pair(m_buffer, currentOffset)); table.insert(std::make_pair(m_buffer, currentOffset));
for (atUint32 i = 1; i < loPair.length; i++) for (atUint32 i = 1; i < loPair.length; i++) {
{
if (dataEnd - (curPos + i) < m_minimumMatch) if (dataEnd - (curPos + i) < m_minimumMatch)
break; break;
std::copy(curPos + i, curPos + m_minimumMatch + i, m_buffer.begin()); std::copy(curPos + i, curPos + m_minimumMatch + i, m_buffer.begin());
table.insert(std::make_pair(m_buffer, currentOffset + i)); table.insert(std::make_pair(m_buffer, currentOffset + i));
} }
//end insert code // end insert code
//Delete code // Delete code
int32_t slidingWindowOffset = std::max(0, currentOffset - m_slidingWindow);//Absolute offset int32_t slidingWindowOffset = std::max(0, currentOffset - m_slidingWindow); // Absolute offset
int32_t tablesize = static_cast<int32_t>(table.size()); int32_t tablesize = static_cast<int32_t>(table.size());
for (int32_t i = 0; i < tablesize - m_slidingWindow; ++i) for (int32_t i = 0; i < tablesize - m_slidingWindow; ++i) {
{ std::copy(dataBegin + slidingWindowOffset + i, dataBegin + slidingWindowOffset + m_minimumMatch + i,
std::copy(dataBegin + slidingWindowOffset + i, dataBegin + slidingWindowOffset + m_minimumMatch + i, m_buffer.begin()); m_buffer.begin());
auto elements = table.equal_range(m_buffer); auto elements = table.equal_range(m_buffer);
for (auto iter = elements.first; iter != elements.second; iter++) for (auto iter = elements.first; iter != elements.second; iter++) {
{ if (slidingWindowOffset + i == iter->second) {
if (slidingWindowOffset + i == iter->second)
{
table.erase(iter); table.erase(iter);
//There should no occurance of the map with the same value // There should no occurance of the map with the same value
break; break;
} }
} }
} }
//end delete code // end delete code
return loPair; return loPair;
//break lookupTable.cpp:109 if table.size()> 4096 // break lookupTable.cpp:109 if table.size()> 4096
} }

View File

@ -4,17 +4,15 @@
#include <cstring> #include <cstring>
LZType10::LZType10(atInt32 MinimumOffset, atInt32 SlidingWindow, atInt32 MinimumMatch, atInt32 BlockSize) LZType10::LZType10(atInt32 MinimumOffset, atInt32 SlidingWindow, atInt32 MinimumMatch, atInt32 BlockSize)
: LZBase(MinimumOffset, SlidingWindow, MinimumMatch, BlockSize) : LZBase(MinimumOffset, SlidingWindow, MinimumMatch, BlockSize) {
{ // ReadAheadBuffer is normalize between (minumum match) and(minimum match + 15) so that matches fit within
//ReadAheadBuffer is normalize between (minumum match) and(minimum match + 15) so that matches fit within // 4-bits.
//4-bits.
m_readAheadBuffer = m_minMatch + 0xF; m_readAheadBuffer = m_minMatch + 0xF;
} }
atUint32 LZType10::compress(const atUint8* src, atUint8** dstBuf, atUint32 srcLength) atUint32 LZType10::compress(const atUint8* src, atUint8** dstBuf, atUint32 srcLength) {
{
atUint32 encodeSize = (srcLength << 8) | (0x10); atUint32 encodeSize = (srcLength << 8) | (0x10);
encodeSize = athena::utility::LittleUint32(encodeSize); //File size needs to be written as little endian always encodeSize = athena::utility::LittleUint32(encodeSize); // File size needs to be written as little endian always
athena::io::MemoryCopyWriter outbuf("tmp"); athena::io::MemoryCopyWriter outbuf("tmp");
outbuf.writeUint32(encodeSize); outbuf.writeUint32(encodeSize);
@ -22,25 +20,23 @@ atUint32 LZType10::compress(const atUint8* src, atUint8** dstBuf, atUint32 srcLe
atUint8* ptrStart = (atUint8*)src; atUint8* ptrStart = (atUint8*)src;
atUint8* ptrEnd = (atUint8*)(src + srcLength); atUint8* ptrEnd = (atUint8*)(src + srcLength);
//At most their will be two bytes written if the bytes can be compressed. So if all bytes in the block can be compressed it would take blockSize*2 bytes // At most their will be two bytes written if the bytes can be compressed. So if all bytes in the block can be
atUint8* compressedBytes = new atUint8[m_blockSize * 2]; //Holds the compressed bytes yet to be written // compressed it would take blockSize*2 bytes
atUint8* compressedBytes = new atUint8[m_blockSize * 2]; // Holds the compressed bytes yet to be written
while (ptrStart < ptrEnd) while (ptrStart < ptrEnd) {
{
atUint8 blockLen = 0; atUint8 blockLen = 0;
//In Binary represents 1 if byte is compressed or 0 if not compressed // In Binary represents 1 if byte is compressed or 0 if not compressed
//For example 01001000 means that the second and fifth byte in the blockSize from the left is compressed // For example 01001000 means that the second and fifth byte in the blockSize from the left is compressed
atUint8* ptrBytes = compressedBytes; atUint8* ptrBytes = compressedBytes;
for (atInt32 i = 0; i < m_blockSize; i++) for (atInt32 i = 0; i < m_blockSize; i++) {
{ // length_offset searchResult=Search(ptrStart, filedata, ptrEnd);
//length_offset searchResult=Search(ptrStart, filedata, ptrEnd);
LZLengthOffset searchResult = m_lookupTable.search(ptrStart, src, ptrEnd); LZLengthOffset searchResult = m_lookupTable.search(ptrStart, src, ptrEnd);
//If the number of bytes to be compressed is at least the size of the Minimum match // If the number of bytes to be compressed is at least the size of the Minimum match
if (searchResult.length >= (atUint32)m_minMatch) if (searchResult.length >= (atUint32)m_minMatch) {
{ // Gotta swap the bytes since system is wii is big endian and most computers are little endian
//Gotta swap the bytes since system is wii is big endian and most computers are little endian
atUint16 lenOff = (((searchResult.length - m_minMatch) & 0xF) << 12) | ((searchResult.offset - 1) & 0xFFF); atUint16 lenOff = (((searchResult.length - m_minMatch) & 0xF) << 12) | ((searchResult.offset - 1) & 0xFFF);
athena::utility::BigUint16(lenOff); athena::utility::BigUint16(lenOff);
@ -51,22 +47,20 @@ atUint32 LZType10::compress(const atUint8* src, atUint8** dstBuf, atUint32 srcLe
ptrStart += searchResult.length; ptrStart += searchResult.length;
blockLen |= (1 << (7 - i)); blockLen |= (1 << (7 - i));
//Stores which of the next 8 bytes is compressed // Stores which of the next 8 bytes is compressed
//bit 1 for compress and bit 0 for not compressed // bit 1 for compress and bit 0 for not compressed
} } else
else
*ptrBytes++ = *ptrStart++; *ptrBytes++ = *ptrStart++;
} }
outbuf.writeByte(blockLen); outbuf.writeByte(blockLen);
outbuf.writeUBytes(compressedBytes, (atUint64)(ptrBytes - compressedBytes)); outbuf.writeUBytes(compressedBytes, (atUint64)(ptrBytes - compressedBytes));
} }
delete[] compressedBytes; delete[] compressedBytes;
compressedBytes = nullptr; compressedBytes = nullptr;
//Add zeros until the file is a multiple of 4 // Add zeros until the file is a multiple of 4
while ((outbuf.position() % 4) != 0) while ((outbuf.position() % 4) != 0)
outbuf.writeByte(0); outbuf.writeByte(0);
@ -75,14 +69,13 @@ atUint32 LZType10::compress(const atUint8* src, atUint8** dstBuf, atUint32 srcLe
return (atUint32)outbuf.length(); return (atUint32)outbuf.length();
} }
atUint32 LZType10::decompress(const atUint8* src, atUint8** dst, atUint32 srcLength) atUint32 LZType10::decompress(const atUint8* src, atUint8** dst, atUint32 srcLength) {
{
if (*(atUint8*)(src) != 0x10) if (*(atUint8*)(src) != 0x10)
return 0; return 0;
atUint32 uncompressedSize = *(atUint32*)(src); //Size of data when it is uncompressed atUint32 uncompressedSize = *(atUint32*)(src); // Size of data when it is uncompressed
athena::utility::LittleUint32(uncompressedSize); //The compressed file has the filesize encoded in little endian athena::utility::LittleUint32(uncompressedSize); // The compressed file has the filesize encoded in little endian
uncompressedSize = uncompressedSize >> 8;//first byte is the encode flag uncompressedSize = uncompressedSize >> 8; // first byte is the encode flag
atUint8* uncompressedData = new atUint8[uncompressedSize]; atUint8* uncompressedData = new atUint8[uncompressedSize];
atUint8* outputPtr = uncompressedData; atUint8* outputPtr = uncompressedData;
@ -90,31 +83,27 @@ atUint32 LZType10::decompress(const atUint8* src, atUint8** dst, atUint32 srcLen
atUint8* inputPtr = (atUint8*)src + 4; atUint8* inputPtr = (atUint8*)src + 4;
atUint8* inputEndPtr = (atUint8*)src + srcLength; atUint8* inputEndPtr = (atUint8*)src + srcLength;
while (inputPtr < inputEndPtr && outputPtr < outputEndPtr) while (inputPtr < inputEndPtr && outputPtr < outputEndPtr) {
{
atUint8 isCompressed = *inputPtr++; atUint8 isCompressed = *inputPtr++;
for (atUint32 i = 0; i < (atUint32)m_blockSize; i++) for (atUint32 i = 0; i < (atUint32)m_blockSize; i++) {
{ // Checks to see if the next byte is compressed by looking
//Checks to see if the next byte is compressed by looking // at its binary representation - E.g 10010000
//at its binary representation - E.g 10010000 // This says that the first extracted byte and the four extracted byte is compressed
//This says that the first extracted byte and the four extracted byte is compressed if ((isCompressed >> (7 - i)) & 0x1) {
if ((isCompressed >> (7 - i)) & 0x1)
{
atUint16 lenOff; atUint16 lenOff;
memcpy(&lenOff, inputPtr, sizeof(atUint16)); memcpy(&lenOff, inputPtr, sizeof(atUint16));
athena::utility::BigUint16(lenOff); athena::utility::BigUint16(lenOff);
inputPtr += sizeof(atUint16); //Move forward two bytes inputPtr += sizeof(atUint16); // Move forward two bytes
//length offset pair has been decoded. // length offset pair has been decoded.
LZLengthOffset decoding; LZLengthOffset decoding;
decoding.length = (lenOff >> 12) + m_minMatch; decoding.length = (lenOff >> 12) + m_minMatch;
decoding.offset = static_cast<atUint16>((lenOff & 0xFFF) + 1); decoding.offset = static_cast<atUint16>((lenOff & 0xFFF) + 1);
if ((outputPtr - decoding.offset) < uncompressedData) {
if ((outputPtr - decoding.offset) < uncompressedData) // If the offset to look for uncompressed is passed the current uncompresed data then the data is not
{ // compressed
//If the offset to look for uncompressed is passed the current uncompresed data then the data is not compressed
delete[] uncompressedData; delete[] uncompressedData;
uncompressedData = nullptr; uncompressedData = nullptr;
dst = nullptr; dst = nullptr;
@ -125,14 +114,11 @@ atUint32 LZType10::decompress(const atUint8* src, atUint8** dst, atUint32 srcLen
outputPtr[j] = (outputPtr - decoding.offset)[j]; outputPtr[j] = (outputPtr - decoding.offset)[j];
outputPtr += decoding.length; outputPtr += decoding.length;
} } else
else
*outputPtr++ = *inputPtr++; *outputPtr++ = *inputPtr++;
if (!(inputPtr < inputEndPtr && outputPtr < outputEndPtr)) if (!(inputPtr < inputEndPtr && outputPtr < outputEndPtr))
break; break;
} }
} }
@ -140,4 +126,3 @@ atUint32 LZType10::decompress(const atUint8* src, atUint8** dst, atUint32 srcLen
return uncompressedSize; return uncompressedSize;
} }

View File

@ -3,29 +3,24 @@
#include <athena/MemoryWriter.hpp> #include <athena/MemoryWriter.hpp>
#include <cstring> #include <cstring>
LZType11::LZType11(atInt32 minimumOffset, atInt32 slidingWindow, atInt32 minimumMatch, atInt32 blockSize) LZType11::LZType11(atInt32 minimumOffset, atInt32 slidingWindow, atInt32 minimumMatch, atInt32 blockSize)
: LZBase(minimumOffset, slidingWindow, minimumMatch, blockSize) : LZBase(minimumOffset, slidingWindow, minimumMatch, blockSize) {
{
m_readAheadBuffer = (0xF + 0xFF + 0xFFFF + m_minMatch); m_readAheadBuffer = (0xF + 0xFF + 0xFFFF + m_minMatch);
m_lookupTable.setLookAheadWindow(m_readAheadBuffer); m_lookupTable.setLookAheadWindow(m_readAheadBuffer);
} }
atUint32 LZType11::compress(const atUint8* src, atUint8** dst, atUint32 srcLength) atUint32 LZType11::compress(const atUint8* src, atUint8** dst, atUint32 srcLength) {
{
athena::io::MemoryCopyWriter outbuff("tmp"); athena::io::MemoryCopyWriter outbuff("tmp");
if (srcLength > 0xFFFFFF) // If length is greater than 24 bits or 16 Megs if (srcLength > 0xFFFFFF) // If length is greater than 24 bits or 16 Megs
{ {
atUint32 encodeFlag = 0x11; atUint32 encodeFlag = 0x11;
athena::utility::LittleUint32(encodeFlag); athena::utility::LittleUint32(encodeFlag);
athena::utility::LittleUint32(srcLength);//Filesize data is little endian athena::utility::LittleUint32(srcLength); // Filesize data is little endian
outbuff.writeUint32(encodeFlag); outbuff.writeUint32(encodeFlag);
outbuff.writeUint32(srcLength); outbuff.writeUint32(srcLength);
} } else {
else
{
atUint32 encodeSize = (srcLength << 8) | (0x11); atUint32 encodeSize = (srcLength << 8) | (0x11);
athena::utility::LittleUint32(encodeSize); athena::utility::LittleUint32(encodeSize);
outbuff.writeUint32(encodeSize); outbuff.writeUint32(encodeSize);
@ -34,13 +29,14 @@ atUint32 LZType11::compress(const atUint8* src, atUint8** dst, atUint32 srcLengt
atUint8* ptrStart = (atUint8*)src; atUint8* ptrStart = (atUint8*)src;
atUint8* ptrEnd = (atUint8*)(src + srcLength); atUint8* ptrEnd = (atUint8*)(src + srcLength);
//At most their will be two bytes written if the bytes can be compressed. So if all bytes in the block can be compressed it would take blockSize*2 bytes // At most their will be two bytes written if the bytes can be compressed. So if all bytes in the block can be
atUint8* compressedBytes = new atUint8[m_blockSize * 2]; //Holds the compressed bytes yet to be written // compressed it would take blockSize*2 bytes
atUint8* compressedBytes = new atUint8[m_blockSize * 2]; // Holds the compressed bytes yet to be written
atUint8 maxTwoByteMatch = 0xF + 1; atUint8 maxTwoByteMatch = 0xF + 1;
atUint8 minThreeByteMatch = maxTwoByteMatch + 1; //Minimum Three byte match is maximum TwoByte match + 1 atUint8 minThreeByteMatch = maxTwoByteMatch + 1; // Minimum Three byte match is maximum TwoByte match + 1
atUint16 maxThreeByteMatch = 0xFF + minThreeByteMatch; atUint16 maxThreeByteMatch = 0xFF + minThreeByteMatch;
atUint16 minFourByteMatch = maxThreeByteMatch + 1; //Minimum Four byte match is maximum Three Byte match + 1 atUint16 minFourByteMatch = maxThreeByteMatch + 1; // Minimum Four byte match is maximum Three Byte match + 1
atInt32 maxFourByteMatch = 0xFFFF + minFourByteMatch; atInt32 maxFourByteMatch = 0xFFFF + minFourByteMatch;
/* /*
@ -57,46 +53,39 @@ atUint32 LZType11::compress(const atUint8* src, atUint8** dst, atUint32 srcLengt
In the three byte case the first 4 bits are 0000 In the three byte case the first 4 bits are 0000
In the four byte case the first 4 bits a 0001 In the four byte case the first 4 bits a 0001
*/ */
while (ptrStart < ptrEnd) while (ptrStart < ptrEnd) {
{
atUint8 blockSize = 0; atUint8 blockSize = 0;
//In Binary represents 1 if byte is compressed or 0 if not compressed // In Binary represents 1 if byte is compressed or 0 if not compressed
//For example 01001000 means that the second and fifth byte in the blockSize from the left is compressed // For example 01001000 means that the second and fifth byte in the blockSize from the left is compressed
atUint8* ptrBytes = compressedBytes; atUint8* ptrBytes = compressedBytes;
for (atInt32 i = 0; i < m_blockSize; i++) for (atInt32 i = 0; i < m_blockSize; i++) {
{ // length_offset searchResult=Search(filedata,ptrStart,ptrEnd);
//length_offset searchResult=Search(filedata,ptrStart,ptrEnd);
LZLengthOffset searchResult = m_lookupTable.search(ptrStart, src, ptrEnd); LZLengthOffset searchResult = m_lookupTable.search(ptrStart, src, ptrEnd);
//If the number of bytes to be compressed is at least the size of the Minimum match // If the number of bytes to be compressed is at least the size of the Minimum match
if (searchResult.length >= (atUint32)m_minMatch) if (searchResult.length >= (atUint32)m_minMatch) {
{ // Gotta swap the bytes since system is wii is big endian and most computers are little endian
//Gotta swap the bytes since system is wii is big endian and most computers are little endian
if (searchResult.length <= maxTwoByteMatch) if (searchResult.length <= maxTwoByteMatch) {
{ atUint16 lenOff = ((((searchResult.length - 1) & 0xF) << 12) | // Bits 15-12
atUint16 lenOff = ((((searchResult.length - 1) & 0xF) << 12) | //Bits 15-12 ((searchResult.offset - 1) & 0xFFF) // Bits 11-0
((searchResult.offset - 1) & 0xFFF) //Bits 11-0
); );
athena::utility::BigUint16(lenOff); athena::utility::BigUint16(lenOff);
memcpy(ptrBytes, &lenOff, 2); memcpy(ptrBytes, &lenOff, 2);
ptrBytes += 2; ptrBytes += 2;
} } else if (searchResult.length <= maxThreeByteMatch) {
else if (searchResult.length <= maxThreeByteMatch) atUint32 lenOff = ((((searchResult.length - minThreeByteMatch) & 0xFF) << 12) | // Bits 20-12
{ ((searchResult.offset - 1) & 0xFFF) // Bits 11-0
atUint32 lenOff = ((((searchResult.length - minThreeByteMatch) & 0xFF) << 12) | //Bits 20-12
((searchResult.offset - 1) & 0xFFF) //Bits 11-0
); );
athena::utility::BigUint32(lenOff); athena::utility::BigUint32(lenOff);
memcpy(ptrBytes, (atUint8*)&lenOff + 1, 3); //Make sure to copy the lower 24 bits. 0x12345678- This statement copies 0x123456 memcpy(ptrBytes, (atUint8*)&lenOff + 1,
3); // Make sure to copy the lower 24 bits. 0x12345678- This statement copies 0x123456
ptrBytes += 3; ptrBytes += 3;
} } else if (searchResult.length <= (atUint32)maxFourByteMatch) {
else if (searchResult.length <= (atUint32)maxFourByteMatch) atUint32 lenOff = ((1 << 28) | // Bits 31-28 Flag to say that this is four bytes
{ (((searchResult.length - minFourByteMatch) & 0xFFFF) << 12) | // Bits 28-12
atUint32 lenOff = ((1 << 28) | //Bits 31-28 Flag to say that this is four bytes ((searchResult.offset - 1) & 0xFFF) // Bits 11-0
(((searchResult.length - minFourByteMatch) & 0xFFFF) << 12) | //Bits 28-12
((searchResult.offset - 1) & 0xFFF) //Bits 11-0
); );
athena::utility::BigUint32(lenOff); athena::utility::BigUint32(lenOff);
memcpy(ptrBytes, &lenOff, 4); memcpy(ptrBytes, &lenOff, 4);
@ -106,23 +95,20 @@ atUint32 LZType11::compress(const atUint8* src, atUint8** dst, atUint32 srcLengt
ptrStart += searchResult.length; ptrStart += searchResult.length;
blockSize |= (1 << (7 - i)); blockSize |= (1 << (7 - i));
//Stores which of the next 8 bytes is compressed // Stores which of the next 8 bytes is compressed
//bit 1 for compress and bit 0 for not compressed // bit 1 for compress and bit 0 for not compressed
} } else
else
*ptrBytes++ = *ptrStart++; *ptrBytes++ = *ptrStart++;
} }
outbuff.writeByte(blockSize); outbuff.writeByte(blockSize);
outbuff.writeUBytes(compressedBytes, (atUint64)(ptrBytes - compressedBytes)); outbuff.writeUBytes(compressedBytes, (atUint64)(ptrBytes - compressedBytes));
} }
delete []compressedBytes; delete[] compressedBytes;
compressedBytes = NULL; compressedBytes = NULL;
//Add zeros until the file is a multiple of 4 // Add zeros until the file is a multiple of 4
while ((outbuff.position() % 4) != 0) while ((outbuff.position() % 4) != 0)
outbuff.writeByte(0); outbuff.writeByte(0);
@ -130,17 +116,17 @@ atUint32 LZType11::compress(const atUint8* src, atUint8** dst, atUint32 srcLengt
return (atUint32)outbuff.length(); return (atUint32)outbuff.length();
} }
atUint32 LZType11::decompress(const atUint8* src, atUint8** dst, atUint32 srcLength) atUint32 LZType11::decompress(const atUint8* src, atUint8** dst, atUint32 srcLength) {
{
if (*(atUint8*)(src) != 0x11) if (*(atUint8*)(src) != 0x11)
return 0; return 0;
atUint32 uncompressedLen = *(atUint32*)(src); atUint32 uncompressedLen = *(atUint32*)(src);
athena::utility::LittleUint32(uncompressedLen);//The compressed file has the filesize encoded in little endian athena::utility::LittleUint32(uncompressedLen); // The compressed file has the filesize encoded in little endian
uncompressedLen = uncompressedLen >> 8; //First byte is the encode flag uncompressedLen = uncompressedLen >> 8; // First byte is the encode flag
atUint32 currentOffset = 4; atUint32 currentOffset = 4;
if (uncompressedLen == 0) //If the filesize var is zero then the true filesize is over 14MB and must be read in from the next 4 bytes if (uncompressedLen ==
0) // If the filesize var is zero then the true filesize is over 14MB and must be read in from the next 4 bytes
{ {
atUint32 filesize = *(atUint32*)(src + 4); atUint32 filesize = *(atUint32*)(src + 4);
filesize = athena::utility::LittleUint32(filesize); filesize = athena::utility::LittleUint32(filesize);
@ -155,25 +141,22 @@ atUint32 LZType11::decompress(const atUint8* src, atUint8** dst, atUint32 srcLen
LZLengthOffset decoding; LZLengthOffset decoding;
atUint8 maxTwoByteMatch = 0xF + 1; atUint8 maxTwoByteMatch = 0xF + 1;
atUint8 threeByteDenorm = maxTwoByteMatch + 1; //Amount to add to length when compression is 3 bytes atUint8 threeByteDenorm = maxTwoByteMatch + 1; // Amount to add to length when compression is 3 bytes
atUint16 maxThreeByteMatch = 0xFF + threeByteDenorm; atUint16 maxThreeByteMatch = 0xFF + threeByteDenorm;
atUint16 fourByteDenorm = maxThreeByteMatch + 1; atUint16 fourByteDenorm = maxThreeByteMatch + 1;
while (inputPtr < inputEndPtr && outputPtr < outputEndPtr) while (inputPtr < inputEndPtr && outputPtr < outputEndPtr) {
{
atUint8 isCompressed = *inputPtr++; atUint8 isCompressed = *inputPtr++;
for (atInt32 i = 0; i < m_blockSize; i++) for (atInt32 i = 0; i < m_blockSize; i++) {
{ // Checks to see if the next byte is compressed by looking
//Checks to see if the next byte is compressed by looking // at its binary representation - E.g 10010000
//at its binary representation - E.g 10010000 // This says that the first extracted byte and the four extracted byte is compressed
//This says that the first extracted byte and the four extracted byte is compressed if ((isCompressed >> (7 - i)) & 0x1) {
if ((isCompressed >> (7 - i)) & 0x1) atUint8 metaDataSize = *inputPtr >> 4; // Look at the top 4 bits
{
atUint8 metaDataSize = *inputPtr >> 4; //Look at the top 4 bits
if (metaDataSize >= 2) //Two Bytes of Length/Offset MetaData if (metaDataSize >= 2) // Two Bytes of Length/Offset MetaData
{ {
atUint16 lenOff = 0; atUint16 lenOff = 0;
memcpy(&lenOff, inputPtr, 2); memcpy(&lenOff, inputPtr, 2);
@ -181,8 +164,7 @@ atUint32 LZType11::decompress(const atUint8* src, atUint8** dst, atUint32 srcLen
athena::utility::BigUint16(lenOff); athena::utility::BigUint16(lenOff);
decoding.length = (lenOff >> 12) + 1; decoding.length = (lenOff >> 12) + 1;
decoding.offset = (lenOff & 0xFFF) + 1; decoding.offset = (lenOff & 0xFFF) + 1;
} } else if (metaDataSize == 0) // Three Bytes of Length/Offset MetaData
else if (metaDataSize == 0) //Three Bytes of Length/Offset MetaData
{ {
atUint32 lenOff = 0; atUint32 lenOff = 0;
memcpy((atUint8*)&lenOff + 1, inputPtr, 3); memcpy((atUint8*)&lenOff + 1, inputPtr, 3);
@ -190,27 +172,25 @@ atUint32 LZType11::decompress(const atUint8* src, atUint8** dst, atUint32 srcLen
athena::utility::BigUint32(lenOff); athena::utility::BigUint32(lenOff);
decoding.length = (lenOff >> 12) + threeByteDenorm; decoding.length = (lenOff >> 12) + threeByteDenorm;
decoding.offset = (lenOff & 0xFFF) + 1; decoding.offset = (lenOff & 0xFFF) + 1;
} } else if (metaDataSize == 1) // Four Bytes of Length/Offset MetaData
else if (metaDataSize == 1) //Four Bytes of Length/Offset MetaData
{ {
atUint32 lenOff = 0; atUint32 lenOff = 0;
memcpy(&lenOff, inputPtr, 4); memcpy(&lenOff, inputPtr, 4);
inputPtr += 4; inputPtr += 4;
athena::utility::BigUint32(lenOff); athena::utility::BigUint32(lenOff);
decoding.length = ((lenOff >> 12) & 0xFFFF) + fourByteDenorm; //Gets rid of the Four byte flag decoding.length = ((lenOff >> 12) & 0xFFFF) + fourByteDenorm; // Gets rid of the Four byte flag
decoding.offset = (lenOff & 0xFFF) + 1; decoding.offset = (lenOff & 0xFFF) + 1;
} } else {
else
{
delete[] uncompressedData; delete[] uncompressedData;
uncompressedData = nullptr; uncompressedData = nullptr;
return 0; return 0;
} }
if ((outputPtr - decoding.offset) < uncompressedData) //If the offset to look for uncompressed is passed the current uncompresed data then the data is not compressed if ((outputPtr - decoding.offset) < uncompressedData) // If the offset to look for uncompressed is passed the
// current uncompresed data then the data is not compressed
{ {
delete []uncompressedData; delete[] uncompressedData;
return 0; return 0;
} }
@ -218,18 +198,14 @@ atUint32 LZType11::decompress(const atUint8* src, atUint8** dst, atUint32 srcLen
outputPtr[j] = (outputPtr - decoding.offset)[j]; outputPtr[j] = (outputPtr - decoding.offset)[j];
outputPtr += decoding.length; outputPtr += decoding.length;
} } else
else
*outputPtr++ = *inputPtr++; *outputPtr++ = *inputPtr++;
if (!(inputPtr < inputEndPtr && outputPtr < outputEndPtr)) if (!(inputPtr < inputEndPtr && outputPtr < outputEndPtr))
break; break;
} }
} }
*dst = uncompressedData; *dst = uncompressedData;
return uncompressedLen; return uncompressedLen;
} }

View File

@ -11,29 +11,26 @@
#define _AES_NI 1 #define _AES_NI 1
#endif #endif
namespace athena namespace athena {
{
/* rotates x one bit to the left */ /* rotates x one bit to the left */
#define ROTL(x) (((x)>>7)|((x)<<1)) #define ROTL(x) (((x) >> 7) | ((x) << 1))
/* Rotates 32-bit word left by 1, 2 or 3 byte */ /* Rotates 32-bit word left by 1, 2 or 3 byte */
#define ROTL8(x) (((x)<<8)|((x)>>24)) #define ROTL8(x) (((x) << 8) | ((x) >> 24))
#define ROTL16(x) (((x)<<16)|((x)>>16)) #define ROTL16(x) (((x) << 16) | ((x) >> 16))
#define ROTL24(x) (((x)<<24)|((x)>>8)) #define ROTL24(x) (((x) << 24) | ((x) >> 8))
static const uint8_t InCo[4] = {0xB, 0xD, 0x9, 0xE}; /* Inverse Coefficients */ static const uint8_t InCo[4] = {0xB, 0xD, 0x9, 0xE}; /* Inverse Coefficients */
static inline uint32_t pack(const uint8_t* b) static inline uint32_t pack(const uint8_t* b) {
{
/* pack bytes into a 32-bit Word */ /* pack bytes into a 32-bit Word */
return ((uint32_t)b[3] << 24) | ((uint32_t)b[2] << 16) | ((uint32_t)b[1] << 8) | (uint32_t)b[0]; return ((uint32_t)b[3] << 24) | ((uint32_t)b[2] << 16) | ((uint32_t)b[1] << 8) | (uint32_t)b[0];
} }
static inline void unpack(uint32_t a, uint8_t* b) static inline void unpack(uint32_t a, uint8_t* b) {
{
/* unpack bytes from a word */ /* unpack bytes from a word */
b[0] = (uint8_t)a; b[0] = (uint8_t)a;
b[1] = (uint8_t)(a >> 8); b[1] = (uint8_t)(a >> 8);
@ -41,13 +38,9 @@ static inline void unpack(uint32_t a, uint8_t* b)
b[3] = (uint8_t)(a >> 24); b[3] = (uint8_t)(a >> 24);
} }
static inline uint8_t xtime(uint8_t a) static inline uint8_t xtime(uint8_t a) { return ((a << 1) ^ (((a >> 7) & 1) * 0x11B)); }
{
return ((a << 1) ^ (((a>>7) & 1) * 0x11B));
}
static const struct SoftwareAESTables static const struct SoftwareAESTables {
{
uint8_t fbsub[256]; uint8_t fbsub[256];
uint8_t rbsub[256]; uint8_t rbsub[256];
uint8_t ptab[256], ltab[256]; uint8_t ptab[256], ltab[256];
@ -55,15 +48,15 @@ static const struct SoftwareAESTables
uint32_t rtable[256]; uint32_t rtable[256];
uint32_t rco[30]; uint32_t rco[30];
uint8_t bmul(uint8_t x, uint8_t y) const uint8_t bmul(uint8_t x, uint8_t y) const {
{
/* x.y= AntiLog(Log(x) + Log(y)) */ /* x.y= AntiLog(Log(x) + Log(y)) */
if (x && y) return ptab[(ltab[x] + ltab[y]) % 255]; if (x && y)
else return 0; return ptab[(ltab[x] + ltab[y]) % 255];
else
return 0;
} }
uint32_t SubByte(uint32_t a) const uint32_t SubByte(uint32_t a) const {
{
uint8_t b[4]; uint8_t b[4];
unpack(a, b); unpack(a, b);
b[0] = fbsub[b[0]]; b[0] = fbsub[b[0]];
@ -73,17 +66,15 @@ static const struct SoftwareAESTables
return pack(b); return pack(b);
} }
uint8_t product(uint32_t x, uint32_t y) const uint8_t product(uint32_t x, uint32_t y) const {
{
/* dot product of two 4-byte arrays */ /* dot product of two 4-byte arrays */
uint8_t xb[4], yb[4]; uint8_t xb[4], yb[4];
unpack(x, xb); unpack(x, xb);
unpack(y, yb); unpack(y, yb);
return bmul(xb[0], yb[0])^bmul(xb[1], yb[1])^bmul(xb[2], yb[2])^bmul(xb[3], yb[3]); return bmul(xb[0], yb[0]) ^ bmul(xb[1], yb[1]) ^ bmul(xb[2], yb[2]) ^ bmul(xb[3], yb[3]);
} }
uint32_t InvMixCol(uint32_t x) const uint32_t InvMixCol(uint32_t x) const {
{
/* matrix Multiplication */ /* matrix Multiplication */
uint32_t y, m; uint32_t y, m;
uint8_t b[4]; uint8_t b[4];
@ -100,8 +91,7 @@ static const struct SoftwareAESTables
return y; return y;
} }
uint8_t ByteSub(uint8_t x) const uint8_t ByteSub(uint8_t x) const {
{
uint8_t y = ptab[255 - ltab[x]]; /* multiplicative inverse */ uint8_t y = ptab[255 - ltab[x]]; /* multiplicative inverse */
x = y; x = y;
x = ROTL(x); x = ROTL(x);
@ -116,8 +106,7 @@ static const struct SoftwareAESTables
return y; return y;
} }
SoftwareAESTables() SoftwareAESTables() {
{
/* generate tables */ /* generate tables */
int i; int i;
uint8_t y, b[4]; uint8_t y, b[4];
@ -130,8 +119,7 @@ static const struct SoftwareAESTables
ptab[1] = 3; ptab[1] = 3;
ltab[3] = 1; ltab[3] = 1;
for (i = 2; i < 256; i++) for (i = 2; i < 256; i++) {
{
ptab[i] = ptab[i - 1] ^ xtime(ptab[i - 1]); ptab[i] = ptab[i - 1] ^ xtime(ptab[i - 1]);
ltab[ptab[i]] = i; ltab[ptab[i]] = i;
} }
@ -141,22 +129,19 @@ static const struct SoftwareAESTables
fbsub[0] = 0x63; fbsub[0] = 0x63;
rbsub[0x63] = 0; rbsub[0x63] = 0;
for (i = 1; i < 256; i++) for (i = 1; i < 256; i++) {
{
y = ByteSub((uint8_t)i); y = ByteSub((uint8_t)i);
fbsub[i] = y; fbsub[i] = y;
rbsub[y] = i; rbsub[y] = i;
} }
for (i = 0, y = 1; i < 30; i++) for (i = 0, y = 1; i < 30; i++) {
{
rco[i] = y; rco[i] = y;
y = xtime(y); y = xtime(y);
} }
/* calculate forward and reverse tables */ /* calculate forward and reverse tables */
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++) {
{
y = fbsub[i]; y = fbsub[i];
b[3] = y ^ xtime(y); b[3] = y ^ xtime(y);
b[2] = y; b[2] = y;
@ -174,8 +159,7 @@ static const struct SoftwareAESTables
} }
} AEStb; } AEStb;
class SoftwareAES : public IAES class SoftwareAES : public IAES {
{
protected: protected:
/* Parameter-dependent data */ /* Parameter-dependent data */
int Nk, Nb, Nr; int Nk, Nb, Nr;
@ -193,8 +177,7 @@ public:
void setKey(const uint8_t* key); void setKey(const uint8_t* key);
}; };
void SoftwareAES::gkey(int nb, int nk, const uint8_t* key) void SoftwareAES::gkey(int nb, int nk, const uint8_t* key) {
{
/* blocksize=32*nb bits. Key=32*nk bits */ /* blocksize=32*nb bits. Key=32*nk bits */
/* currently nb,bk = 4, 6 or 8 */ /* currently nb,bk = 4, 6 or 8 */
/* key comes as 4*Nk bytes */ /* key comes as 4*Nk bytes */
@ -207,17 +190,23 @@ void SoftwareAES::gkey(int nb, int nk, const uint8_t* key)
Nk = nk; Nk = nk;
/* Nr is number of rounds */ /* Nr is number of rounds */
if (Nb >= Nk) Nr = 6 + Nb; if (Nb >= Nk)
else Nr = 6 + Nk; Nr = 6 + Nb;
else
Nr = 6 + Nk;
C1 = 1; C1 = 1;
if (Nb < 8) { C2 = 2; C3 = 3; } if (Nb < 8) {
else { C2 = 3; C3 = 4; } C2 = 2;
C3 = 3;
} else {
C2 = 3;
C3 = 4;
}
/* pre-calculate forward and reverse increments */ /* pre-calculate forward and reverse increments */
for (m = j = 0; j < nb; j++, m += 3) for (m = j = 0; j < nb; j++, m += 3) {
{
fi[m] = (j + C1) % nb; fi[m] = (j + C1) % nb;
fi[m + 1] = (j + C2) % nb; fi[m + 1] = (j + C2) % nb;
fi[m + 2] = (j + C3) % nb; fi[m + 2] = (j + C3) % nb;
@ -228,61 +217,56 @@ void SoftwareAES::gkey(int nb, int nk, const uint8_t* key)
N = Nb * (Nr + 1); N = Nb * (Nr + 1);
for (i = j = 0; i < Nk; i++, j += 4) for (i = j = 0; i < Nk; i++, j += 4) {
{
CipherKey[i] = pack(key + j); CipherKey[i] = pack(key + j);
} }
for (i = 0; i < Nk; i++) fkey[i] = CipherKey[i]; for (i = 0; i < Nk; i++)
fkey[i] = CipherKey[i];
for (j = Nk, k = 0; j < N; j += Nk, k++) for (j = Nk, k = 0; j < N; j += Nk, k++) {
{ fkey[j] = fkey[j - Nk] ^ AEStb.SubByte(ROTL24(fkey[j - 1])) ^ AEStb.rco[k];
fkey[j] = fkey[j - Nk] ^ AEStb.SubByte(ROTL24(fkey[j - 1]))^AEStb.rco[k];
if (Nk <= 6) if (Nk <= 6) {
{
for (i = 1; i < Nk && (i + j) < N; i++) for (i = 1; i < Nk && (i + j) < N; i++)
fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1]; fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1];
} } else {
else
{
for (i = 1; i < 4 && (i + j) < N; i++) for (i = 1; i < 4 && (i + j) < N; i++)
fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1]; fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1];
if ((j + 4) < N) fkey[j + 4] = fkey[j + 4 - Nk] ^ AEStb.SubByte(fkey[j + 3]); if ((j + 4) < N)
fkey[j + 4] = fkey[j + 4 - Nk] ^ AEStb.SubByte(fkey[j + 3]);
for (i = 5; i < Nk && (i + j) < N; i++) for (i = 5; i < Nk && (i + j) < N; i++)
fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1]; fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1];
} }
} }
/* now for the expanded decrypt key in reverse order */ /* now for the expanded decrypt key in reverse order */
for (j = 0; j < Nb; j++) rkey[j + N - Nb] = fkey[j]; for (j = 0; j < Nb; j++)
rkey[j + N - Nb] = fkey[j];
for (i = Nb; i < N - Nb; i += Nb) for (i = Nb; i < N - Nb; i += Nb) {
{
k = N - Nb - i; k = N - Nb - i;
for (j = 0; j < Nb; j++) rkey[k + j] = AEStb.InvMixCol(fkey[i + j]); for (j = 0; j < Nb; j++)
rkey[k + j] = AEStb.InvMixCol(fkey[i + j]);
} }
for (j = N - Nb; j < N; j++) rkey[j - N + Nb] = fkey[j]; for (j = N - Nb; j < N; j++)
rkey[j - N + Nb] = fkey[j];
} }
/* There is an obvious time/space trade-off possible here. * /* There is an obvious time/space trade-off possible here. *
* Instead of just one ftable[], I could have 4, the other * * Instead of just one ftable[], I could have 4, the other *
* 3 pre-rotated to save the ROTL8, ROTL16 and ROTL24 overhead */ * 3 pre-rotated to save the ROTL8, ROTL16 and ROTL24 overhead */
void SoftwareAES::_encrypt(uint8_t* buff) void SoftwareAES::_encrypt(uint8_t* buff) {
{
int i, j, k, m; int i, j, k, m;
uint32_t a[8], b[8], *x, *y, *t; uint32_t a[8], b[8], *x, *y, *t;
for (i = j = 0; i < Nb; i++, j += 4) for (i = j = 0; i < Nb; i++, j += 4) {
{
a[i] = pack(buff + j); a[i] = pack(buff + j);
a[i] ^= fkey[i]; a[i] ^= fkey[i];
} }
@ -292,21 +276,17 @@ void SoftwareAES::_encrypt(uint8_t* buff)
y = b; y = b;
/* State alternates between a and b */ /* State alternates between a and b */
for (i = 1; i < Nr; i++) for (i = 1; i < Nr; i++) {
{
/* Nr is number of rounds. May be odd. */ /* Nr is number of rounds. May be odd. */
/* if Nb is fixed - unroll this next /* if Nb is fixed - unroll this next
loop and hard-code in the values of fi[] */ loop and hard-code in the values of fi[] */
for (m = j = 0; j < Nb; j++, m += 3) for (m = j = 0; j < Nb; j++, m += 3) {
{
/* deal with each 32-bit element of the State */ /* deal with each 32-bit element of the State */
/* This is the time-critical bit */ /* This is the time-critical bit */
y[j] = fkey[k++] ^ AEStb.ftable[(uint8_t)x[j]] ^ y[j] = fkey[k++] ^ AEStb.ftable[(uint8_t)x[j]] ^ ROTL8(AEStb.ftable[(uint8_t)(x[fi[m]] >> 8)]) ^
ROTL8(AEStb.ftable[(uint8_t)(x[fi[m]] >> 8)])^ ROTL16(AEStb.ftable[(uint8_t)(x[fi[m + 1]] >> 16)]) ^ ROTL24(AEStb.ftable[(uint8_t)(x[fi[m + 2]] >> 24)]);
ROTL16(AEStb.ftable[(uint8_t)(x[fi[m + 1]] >> 16)])^
ROTL24(AEStb.ftable[(uint8_t)(x[fi[m + 2]] >> 24)]);
} }
t = x; t = x;
@ -315,16 +295,13 @@ void SoftwareAES::_encrypt(uint8_t* buff)
} }
/* Last Round - unroll if possible */ /* Last Round - unroll if possible */
for (m = j = 0; j < Nb; j++, m += 3) for (m = j = 0; j < Nb; j++, m += 3) {
{ y[j] = fkey[k++] ^ (uint32_t)AEStb.fbsub[(uint8_t)x[j]] ^ ROTL8((uint32_t)AEStb.fbsub[(uint8_t)(x[fi[m]] >> 8)]) ^
y[j] = fkey[k++] ^ (uint32_t)AEStb.fbsub[(uint8_t)x[j]] ^ ROTL16((uint32_t)AEStb.fbsub[(uint8_t)(x[fi[m + 1]] >> 16)]) ^
ROTL8((uint32_t)AEStb.fbsub[(uint8_t)(x[fi[m]] >> 8)])^
ROTL16((uint32_t)AEStb.fbsub[(uint8_t)(x[fi[m + 1]] >> 16)])^
ROTL24((uint32_t)AEStb.fbsub[(uint8_t)(x[fi[m + 2]] >> 24)]); ROTL24((uint32_t)AEStb.fbsub[(uint8_t)(x[fi[m + 2]] >> 24)]);
} }
for (i = j = 0; i < Nb; i++, j += 4) for (i = j = 0; i < Nb; i++, j += 4) {
{
unpack(y[i], (uint8_t*)&buff[j]); unpack(y[i], (uint8_t*)&buff[j]);
x[i] = y[i] = 0; /* clean up stack */ x[i] = y[i] = 0; /* clean up stack */
} }
@ -332,13 +309,11 @@ void SoftwareAES::_encrypt(uint8_t* buff)
return; return;
} }
void SoftwareAES::_decrypt(uint8_t* buff) void SoftwareAES::_decrypt(uint8_t* buff) {
{
int i, j, k, m; int i, j, k, m;
uint32_t a[8], b[8], *x, *y, *t; uint32_t a[8], b[8], *x, *y, *t;
for (i = j = 0; i < Nb; i++, j += 4) for (i = j = 0; i < Nb; i++, j += 4) {
{
a[i] = pack(buff + j); a[i] = pack(buff + j);
a[i] ^= rkey[i]; a[i] ^= rkey[i];
} }
@ -348,20 +323,16 @@ void SoftwareAES::_decrypt(uint8_t* buff)
y = b; y = b;
/* State alternates between a and b */ /* State alternates between a and b */
for (i = 1; i < Nr; i++) for (i = 1; i < Nr; i++) {
{
/* Nr is number of rounds. May be odd. */ /* Nr is number of rounds. May be odd. */
/* if Nb is fixed - unroll this next /* if Nb is fixed - unroll this next
loop and hard-code in the values of ri[] */ loop and hard-code in the values of ri[] */
for (m = j = 0; j < Nb; j++, m += 3) for (m = j = 0; j < Nb; j++, m += 3) {
{
/* This is the time-critical bit */ /* This is the time-critical bit */
y[j] = rkey[k++] ^ AEStb.rtable[(uint8_t)x[j]] ^ y[j] = rkey[k++] ^ AEStb.rtable[(uint8_t)x[j]] ^ ROTL8(AEStb.rtable[(uint8_t)(x[ri[m]] >> 8)]) ^
ROTL8(AEStb.rtable[(uint8_t)(x[ri[m]] >> 8)])^ ROTL16(AEStb.rtable[(uint8_t)(x[ri[m + 1]] >> 16)]) ^ ROTL24(AEStb.rtable[(uint8_t)(x[ri[m + 2]] >> 24)]);
ROTL16(AEStb.rtable[(uint8_t)(x[ri[m + 1]] >> 16)])^
ROTL24(AEStb.rtable[(uint8_t)(x[ri[m + 2]] >> 24)]);
} }
t = x; t = x;
@ -370,16 +341,13 @@ void SoftwareAES::_decrypt(uint8_t* buff)
} }
/* Last Round - unroll if possible */ /* Last Round - unroll if possible */
for (m = j = 0; j < Nb; j++, m += 3) for (m = j = 0; j < Nb; j++, m += 3) {
{ y[j] = rkey[k++] ^ (uint32_t)AEStb.rbsub[(uint8_t)x[j]] ^ ROTL8((uint32_t)AEStb.rbsub[(uint8_t)(x[ri[m]] >> 8)]) ^
y[j] = rkey[k++] ^ (uint32_t)AEStb.rbsub[(uint8_t)x[j]] ^ ROTL16((uint32_t)AEStb.rbsub[(uint8_t)(x[ri[m + 1]] >> 16)]) ^
ROTL8((uint32_t)AEStb.rbsub[(uint8_t)(x[ri[m]] >> 8)])^
ROTL16((uint32_t)AEStb.rbsub[(uint8_t)(x[ri[m + 1]] >> 16)])^
ROTL24((uint32_t)AEStb.rbsub[(uint8_t)(x[ri[m + 2]] >> 24)]); ROTL24((uint32_t)AEStb.rbsub[(uint8_t)(x[ri[m + 2]] >> 24)]);
} }
for (i = j = 0; i < Nb; i++, j += 4) for (i = j = 0; i < Nb; i++, j += 4) {
{
unpack(y[i], (uint8_t*)&buff[j]); unpack(y[i], (uint8_t*)&buff[j]);
x[i] = y[i] = 0; /* clean up stack */ x[i] = y[i] = 0; /* clean up stack */
} }
@ -387,45 +355,42 @@ void SoftwareAES::_decrypt(uint8_t* buff)
return; return;
} }
void SoftwareAES::setKey(const uint8_t* key) void SoftwareAES::setKey(const uint8_t* key) { gkey(4, 4, key); }
{
gkey(4, 4, key);
}
// CBC mode decryption // CBC mode decryption
void SoftwareAES::decrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len) void SoftwareAES::decrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len) {
{
uint8_t block[16]; uint8_t block[16];
const uint8_t* ctext_ptr; const uint8_t* ctext_ptr;
unsigned int blockno = 0, i; unsigned int blockno = 0, i;
//fprintf( stderr,"aes_decrypt(%p, %p, %p, %lld)\n", iv, inbuf, outbuf, len ); // fprintf( stderr,"aes_decrypt(%p, %p, %p, %lld)\n", iv, inbuf, outbuf, len );
//printf("aes_decrypt(%p, %p, %p, %lld)\n", iv, inbuf, outbuf, len); // printf("aes_decrypt(%p, %p, %p, %lld)\n", iv, inbuf, outbuf, len);
for (blockno = 0; blockno <= (len / sizeof(block)); blockno++) for (blockno = 0; blockno <= (len / sizeof(block)); blockno++) {
{
unsigned int fraction; unsigned int fraction;
if (blockno == (len / sizeof(block))) // last block if (blockno == (len / sizeof(block))) // last block
{ {
fraction = len % sizeof(block); fraction = len % sizeof(block);
if (fraction == 0) break; if (fraction == 0)
break;
memset(block, 0, sizeof(block)); memset(block, 0, sizeof(block));
} } else
else fraction = 16; fraction = 16;
// debug_printf("block %d: fraction = %d\n", blockno, fraction); // debug_printf("block %d: fraction = %d\n", blockno, fraction);
memcpy(block, inbuf + blockno * sizeof(block), fraction); memcpy(block, inbuf + blockno * sizeof(block), fraction);
_decrypt(block); _decrypt(block);
if (blockno == 0) ctext_ptr = iv; if (blockno == 0)
else ctext_ptr = (uint8_t*)(inbuf + (blockno - 1) * sizeof(block)); ctext_ptr = iv;
else
ctext_ptr = (uint8_t*)(inbuf + (blockno - 1) * sizeof(block));
for (i = 0; i < fraction; i++) for (i = 0; i < fraction; i++)
outbuf[blockno * sizeof(block) + i] = outbuf[blockno * sizeof(block) + i] = ctext_ptr[i] ^ block[i];
ctext_ptr[i] ^ block[i];
// debug_printf("Block %d output: ", blockno); // debug_printf("Block %d output: ", blockno);
// hexdump(outbuf + blockno*sizeof(block), 16); // hexdump(outbuf + blockno*sizeof(block), 16);
@ -433,29 +398,28 @@ void SoftwareAES::decrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outb
} }
// CBC mode encryption // CBC mode encryption
void SoftwareAES::encrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len) void SoftwareAES::encrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len) {
{
uint8_t block[16]; uint8_t block[16];
uint8_t feedback[16]; uint8_t feedback[16];
memcpy(feedback, iv, 16); memcpy(feedback, iv, 16);
unsigned int blockno = 0, i; unsigned int blockno = 0, i;
//printf("aes_decrypt(%p, %p, %p, %lld)\n", iv, inbuf, outbuf, len); // printf("aes_decrypt(%p, %p, %p, %lld)\n", iv, inbuf, outbuf, len);
//fprintf( stderr,"aes_encrypt(%p, %p, %p, %lld)\n", iv, inbuf, outbuf, len); // fprintf( stderr,"aes_encrypt(%p, %p, %p, %lld)\n", iv, inbuf, outbuf, len);
for (blockno = 0; blockno <= (len / sizeof(block)); blockno++) for (blockno = 0; blockno <= (len / sizeof(block)); blockno++) {
{
unsigned int fraction; unsigned int fraction;
if (blockno == (len / sizeof(block))) // last block if (blockno == (len / sizeof(block))) // last block
{ {
fraction = len % sizeof(block); fraction = len % sizeof(block);
if (fraction == 0) break; if (fraction == 0)
break;
memset(block, 0, sizeof(block)); memset(block, 0, sizeof(block));
} } else
else fraction = 16; fraction = 16;
// debug_printf("block %d: fraction = %d\n", blockno, fraction); // debug_printf("block %d: fraction = %d\n", blockno, fraction);
memcpy(block, inbuf + blockno * sizeof(block), fraction); memcpy(block, inbuf + blockno * sizeof(block), fraction);
@ -475,45 +439,41 @@ void SoftwareAES::encrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outb
#include <wmmintrin.h> #include <wmmintrin.h>
class NiAES : public IAES class NiAES : public IAES {
{
__m128i m_ekey[11]; __m128i m_ekey[11];
__m128i m_dkey[11]; __m128i m_dkey[11];
public: public:
void encrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len) void encrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len) {
{ __m128i feedback, data;
__m128i feedback,data; uint64_t i, j;
uint64_t i,j; if (len % 16)
if (len%16) len = len / 16 + 1;
len = len/16+1;
else else
len /= 16; len /= 16;
feedback = _mm_loadu_si128((__m128i*)iv); feedback = _mm_loadu_si128((__m128i*)iv);
for (i=0 ; i<len ; i++) for (i = 0; i < len; i++) {
{
data = _mm_loadu_si128(&((__m128i*)inbuf)[i]); data = _mm_loadu_si128(&((__m128i*)inbuf)[i]);
feedback = _mm_xor_si128(data, feedback); feedback = _mm_xor_si128(data, feedback);
feedback = _mm_xor_si128(feedback, m_ekey[0]); feedback = _mm_xor_si128(feedback, m_ekey[0]);
for (j=1 ; j<10 ; j++) for (j = 1; j < 10; j++)
feedback = _mm_aesenc_si128(feedback, m_ekey[j]); feedback = _mm_aesenc_si128(feedback, m_ekey[j]);
feedback = _mm_aesenclast_si128(feedback, m_ekey[j]); feedback = _mm_aesenclast_si128(feedback, m_ekey[j]);
_mm_storeu_si128(&((__m128i*)outbuf)[i], feedback); _mm_storeu_si128(&((__m128i*)outbuf)[i], feedback);
} }
} }
void decrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len) void decrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len) {
{ __m128i data, feedback, last_in;
__m128i data,feedback,last_in; uint64_t i, j;
uint64_t i,j; if (len % 16)
if (len%16) len = len / 16 + 1;
len = len/16+1;
else else
len /= 16; len /= 16;
feedback = _mm_loadu_si128((__m128i*)iv); feedback = _mm_loadu_si128((__m128i*)iv);
for (i=0 ; i<len ; i++) for (i = 0; i < len; i++) {
{ last_in = _mm_loadu_si128(&((__m128i*)inbuf)[i]);
last_in=_mm_loadu_si128(&((__m128i*)inbuf)[i]);
data = _mm_xor_si128(last_in, m_dkey[0]); data = _mm_xor_si128(last_in, m_dkey[0]);
for (j=1 ; j<10 ; j++) for (j = 1; j < 10; j++)
data = _mm_aesdec_si128(data, m_dkey[j]); data = _mm_aesdec_si128(data, m_dkey[j]);
data = _mm_aesdeclast_si128(data, m_dkey[j]); data = _mm_aesdeclast_si128(data, m_dkey[j]);
data = _mm_xor_si128(data, feedback); data = _mm_xor_si128(data, feedback);
@ -522,22 +482,20 @@ public:
} }
} }
static inline __m128i AES_128_ASSIST (__m128i temp1, __m128i temp2) static inline __m128i AES_128_ASSIST(__m128i temp1, __m128i temp2) {
{
__m128i temp3; __m128i temp3;
temp2 = _mm_shuffle_epi32 (temp2 ,0xff); temp2 = _mm_shuffle_epi32(temp2, 0xff);
temp3 = _mm_slli_si128 (temp1, 0x4); temp3 = _mm_slli_si128(temp1, 0x4);
temp1 = _mm_xor_si128 (temp1, temp3); temp1 = _mm_xor_si128(temp1, temp3);
temp3 = _mm_slli_si128 (temp3, 0x4); temp3 = _mm_slli_si128(temp3, 0x4);
temp1 = _mm_xor_si128 (temp1, temp3); temp1 = _mm_xor_si128(temp1, temp3);
temp3 = _mm_slli_si128 (temp3, 0x4); temp3 = _mm_slli_si128(temp3, 0x4);
temp1 = _mm_xor_si128 (temp1, temp3); temp1 = _mm_xor_si128(temp1, temp3);
temp1 = _mm_xor_si128 (temp1, temp2); temp1 = _mm_xor_si128(temp1, temp2);
return temp1; return temp1;
} }
void setKey(const uint8_t* key) void setKey(const uint8_t* key) {
{
__m128i temp1, temp2; __m128i temp1, temp2;
temp1 = _mm_loadu_si128((__m128i*)key); temp1 = _mm_loadu_si128((__m128i*)key);
@ -590,18 +548,16 @@ static int HAS_AES_NI = -1;
#endif #endif
std::unique_ptr<IAES> NewAES() std::unique_ptr<IAES> NewAES() {
{
#if _AES_NI #if _AES_NI
if (HAS_AES_NI == -1) if (HAS_AES_NI == -1) {
{
#if _MSC_VER #if _MSC_VER
int info[4]; int info[4];
__cpuid(info, 1); __cpuid(info, 1);
HAS_AES_NI = ((info[2] & 0x2000000) != 0); HAS_AES_NI = ((info[2] & 0x2000000) != 0);
#else #else
unsigned int a,b,c,d; unsigned int a, b, c, d;
__cpuid(1, a,b,c,d); __cpuid(1, a, b, c, d);
HAS_AES_NI = ((c & 0x2000000) != 0); HAS_AES_NI = ((c & 0x2000000) != 0);
#endif #endif
} }
@ -614,5 +570,4 @@ std::unique_ptr<IAES> NewAES()
#endif #endif
} }
} } // namespace athena

View File

@ -1,21 +1,14 @@
#include "athena/ALTTPFile.hpp" #include "athena/ALTTPFile.hpp"
#include "athena/ALTTPQuest.hpp" #include "athena/ALTTPQuest.hpp"
namespace athena namespace athena {
{ ALTTPFile::ALTTPFile() {}
ALTTPFile::ALTTPFile()
{}
ALTTPFile::ALTTPFile(std::vector<ALTTPQuest*> quests, std::vector<ALTTPQuest*> backup) ALTTPFile::ALTTPFile(std::vector<ALTTPQuest*> quests, std::vector<ALTTPQuest*> backup)
: m_quests(quests) : m_quests(quests), m_backup(backup) {}
, m_backup(backup)
{
}
void ALTTPFile::setQuest(atUint32 id, ALTTPQuest* val) void ALTTPFile::setQuest(atUint32 id, ALTTPQuest* val) {
{ if (id > m_quests.size()) {
if (id > m_quests.size())
{
atWarning("index out of range"); atWarning("index out of range");
return; return;
} }
@ -23,14 +16,9 @@ void ALTTPFile::setQuest(atUint32 id, ALTTPQuest* val)
m_quests[id] = val; m_quests[id] = val;
} }
std::vector<ALTTPQuest*> ALTTPFile::questList() const std::vector<ALTTPQuest*> ALTTPFile::questList() const { return m_quests; }
{ ALTTPQuest* ALTTPFile::quest(atUint32 id) const {
return m_quests; if (id > m_quests.size()) {
}
ALTTPQuest* ALTTPFile::quest(atUint32 id) const
{
if (id > m_quests.size())
{
atWarning("index out of range"); atWarning("index out of range");
return nullptr; return nullptr;
} }
@ -38,8 +26,5 @@ ALTTPQuest* ALTTPFile::quest(atUint32 id) const
return m_quests[id]; return m_quests[id];
} }
atUint32 ALTTPFile::questCount() const atUint32 ALTTPFile::questCount() const { return (atUint32)m_quests.size(); }
{ } // namespace athena
return (atUint32)m_quests.size();
}
} // zelda

View File

@ -4,26 +4,17 @@
#include <iostream> #include <iostream>
#include "athena/Global.hpp" #include "athena/Global.hpp"
namespace athena::io namespace athena::io {
{
ALTTPFileReader::ALTTPFileReader(atUint8* data, atUint64 length) ALTTPFileReader::ALTTPFileReader(atUint8* data, atUint64 length) : MemoryCopyReader(data, length) {}
: MemoryCopyReader(data, length)
{
}
ALTTPFileReader::ALTTPFileReader(const std::string& filename) ALTTPFileReader::ALTTPFileReader(const std::string& filename) : MemoryCopyReader(filename) {}
: MemoryCopyReader(filename)
{
}
ALTTPFile* ALTTPFileReader::readFile() ALTTPFile* ALTTPFileReader::readFile() {
{
std::vector<ALTTPQuest*> quests; std::vector<ALTTPQuest*> quests;
std::vector<ALTTPQuest*> backup; std::vector<ALTTPQuest*> backup;
for (atUint32 i = 0; i < 6; i++) for (atUint32 i = 0; i < 6; i++) {
{
// Temporary values to use for each save // Temporary values to use for each save
ALTTPQuest* quest = new ALTTPQuest(); ALTTPQuest* quest = new ALTTPQuest();
std::vector<ALTTPRoomFlags*> roomFlags; std::vector<ALTTPRoomFlags*> roomFlags;
@ -36,8 +27,7 @@ ALTTPFile* ALTTPFileReader::readFile()
int j = 0x140; int j = 0x140;
while ((j--) > 0) while ((j--) > 0) {
{
roomFlags.push_back(readRoomFlags()); roomFlags.push_back(readRoomFlags());
} }
@ -96,8 +86,7 @@ ALTTPFile* ALTTPFileReader::readFile()
j = 0x10; j = 0x10;
while ((j--) > 0) while ((j--) > 0) {
{
dungeonKeys.push_back(readByte()); dungeonKeys.push_back(readByte());
} }
@ -114,8 +103,7 @@ ALTTPFile* ALTTPFileReader::readFile()
j = 6; j = 6;
while ((j--) > 0) while ((j--) > 0) {
{
oldmanFlags.push_back(readByte()); oldmanFlags.push_back(readByte());
} }
@ -124,8 +112,7 @@ ALTTPFile* ALTTPFileReader::readFile()
j = 5; j = 5;
while ((j--) > 0) while ((j--) > 0) {
{
unknown1.push_back(readByte()); unknown1.push_back(readByte());
} }
@ -133,8 +120,7 @@ ALTTPFile* ALTTPFileReader::readFile()
j = 6; j = 6;
while ((j--) > 0) while ((j--) > 0) {
{
playerName.push_back(readUint16()); playerName.push_back(readUint16());
} }
@ -143,8 +129,7 @@ ALTTPFile* ALTTPFileReader::readFile()
j = 0x0D; j = 0x0D;
while ((j--) > 0) while ((j--) > 0) {
{
dungeonDeaths.push_back(readUint16()); dungeonDeaths.push_back(readUint16());
} }
@ -167,8 +152,7 @@ ALTTPFile* ALTTPFileReader::readFile()
return new ALTTPFile(quests, backup); return new ALTTPFile(quests, backup);
} }
ALTTPRoomFlags* ALTTPFileReader::readRoomFlags() ALTTPRoomFlags* ALTTPFileReader::readRoomFlags() {
{
ALTTPRoomFlags* flags = new ALTTPRoomFlags; ALTTPRoomFlags* flags = new ALTTPRoomFlags;
atUint8 flagsByte = readUByte(); atUint8 flagsByte = readUByte();
flags->Chest1 = flagsByte & 1; flags->Chest1 = flagsByte & 1;
@ -192,8 +176,7 @@ ALTTPRoomFlags* ALTTPFileReader::readRoomFlags()
return flags; return flags;
} }
ALTTPOverworldEvent* ALTTPFileReader::readOverworldEvent() ALTTPOverworldEvent* ALTTPFileReader::readOverworldEvent() {
{
ALTTPOverworldEvent* event = new ALTTPOverworldEvent; ALTTPOverworldEvent* event = new ALTTPOverworldEvent;
atUint8 flagsByte = readUByte(); atUint8 flagsByte = readUByte();
event->Unused1 = flagsByte & 1; event->Unused1 = flagsByte & 1;
@ -207,8 +190,7 @@ ALTTPOverworldEvent* ALTTPFileReader::readOverworldEvent()
return event; return event;
} }
ALTTPDungeonItemFlags ALTTPFileReader::readDungeonFlags() ALTTPDungeonItemFlags ALTTPFileReader::readDungeonFlags() {
{
ALTTPDungeonItemFlags flags; ALTTPDungeonItemFlags flags;
atUint8 flagsByte = readUByte(); atUint8 flagsByte = readUByte();
flags.Unused1 = flagsByte & 1; flags.Unused1 = flagsByte & 1;
@ -233,4 +215,4 @@ ALTTPDungeonItemFlags ALTTPFileReader::readDungeonFlags()
return flags; return flags;
} }
} // io } // namespace athena::io

View File

@ -3,40 +3,28 @@
#include "athena/ALTTPQuest.hpp" #include "athena/ALTTPQuest.hpp"
#include <iostream> #include <iostream>
namespace athena namespace athena {
{
namespace io namespace io {
{
ALTTPFileWriter::ALTTPFileWriter(atUint8* data, atUint64 length) ALTTPFileWriter::ALTTPFileWriter(atUint8* data, atUint64 length) : MemoryCopyWriter(data, length) {}
: MemoryCopyWriter(data, length)
{
}
ALTTPFileWriter::ALTTPFileWriter(const std::string& filename) ALTTPFileWriter::ALTTPFileWriter(const std::string& filename) : MemoryCopyWriter(filename) {}
: MemoryCopyWriter(filename)
{
}
void ALTTPFileWriter::writeFile(ALTTPFile* file) void ALTTPFileWriter::writeFile(ALTTPFile* file) {
{
ALTTPQuest* quest = NULL; ALTTPQuest* quest = NULL;
for (atUint32 i = 0; i < 6; i++) for (atUint32 i = 0; i < 6; i++) {
{
if (i < 3) if (i < 3)
quest = file->quest(i); quest = file->quest(i);
else else
quest = file->quest(i - 3); quest = file->quest(i - 3);
for (int j = 0; j < 0x140; j++) for (int j = 0; j < 0x140; j++) {
{
writeRoomFlags(quest->roomFlags(j)); writeRoomFlags(quest->roomFlags(j));
} }
for (int j = 0; j < 0x0C0; j++) for (int j = 0; j < 0x0C0; j++) {
{
writeOverworldEvent(quest->overworldEvent(j)); writeOverworldEvent(quest->overworldEvent(j));
} }
@ -113,7 +101,6 @@ void ALTTPFileWriter::writeFile(ALTTPFile* file)
for (int j = 0; j < 0x0D; j++) for (int j = 0; j < 0x0D; j++)
writeUint16(quest->dungeonDeathTotal(j)); writeUint16(quest->dungeonDeathTotal(j));
writeUint16(quest->unknown2()); writeUint16(quest->unknown2());
writeUint16(quest->deathSaveCount()); writeUint16(quest->deathSaveCount());
writeUint16(quest->postGameDeathCounter()); writeUint16(quest->postGameDeathCounter());
@ -123,8 +110,7 @@ void ALTTPFileWriter::writeFile(ALTTPFile* file)
} }
} }
void ALTTPFileWriter::writeRoomFlags(ALTTPRoomFlags* flags) void ALTTPFileWriter::writeRoomFlags(ALTTPRoomFlags* flags) {
{
atUint8 flagsByte = 0; atUint8 flagsByte = 0;
flagsByte |= flags->Chest1; flagsByte |= flags->Chest1;
flagsByte |= flags->Chest2 << 1; flagsByte |= flags->Chest2 << 1;
@ -147,8 +133,7 @@ void ALTTPFileWriter::writeRoomFlags(ALTTPRoomFlags* flags)
writeUByte(flagsByte); writeUByte(flagsByte);
} }
void ALTTPFileWriter::writeOverworldEvent(ALTTPOverworldEvent* event) void ALTTPFileWriter::writeOverworldEvent(ALTTPOverworldEvent* event) {
{
atUint8 flagsByte = 0; atUint8 flagsByte = 0;
flagsByte |= event->Unused1; flagsByte |= event->Unused1;
flagsByte |= event->HeartPiece << 1; flagsByte |= event->HeartPiece << 1;
@ -161,8 +146,7 @@ void ALTTPFileWriter::writeOverworldEvent(ALTTPOverworldEvent* event)
writeUByte(flagsByte); writeUByte(flagsByte);
} }
void ALTTPFileWriter::writeDungeonItems(ALTTPDungeonItemFlags flags) void ALTTPFileWriter::writeDungeonItems(ALTTPDungeonItemFlags flags) {
{
atUint8 flagsByte = 0; atUint8 flagsByte = 0;
flagsByte |= flags.Unused1; flagsByte |= flags.Unused1;
flagsByte |= flags.Unused2 << 1; flagsByte |= flags.Unused2 << 1;
@ -184,8 +168,7 @@ void ALTTPFileWriter::writeDungeonItems(ALTTPDungeonItemFlags flags)
writeUByte(flagsByte); writeUByte(flagsByte);
} }
atUint16 ALTTPFileWriter::calculateChecksum(atUint32 game) atUint16 ALTTPFileWriter::calculateChecksum(atUint32 game) {
{
/* /*
* ALTTP's checksum is very basic * ALTTP's checksum is very basic
* It adds each word up and then subtracts the sum from 0x5a5a * It adds each word up and then subtracts the sum from 0x5a5a
@ -219,5 +202,5 @@ atUint16 ALTTPFileWriter::calculateChecksum(atUint32 game)
*/ */
} }
} // io } // namespace io
} // zelda } // namespace athena

View File

@ -1,15 +1,11 @@
#include "athena/ALTTPQuest.hpp" #include "athena/ALTTPQuest.hpp"
#include <iostream> #include <iostream>
namespace athena namespace athena {
{
ALTTPQuest::ALTTPQuest() ALTTPQuest::ALTTPQuest() {}
{
}
ALTTPQuest::~ALTTPQuest() ALTTPQuest::~ALTTPQuest() {
{
m_roomFlags.clear(); m_roomFlags.clear();
m_overworldEvents.clear(); m_overworldEvents.clear();
m_oldManFlags.clear(); m_oldManFlags.clear();
@ -17,45 +13,22 @@ ALTTPQuest::~ALTTPQuest()
m_unknown1.clear(); m_unknown1.clear();
} }
void ALTTPQuest::setRoomFlags(std::vector<ALTTPRoomFlags*> rf) void ALTTPQuest::setRoomFlags(std::vector<ALTTPRoomFlags*> rf) { m_roomFlags = rf; }
{
m_roomFlags = rf;
}
void ALTTPQuest::setRoomFlags(ALTTPRoomFlags* rf, atUint32 id) void ALTTPQuest::setRoomFlags(ALTTPRoomFlags* rf, atUint32 id) { m_roomFlags[id] = rf; }
{
m_roomFlags[id] = rf;
}
std::vector<ALTTPRoomFlags*> ALTTPQuest::roomFlags() std::vector<ALTTPRoomFlags*> ALTTPQuest::roomFlags() { return m_roomFlags; }
{
return m_roomFlags;
}
ALTTPRoomFlags* ALTTPQuest::roomFlags(atUint32 id) ALTTPRoomFlags* ALTTPQuest::roomFlags(atUint32 id) { return m_roomFlags[id]; }
{
return m_roomFlags[id];
}
void ALTTPQuest::setOverworldEvents(std::vector<ALTTPOverworldEvent*> ow) void ALTTPQuest::setOverworldEvents(std::vector<ALTTPOverworldEvent*> ow) { m_overworldEvents = ow; }
{
m_overworldEvents = ow;
}
void ALTTPQuest::setOverworldEvents(ALTTPOverworldEvent* ow, atUint32 id) void ALTTPQuest::setOverworldEvents(ALTTPOverworldEvent* ow, atUint32 id) { m_overworldEvents[id] = ow; }
{
m_overworldEvents[id] = ow;
}
std::vector<ALTTPOverworldEvent*> ALTTPQuest::overworldEvents() const std::vector<ALTTPOverworldEvent*> ALTTPQuest::overworldEvents() const { return m_overworldEvents; }
{
return m_overworldEvents;
}
ALTTPOverworldEvent* ALTTPQuest::overworldEvent(atUint32 id) const ALTTPOverworldEvent* ALTTPQuest::overworldEvent(atUint32 id) const {
{ if (id > m_overworldEvents.size() - 1) {
if (id > m_overworldEvents.size() - 1)
{
atWarning("index out of range"); atWarning("index out of range");
return nullptr; return nullptr;
} }
@ -63,233 +36,96 @@ ALTTPOverworldEvent* ALTTPQuest::overworldEvent(atUint32 id) const
return m_overworldEvents[id]; return m_overworldEvents[id];
} }
void ALTTPQuest::setInventory(const ALTTPInventory& inv) void ALTTPQuest::setInventory(const ALTTPInventory& inv) { m_inventory = inv; }
{
m_inventory = inv;
}
const ALTTPInventory& ALTTPQuest::inventory() const const ALTTPInventory& ALTTPQuest::inventory() const { return m_inventory; }
{
return m_inventory;
}
void ALTTPQuest::setRupeeMax(atUint16 val) void ALTTPQuest::setRupeeMax(atUint16 val) { m_rupeeMax = val; }
{
m_rupeeMax = val;
}
atUint16 ALTTPQuest::rupeeMax() const atUint16 ALTTPQuest::rupeeMax() const { return m_rupeeMax; }
{
return m_rupeeMax;
}
void ALTTPQuest::setRupeeCurrent(atUint16 val) void ALTTPQuest::setRupeeCurrent(atUint16 val) { m_rupeeCurrent = val; }
{
m_rupeeCurrent = val;
}
atUint16 ALTTPQuest::rupeeCurrent() const atUint16 ALTTPQuest::rupeeCurrent() const { return m_rupeeCurrent; }
{
return m_rupeeCurrent;
}
void ALTTPQuest::setCompasses(ALTTPDungeonItemFlags flags) void ALTTPQuest::setCompasses(ALTTPDungeonItemFlags flags) { m_compasses = flags; }
{
m_compasses = flags;
}
ALTTPDungeonItemFlags ALTTPQuest::compasses() const ALTTPDungeonItemFlags ALTTPQuest::compasses() const { return m_compasses; }
{
return m_compasses;
}
void ALTTPQuest::setBigKeys(ALTTPDungeonItemFlags flags) void ALTTPQuest::setBigKeys(ALTTPDungeonItemFlags flags) { m_bigKeys = flags; }
{
m_bigKeys = flags;
}
ALTTPDungeonItemFlags ALTTPQuest::bigKeys() const ALTTPDungeonItemFlags ALTTPQuest::bigKeys() const { return m_bigKeys; }
{
return m_bigKeys;
}
void ALTTPQuest::setDungeonMaps(ALTTPDungeonItemFlags flags) void ALTTPQuest::setDungeonMaps(ALTTPDungeonItemFlags flags) { m_dungeonMaps = flags; }
{
m_dungeonMaps = flags;
}
ALTTPDungeonItemFlags ALTTPQuest::dungeonMaps() const ALTTPDungeonItemFlags ALTTPQuest::dungeonMaps() const { return m_dungeonMaps; }
{
return m_dungeonMaps;
}
void ALTTPQuest::setWishingPond(atUint16 val) void ALTTPQuest::setWishingPond(atUint16 val) { m_wishingPond = val; }
{
m_wishingPond = val;
}
atUint16 ALTTPQuest::wishingPond() const atUint16 ALTTPQuest::wishingPond() const { return m_wishingPond; }
{
return m_wishingPond;
}
void ALTTPQuest::setHealthMax(atUint8 val) void ALTTPQuest::setHealthMax(atUint8 val) { m_healthMax = val; }
{
m_healthMax = val;
}
atUint8 ALTTPQuest::healthMax() const atUint8 ALTTPQuest::healthMax() const { return m_healthMax; }
{
return m_healthMax;
}
void ALTTPQuest::setHealth(atUint8 val) void ALTTPQuest::setHealth(atUint8 val) { m_health = val; }
{
m_health = val;
}
atUint8 ALTTPQuest::health() const atUint8 ALTTPQuest::health() const { return m_health; }
{
return m_health;
}
void ALTTPQuest::setMagicPower(atUint8 val) void ALTTPQuest::setMagicPower(atUint8 val) { m_magicPower = val; }
{
m_magicPower = val;
}
atUint8 ALTTPQuest::magicPower() const atUint8 ALTTPQuest::magicPower() const { return m_magicPower; }
{
return m_magicPower;
}
void ALTTPQuest::setKeys(atUint8 val) void ALTTPQuest::setKeys(atUint8 val) { m_keys = val; }
{
m_keys = val;
}
atUint8 ALTTPQuest::keys() const atUint8 ALTTPQuest::keys() const { return m_keys; }
{
return m_keys;
}
void ALTTPQuest::setBombUpgrades(atUint8 val) void ALTTPQuest::setBombUpgrades(atUint8 val) { m_bombUpgrades = val; }
{
m_bombUpgrades = val;
}
atUint8 ALTTPQuest::bombUpgrades() const atUint8 ALTTPQuest::bombUpgrades() const { return m_bombUpgrades; }
{
return m_bombUpgrades;
}
void ALTTPQuest::setArrowUpgrades(atUint8 val) void ALTTPQuest::setArrowUpgrades(atUint8 val) { m_arrowUpgrades = val; }
{
m_arrowUpgrades = val;
}
atUint8 ALTTPQuest::arrowUpgrades() const atUint8 ALTTPQuest::arrowUpgrades() const { return m_arrowUpgrades; }
{
return m_arrowUpgrades;
}
void ALTTPQuest::setHealthFiller(atUint8 val) void ALTTPQuest::setHealthFiller(atUint8 val) { m_heartFiller = val; }
{
m_heartFiller = val;
}
atUint8 ALTTPQuest::healthFiller() const atUint8 ALTTPQuest::healthFiller() const { return m_heartFiller; }
{ void ALTTPQuest::setMagicFiller(atUint8 val) { m_heartFiller = val; }
return m_heartFiller;
}
void ALTTPQuest::setMagicFiller(atUint8 val)
{
m_heartFiller = val;
}
atUint8 ALTTPQuest::magicFiller() const atUint8 ALTTPQuest::magicFiller() const { return m_heartFiller; }
{
return m_heartFiller;
}
void ALTTPQuest::setPendants(ALTTPPendants val) void ALTTPQuest::setPendants(ALTTPPendants val) { m_pendants = val; }
{
m_pendants = val;
}
ALTTPPendants ALTTPQuest::pendants() const ALTTPPendants ALTTPQuest::pendants() const { return m_pendants; }
{
return m_pendants;
}
void ALTTPQuest::setBombFiller(atUint8 val) void ALTTPQuest::setBombFiller(atUint8 val) { m_bombFiller = val; }
{
m_bombFiller = val;
}
atUint8 ALTTPQuest::bombFiller() const atUint8 ALTTPQuest::bombFiller() const { return m_bombFiller; }
{
return m_bombFiller;
}
void ALTTPQuest::setArrowFiller(atUint8 val) void ALTTPQuest::setArrowFiller(atUint8 val) { m_arrowFiller = val; }
{
m_arrowFiller = val;
}
atUint8 ALTTPQuest::arrowFiller() const atUint8 ALTTPQuest::arrowFiller() const { return m_arrowFiller; }
{ void ALTTPQuest::setArrows(atUint8 val) { m_arrows = val; }
return m_arrowFiller;
}
void ALTTPQuest::setArrows(atUint8 val)
{
m_arrows = val;
}
atUint8 ALTTPQuest::arrows() const atUint8 ALTTPQuest::arrows() const { return m_arrows; }
{
return m_arrows;
}
void ALTTPQuest::setAbilityFlags(ALTTPAbilities val) void ALTTPQuest::setAbilityFlags(ALTTPAbilities val) { m_abilityFlags = val; }
{
m_abilityFlags = val;
}
ALTTPAbilities ALTTPQuest::abilityFlags() const ALTTPAbilities ALTTPQuest::abilityFlags() const { return m_abilityFlags; }
{
return m_abilityFlags;
}
void ALTTPQuest::setCrystals(ALTTPCrystals val) void ALTTPQuest::setCrystals(ALTTPCrystals val) { m_crystals = val; }
{
m_crystals = val;
}
ALTTPCrystals ALTTPQuest::crystals() const ALTTPCrystals ALTTPQuest::crystals() const { return m_crystals; }
{
return m_crystals;
}
void ALTTPQuest::setMagicUsage(ALTTPMagicUsage val) void ALTTPQuest::setMagicUsage(ALTTPMagicUsage val) { m_magicUsage = val; }
{
m_magicUsage = val;
}
ALTTPMagicUsage ALTTPQuest::magicUsage() const ALTTPMagicUsage ALTTPQuest::magicUsage() const { return m_magicUsage; }
{
return m_magicUsage;
}
void ALTTPQuest::setDungeonKeys(std::vector<atUint8> val) void ALTTPQuest::setDungeonKeys(std::vector<atUint8> val) { m_dungeonKeys = val; }
{
m_dungeonKeys = val;
}
void ALTTPQuest::setDungeonKeys(atUint32 id, atUint8 val) void ALTTPQuest::setDungeonKeys(atUint32 id, atUint8 val) {
{ if (id > m_dungeonKeys.size() - 1) {
if (id > m_dungeonKeys.size() - 1)
{
atWarning("index out of range"); atWarning("index out of range");
return; return;
} }
@ -297,10 +133,8 @@ void ALTTPQuest::setDungeonKeys(atUint32 id, atUint8 val)
m_dungeonKeys[id] = val; m_dungeonKeys[id] = val;
} }
atUint8 ALTTPQuest::dungeonKeys(atUint32 id) const atUint8 ALTTPQuest::dungeonKeys(atUint32 id) const {
{ if (id > m_dungeonKeys.size() - 1) {
if (id > m_dungeonKeys.size() - 1)
{
atWarning("index out of range"); atWarning("index out of range");
return 0; return 0;
} }
@ -308,91 +142,40 @@ atUint8 ALTTPQuest::dungeonKeys(atUint32 id) const
return m_dungeonKeys[id]; return m_dungeonKeys[id];
} }
atUint32 ALTTPQuest::dungeonCount() const atUint32 ALTTPQuest::dungeonCount() const { return (atUint32)m_dungeonKeys.size(); }
{
return (atUint32)m_dungeonKeys.size();
}
void ALTTPQuest::setProgressIndicator(ALTTPProgressIndicator val) { m_progressIndicator = val; }
void ALTTPQuest::setProgressIndicator(ALTTPProgressIndicator val) ALTTPProgressIndicator ALTTPQuest::progressIndicator() const { return m_progressIndicator; }
{
m_progressIndicator = val;
}
ALTTPProgressIndicator ALTTPQuest::progressIndicator() const void ALTTPQuest::setProgressFlags1(ALTTPProgressFlags1 val) { m_progressFlags1 = val; }
{
return m_progressIndicator;
}
void ALTTPQuest::setProgressFlags1(ALTTPProgressFlags1 val) ALTTPProgressFlags1 ALTTPQuest::progressFlags1() const { return m_progressFlags1; }
{
m_progressFlags1 = val;
}
ALTTPProgressFlags1 ALTTPQuest::progressFlags1() const void ALTTPQuest::setMapIcon(ALTTPMapIcon val) { m_mapIcon = val; }
{
return m_progressFlags1;
}
void ALTTPQuest::setMapIcon(ALTTPMapIcon val) ALTTPMapIcon ALTTPQuest::mapIcon() const { return m_mapIcon; }
{
m_mapIcon = val;
}
ALTTPMapIcon ALTTPQuest::mapIcon() const void ALTTPQuest::setStartLocation(ALTTPStartLocation val) { m_startLocation = val; }
{
return m_mapIcon;
}
void ALTTPQuest::setStartLocation(ALTTPStartLocation val) ALTTPStartLocation ALTTPQuest::startLocation() const { return m_startLocation; }
{
m_startLocation = val;
}
ALTTPStartLocation ALTTPQuest::startLocation() const void ALTTPQuest::setProgressFlags2(ALTTPProgressFlags2 val) { m_progressFlags2 = val; }
{
return m_startLocation;
}
void ALTTPQuest::setProgressFlags2(ALTTPProgressFlags2 val) ALTTPProgressFlags2 ALTTPQuest::progressFlags2() const { return m_progressFlags2; }
{
m_progressFlags2 = val;
}
ALTTPProgressFlags2 ALTTPQuest::progressFlags2() const void ALTTPQuest::setLightDarkWorldIndicator(ALTTPLightDarkWorldIndicator val) { m_lightDarkWorldIndicator = val; }
{
return m_progressFlags2;
}
void ALTTPQuest::setLightDarkWorldIndicator(ALTTPLightDarkWorldIndicator val) ALTTPLightDarkWorldIndicator ALTTPQuest::lightDarkWorldIndicator() const { return m_lightDarkWorldIndicator; }
{
m_lightDarkWorldIndicator = val;
}
ALTTPLightDarkWorldIndicator ALTTPQuest::lightDarkWorldIndicator() const void ALTTPQuest::setTagAlong(ALTTPTagAlong val) { m_tagAlong = val; }
{
return m_lightDarkWorldIndicator;
}
void ALTTPQuest::setTagAlong(ALTTPTagAlong val) ALTTPTagAlong ALTTPQuest::tagAlong() const { return m_tagAlong; }
{
m_tagAlong = val;
}
ALTTPTagAlong ALTTPQuest::tagAlong() const void ALTTPQuest::setOldManFlags(std::vector<atUint8> flags) { m_oldManFlags = flags; }
{
return m_tagAlong;
}
void ALTTPQuest::setOldManFlags(std::vector<atUint8> flags) void ALTTPQuest::setOldManFlag(atUint32 id, atUint8 val) {
{ if (id > m_oldManFlags.size() - 1) {
m_oldManFlags = flags;
}
void ALTTPQuest::setOldManFlag(atUint32 id, atUint8 val)
{
if (id > m_oldManFlags.size() - 1)
{
atWarning("index out of range"); atWarning("index out of range");
return; return;
} }
@ -400,40 +183,24 @@ void ALTTPQuest::setOldManFlag(atUint32 id, atUint8 val)
m_oldManFlags[id] = val; m_oldManFlags[id] = val;
} }
atUint8 ALTTPQuest::oldManFlag(atUint32 id) atUint8 ALTTPQuest::oldManFlag(atUint32 id) {
{ if (id > m_oldManFlags.size() - 1) {
if (id > m_oldManFlags.size() - 1)
{
atWarning("index out of range"); atWarning("index out of range");
return 0; return 0;
} }
return m_oldManFlags[id]; return m_oldManFlags[id];
} }
atUint32 ALTTPQuest::oldManFlagCount() const atUint32 ALTTPQuest::oldManFlagCount() const { return (atUint32)m_oldManFlags.size(); }
{
return (atUint32)m_oldManFlags.size();
}
void ALTTPQuest::setBombFlag(atUint8 flag) void ALTTPQuest::setBombFlag(atUint8 flag) { m_bombFlag = flag; }
{
m_bombFlag = flag;
}
atUint8 ALTTPQuest::bombFlag() const atUint8 ALTTPQuest::bombFlag() const { return m_bombFlag; }
{
return m_bombFlag;
}
void ALTTPQuest::setUnknown1(std::vector<atUint8> flags) void ALTTPQuest::setUnknown1(std::vector<atUint8> flags) { m_unknown1 = flags; }
{
m_unknown1 = flags;
}
void ALTTPQuest::setUnknown1(atUint32 id, atUint8 val) void ALTTPQuest::setUnknown1(atUint32 id, atUint8 val) {
{ if (id > m_unknown1.size()) {
if (id > m_unknown1.size())
{
atWarning("index out of range"); atWarning("index out of range");
return; return;
} }
@ -441,10 +208,8 @@ void ALTTPQuest::setUnknown1(atUint32 id, atUint8 val)
m_unknown1[id] = val; m_unknown1[id] = val;
} }
atUint8 ALTTPQuest::unknown1(atUint32 id) atUint8 ALTTPQuest::unknown1(atUint32 id) {
{ if (id > m_unknown1.size()) {
if (id > m_unknown1.size())
{
atWarning("index out of range"); atWarning("index out of range");
return 0; return 0;
} }
@ -452,67 +217,51 @@ atUint8 ALTTPQuest::unknown1(atUint32 id)
return m_unknown1[id]; return m_unknown1[id];
} }
atUint32 ALTTPQuest::unknown1Count() const atUint32 ALTTPQuest::unknown1Count() const { return (atUint32)m_unknown1.size(); }
{
return (atUint32)m_unknown1.size();
}
void ALTTPQuest::setPlayerName(std::vector<atUint16> playerName) void ALTTPQuest::setPlayerName(std::vector<atUint16> playerName) { m_playerName = playerName; }
{
m_playerName = playerName;
}
void ALTTPQuest::setPlayerName(const std::string& playerName) void ALTTPQuest::setPlayerName(const std::string& playerName) {
{ if (playerName == std::string() || playerName.size() > 6) {
if (playerName == std::string() || playerName.size() > 6)
{
atWarning("index out of range"); atWarning("index out of range");
return; return;
} }
m_playerName.clear(); m_playerName.clear();
for (atUint32 i = 0; i < 6; i++) for (atUint32 i = 0; i < 6; i++) {
{ if (i > playerName.size() - 1) {
if (i > playerName.size() - 1)
{
m_playerName.push_back((atUint16)0xA9); m_playerName.push_back((atUint16)0xA9);
continue; continue;
} }
char c = playerName[i]; char c = playerName[i];
if (c >= 'A' && c <= 'P' && c != 'I') if (c >= 'A' && c <= 'P' && c != 'I') {
{
m_playerName.push_back((atUint16)(c - 'A')); m_playerName.push_back((atUint16)(c - 'A'));
continue; continue;
} }
if (c >= 'Q' && c <= 'Z') if (c >= 'Q' && c <= 'Z') {
{
std::cout << std::hex << (atUint16)((c - 'Q') + 0x20) << std::endl; std::cout << std::hex << (atUint16)((c - 'Q') + 0x20) << std::endl;
m_playerName.push_back((atUint16)((c - 'Q') + 0x20)); m_playerName.push_back((atUint16)((c - 'Q') + 0x20));
continue; continue;
} }
if (c >= 'a' && c <= 'f') if (c >= 'a' && c <= 'f') {
{
std::cout << std::hex << (atUint16)((c - 'a') + 0x2A) << std::endl; std::cout << std::hex << (atUint16)((c - 'a') + 0x2A) << std::endl;
m_playerName.push_back((atUint16)((c - 'a') + 0x2A)); m_playerName.push_back((atUint16)((c - 'a') + 0x2A));
continue; continue;
} }
if (c >= 'g' && c <= 'v') if (c >= 'g' && c <= 'v') {
{ if (c == 'k') {
if (c == 'k')
{
m_playerName.push_back(0x42); m_playerName.push_back(0x42);
continue; continue;
} }
if (c == 'i') if (c == 'i') {
{
m_playerName.push_back(0x44); m_playerName.push_back(0x44);
continue; continue;
} }
@ -521,92 +270,77 @@ void ALTTPQuest::setPlayerName(const std::string& playerName)
continue; continue;
} }
if (c >= 'w' && c <= 'z') if (c >= 'w' && c <= 'z') {
{
m_playerName.push_back((atUint16)((c - 'w') + 0x60)); m_playerName.push_back((atUint16)((c - 'w') + 0x60));
continue; continue;
} }
if (c >= '0' && c <= '9') if (c >= '0' && c <= '9') {
{
m_playerName.push_back((atUint16)((c - '0') + 0x64)); m_playerName.push_back((atUint16)((c - '0') + 0x64));
continue; continue;
} }
if (c == '-' || c == '.') if (c == '-' || c == '.') {
{
m_playerName.push_back((atUint16)(c - '-') + 0x80); m_playerName.push_back((atUint16)(c - '-') + 0x80);
continue; continue;
} }
switch (c) switch (c) {
{ case '?':
case '?' :
m_playerName.push_back(0x6E); m_playerName.push_back(0x6E);
break; break;
case '!' : case '!':
m_playerName.push_back(0x6F); m_playerName.push_back(0x6F);
break; break;
case ',' : case ',':
m_playerName.push_back(0x82); m_playerName.push_back(0x82);
break; break;
case '(' : case '(':
m_playerName.push_back(0x85); m_playerName.push_back(0x85);
break; break;
case ')' : case ')':
m_playerName.push_back(0x86); m_playerName.push_back(0x86);
break; break;
case 'I' : case 'I':
m_playerName.push_back(0xAF); m_playerName.push_back(0xAF);
break; break;
} }
} }
} }
std::vector<atUint16> ALTTPQuest::playerName() const std::vector<atUint16> ALTTPQuest::playerName() const { return m_playerName; }
{
return m_playerName;
}
std::string ALTTPQuest::playerNameToString() const std::string ALTTPQuest::playerNameToString() const {
{
std::string ret; std::string ret;
for (atInt16 c : m_playerName) for (atInt16 c : m_playerName) {
{ if (c >= 0x00 && c <= 0x0F) {
if (c >= 0x00 && c <= 0x0F)
{
ret.push_back((char)('A' + c)); ret.push_back((char)('A' + c));
continue; continue;
} }
if (c >= 0x20 && c <= 0x29) if (c >= 0x20 && c <= 0x29) {
{
ret.push_back((char)('Q' + (c - 0x20))); ret.push_back((char)('Q' + (c - 0x20)));
continue; continue;
} }
if (c >= 0x2A && c <= 0x2F) if (c >= 0x2A && c <= 0x2F) {
{
ret.push_back((char)('a' + (c - 0x2A))); ret.push_back((char)('a' + (c - 0x2A)));
continue; continue;
} }
if (c >= 0x40 && c <= 0x4F) if (c >= 0x40 && c <= 0x4F) {
{ if (c == 0x42) {
if (c == 0x42)
{
ret.push_back('k'); ret.push_back('k');
continue; continue;
} }
if (c == 0x44) if (c == 0x44) {
{
ret.push_back('i'); ret.push_back('i');
continue; continue;
} }
@ -614,26 +348,22 @@ std::string ALTTPQuest::playerNameToString() const
ret.push_back((char)('g' + (c - 0x40))); ret.push_back((char)('g' + (c - 0x40)));
} }
if (c >= 0x60 && c <= 0x63) if (c >= 0x60 && c <= 0x63) {
{
ret.push_back((char)('w' + (c - 0x60))); ret.push_back((char)('w' + (c - 0x60)));
continue; continue;
} }
if (c >= 0x64 && c <= 0x6D) if (c >= 0x64 && c <= 0x6D) {
{
ret.push_back((char)('0' + (c - 0x64))); ret.push_back((char)('0' + (c - 0x64)));
continue; continue;
} }
if (c == 0x80 || c == 0x81) if (c == 0x80 || c == 0x81) {
{
ret.push_back((char)('-' + (c - 0x80))); ret.push_back((char)('-' + (c - 0x80)));
continue; continue;
} }
switch (c) switch (c) {
{
case 0x6E: case 0x6E:
ret.push_back('?'); ret.push_back('?');
break; break;
@ -663,25 +393,14 @@ std::string ALTTPQuest::playerNameToString() const
return ret; return ret;
} }
void ALTTPQuest::setValid(bool val) void ALTTPQuest::setValid(bool val) { m_valid = val; }
{
m_valid = val;
}
bool ALTTPQuest::valid() bool ALTTPQuest::valid() { return m_valid; }
{
return m_valid;
}
void ALTTPQuest::setDungeonDeathTotals(std::vector<atUint16> val) void ALTTPQuest::setDungeonDeathTotals(std::vector<atUint16> val) { m_dungeonDeathTotals = val; }
{
m_dungeonDeathTotals = val;
}
void ALTTPQuest::setDungeonDeathTotal(atUint32 id, atUint16 val) void ALTTPQuest::setDungeonDeathTotal(atUint32 id, atUint16 val) {
{ if (id > m_dungeonDeathTotals.size()) {
if (id > m_dungeonDeathTotals.size())
{
atWarning("index out of range"); atWarning("index out of range");
return; return;
} }
@ -689,10 +408,8 @@ void ALTTPQuest::setDungeonDeathTotal(atUint32 id, atUint16 val)
m_dungeonDeathTotals[id] = val; m_dungeonDeathTotals[id] = val;
} }
atUint16 ALTTPQuest::dungeonDeathTotal(atUint32 id) const atUint16 ALTTPQuest::dungeonDeathTotal(atUint32 id) const {
{ if (id > m_dungeonDeathTotals.size()) {
if (id > m_dungeonDeathTotals.size())
{
atWarning("index out of range"); atWarning("index out of range");
return 0; return 0;
} }
@ -700,48 +417,21 @@ atUint16 ALTTPQuest::dungeonDeathTotal(atUint32 id) const
return m_dungeonDeathTotals[id]; return m_dungeonDeathTotals[id];
} }
atUint16 ALTTPQuest::dungeonDeathTotalCount() const atUint16 ALTTPQuest::dungeonDeathTotalCount() const { return (atUint16)m_dungeonDeathTotals.size(); }
{
return (atUint16)m_dungeonDeathTotals.size();
}
void ALTTPQuest::setUnknown2(atUint16 val) void ALTTPQuest::setUnknown2(atUint16 val) { m_unknown2 = val; }
{
m_unknown2 = val;
}
atUint16 ALTTPQuest::unknown2() const atUint16 ALTTPQuest::unknown2() const { return m_unknown2; }
{
return m_unknown2;
}
void ALTTPQuest::setDeathSaveCount(atUint16 val) void ALTTPQuest::setDeathSaveCount(atUint16 val) { m_deathSaveCount = val; }
{ atUint16 ALTTPQuest::deathSaveCount() const { return m_deathSaveCount; }
m_deathSaveCount = val;
}
atUint16 ALTTPQuest::deathSaveCount() const
{
return m_deathSaveCount;
}
void ALTTPQuest::setPostGameDeathCounter(atInt16 val) void ALTTPQuest::setPostGameDeathCounter(atInt16 val) { m_postGameDeathCounter = val; }
{
m_postGameDeathCounter = val;
}
atInt16 ALTTPQuest::postGameDeathCounter() const atInt16 ALTTPQuest::postGameDeathCounter() const { return m_postGameDeathCounter; }
{
return m_postGameDeathCounter;
}
void ALTTPQuest::setChecksum(atUint16 checksum) void ALTTPQuest::setChecksum(atUint16 checksum) { m_checksum = checksum; }
{
m_checksum = checksum;
}
atUint16 ALTTPQuest::checksum() const atUint16 ALTTPQuest::checksum() const { return m_checksum; }
{
return m_checksum;
}
} // zelda } // namespace athena

View File

@ -3,76 +3,61 @@
#include <iostream> #include <iostream>
#include <iomanip> #include <iomanip>
namespace athena::checksums namespace athena::checksums {
{ atUint64 crc64(const atUint8* data, atUint64 length, atUint64 seed, atUint64 final) {
atUint64 crc64(const atUint8* data, atUint64 length, atUint64 seed, atUint64 final) static const atUint64 crc64Table[256] = {
{ 0x0000000000000000, 0x42F0E1EBA9EA3693, 0x85E1C3D753D46D26, 0xC711223CFA3E5BB5, 0x493366450E42ECDF,
static const atUint64 crc64Table[256] = 0x0BC387AEA7A8DA4C, 0xCCD2A5925D9681F9, 0x8E224479F47CB76A, 0x9266CC8A1C85D9BE, 0xD0962D61B56FEF2D,
{ 0x17870F5D4F51B498, 0x5577EEB6E6BB820B, 0xDB55AACF12C73561, 0x99A54B24BB2D03F2, 0x5EB4691841135847,
0x0000000000000000, 0x42F0E1EBA9EA3693, 0x85E1C3D753D46D26, 0xC711223CFA3E5BB5, 0x1C4488F3E8F96ED4, 0x663D78FF90E185EF, 0x24CD9914390BB37C, 0xE3DCBB28C335E8C9, 0xA12C5AC36ADFDE5A,
0x493366450E42ECDF, 0x0BC387AEA7A8DA4C, 0xCCD2A5925D9681F9, 0x8E224479F47CB76A, 0x2F0E1EBA9EA36930, 0x6DFEFF5137495FA3, 0xAAEFDD6DCD770416, 0xE81F3C86649D3285, 0xF45BB4758C645C51,
0x9266CC8A1C85D9BE, 0xD0962D61B56FEF2D, 0x17870F5D4F51B498, 0x5577EEB6E6BB820B, 0xB6AB559E258E6AC2, 0x71BA77A2DFB03177, 0x334A9649765A07E4, 0xBD68D2308226B08E, 0xFF9833DB2BCC861D,
0xDB55AACF12C73561, 0x99A54B24BB2D03F2, 0x5EB4691841135847, 0x1C4488F3E8F96ED4, 0x388911E7D1F2DDA8, 0x7A79F00C7818EB3B, 0xCC7AF1FF21C30BDE, 0x8E8A101488293D4D, 0x499B3228721766F8,
0x663D78FF90E185EF, 0x24CD9914390BB37C, 0xE3DCBB28C335E8C9, 0xA12C5AC36ADFDE5A, 0x0B6BD3C3DBFD506B, 0x854997BA2F81E701, 0xC7B97651866BD192, 0x00A8546D7C558A27, 0x4258B586D5BFBCB4,
0x2F0E1EBA9EA36930, 0x6DFEFF5137495FA3, 0xAAEFDD6DCD770416, 0xE81F3C86649D3285, 0x5E1C3D753D46D260, 0x1CECDC9E94ACE4F3, 0xDBFDFEA26E92BF46, 0x990D1F49C77889D5, 0x172F5B3033043EBF,
0xF45BB4758C645C51, 0xB6AB559E258E6AC2, 0x71BA77A2DFB03177, 0x334A9649765A07E4, 0x55DFBADB9AEE082C, 0x92CE98E760D05399, 0xD03E790CC93A650A, 0xAA478900B1228E31, 0xE8B768EB18C8B8A2,
0xBD68D2308226B08E, 0xFF9833DB2BCC861D, 0x388911E7D1F2DDA8, 0x7A79F00C7818EB3B, 0x2FA64AD7E2F6E317, 0x6D56AB3C4B1CD584, 0xE374EF45BF6062EE, 0xA1840EAE168A547D, 0x66952C92ECB40FC8,
0xCC7AF1FF21C30BDE, 0x8E8A101488293D4D, 0x499B3228721766F8, 0x0B6BD3C3DBFD506B, 0x2465CD79455E395B, 0x3821458AADA7578F, 0x7AD1A461044D611C, 0xBDC0865DFE733AA9, 0xFF3067B657990C3A,
0x854997BA2F81E701, 0xC7B97651866BD192, 0x00A8546D7C558A27, 0x4258B586D5BFBCB4, 0x711223CFA3E5BB50, 0x33E2C2240A0F8DC3, 0xF4F3E018F031D676, 0xB60301F359DBE0E5, 0xDA050215EA6C212F,
0x5E1C3D753D46D260, 0x1CECDC9E94ACE4F3, 0xDBFDFEA26E92BF46, 0x990D1F49C77889D5, 0x98F5E3FE438617BC, 0x5FE4C1C2B9B84C09, 0x1D14202910527A9A, 0x93366450E42ECDF0, 0xD1C685BB4DC4FB63,
0x172F5B3033043EBF, 0x55DFBADB9AEE082C, 0x92CE98E760D05399, 0xD03E790CC93A650A, 0x16D7A787B7FAA0D6, 0x5427466C1E109645, 0x4863CE9FF6E9F891, 0x0A932F745F03CE02, 0xCD820D48A53D95B7,
0xAA478900B1228E31, 0xE8B768EB18C8B8A2, 0x2FA64AD7E2F6E317, 0x6D56AB3C4B1CD584, 0x8F72ECA30CD7A324, 0x0150A8DAF8AB144E, 0x43A04931514122DD, 0x84B16B0DAB7F7968, 0xC6418AE602954FFB,
0xE374EF45BF6062EE, 0xA1840EAE168A547D, 0x66952C92ECB40FC8, 0x2465CD79455E395B, 0xBC387AEA7A8DA4C0, 0xFEC89B01D3679253, 0x39D9B93D2959C9E6, 0x7B2958D680B3FF75, 0xF50B1CAF74CF481F,
0x3821458AADA7578F, 0x7AD1A461044D611C, 0xBDC0865DFE733AA9, 0xFF3067B657990C3A, 0xB7FBFD44DD257E8C, 0x70EADF78271B2539, 0x321A3E938EF113AA, 0x2E5EB66066087D7E, 0x6CAE578BCFE24BED,
0x711223CFA3E5BB50, 0x33E2C2240A0F8DC3, 0xF4F3E018F031D676, 0xB60301F359DBE0E5, 0xABBF75B735DC1058, 0xE94F945C9C3626CB, 0x676DD025684A91A1, 0x259D31CEC1A0A732, 0xE28C13F23B9EFC87,
0xDA050215EA6C212F, 0x98F5E3FE438617BC, 0x5FE4C1C2B9B84C09, 0x1D14202910527A9A, 0xA07CF2199274CA14, 0x167FF3EACBAF2AF1, 0x548F120162451C62, 0x939E303D987B47D7, 0xD16ED1D631917144,
0x93366450E42ECDF0, 0xD1C685BB4DC4FB63, 0x16D7A787B7FAA0D6, 0x5427466C1E109645, 0x5F4C95AFC5EDC62E, 0x1DBC74446C07F0BD, 0xDAAD56789639AB08, 0x985DB7933FD39D9B, 0x84193F60D72AF34F,
0x4863CE9FF6E9F891, 0x0A932F745F03CE02, 0xCD820D48A53D95B7, 0x8F72ECA30CD7A324, 0xC6E9DE8B7EC0C5DC, 0x01F8FCB784FE9E69, 0x43081D5C2D14A8FA, 0xCD2A5925D9681F90, 0x8FDAB8CE70822903,
0x0150A8DAF8AB144E, 0x43A04931514122DD, 0x84B16B0DAB7F7968, 0xC6418AE602954FFB, 0x48CB9AF28ABC72B6, 0x0A3B7B1923564425, 0x70428B155B4EAF1E, 0x32B26AFEF2A4998D, 0xF5A348C2089AC238,
0xBC387AEA7A8DA4C0, 0xFEC89B01D3679253, 0x39D9B93D2959C9E6, 0x7B2958D680B3FF75, 0xB753A929A170F4AB, 0x3971ED50550C43C1, 0x7B810CBBFCE67552, 0xBC902E8706D82EE7, 0xFE60CF6CAF321874,
0xF50B1CAF74CF481F, 0xB7FBFD44DD257E8C, 0x70EADF78271B2539, 0x321A3E938EF113AA, 0xE224479F47CB76A0, 0xA0D4A674EE214033, 0x67C58448141F1B86, 0x253565A3BDF52D15, 0xAB1721DA49899A7F,
0x2E5EB66066087D7E, 0x6CAE578BCFE24BED, 0xABBF75B735DC1058, 0xE94F945C9C3626CB, 0xE9E7C031E063ACEC, 0x2EF6E20D1A5DF759, 0x6C0603E6B3B7C1CA, 0xF6FAE5C07D3274CD, 0xB40A042BD4D8425E,
0x676DD025684A91A1, 0x259D31CEC1A0A732, 0xE28C13F23B9EFC87, 0xA07CF2199274CA14, 0x731B26172EE619EB, 0x31EBC7FC870C2F78, 0xBFC9838573709812, 0xFD39626EDA9AAE81, 0x3A28405220A4F534,
0x167FF3EACBAF2AF1, 0x548F120162451C62, 0x939E303D987B47D7, 0xD16ED1D631917144, 0x78D8A1B9894EC3A7, 0x649C294A61B7AD73, 0x266CC8A1C85D9BE0, 0xE17DEA9D3263C055, 0xA38D0B769B89F6C6,
0x5F4C95AFC5EDC62E, 0x1DBC74446C07F0BD, 0xDAAD56789639AB08, 0x985DB7933FD39D9B, 0x2DAF4F0F6FF541AC, 0x6F5FAEE4C61F773F, 0xA84E8CD83C212C8A, 0xEABE6D3395CB1A19, 0x90C79D3FEDD3F122,
0x84193F60D72AF34F, 0xC6E9DE8B7EC0C5DC, 0x01F8FCB784FE9E69, 0x43081D5C2D14A8FA, 0xD2377CD44439C7B1, 0x15265EE8BE079C04, 0x57D6BF0317EDAA97, 0xD9F4FB7AE3911DFD, 0x9B041A914A7B2B6E,
0xCD2A5925D9681F90, 0x8FDAB8CE70822903, 0x48CB9AF28ABC72B6, 0x0A3B7B1923564425, 0x5C1538ADB04570DB, 0x1EE5D94619AF4648, 0x02A151B5F156289C, 0x4051B05E58BC1E0F, 0x87409262A28245BA,
0x70428B155B4EAF1E, 0x32B26AFEF2A4998D, 0xF5A348C2089AC238, 0xB753A929A170F4AB, 0xC5B073890B687329, 0x4B9237F0FF14C443, 0x0962D61B56FEF2D0, 0xCE73F427ACC0A965, 0x8C8315CC052A9FF6,
0x3971ED50550C43C1, 0x7B810CBBFCE67552, 0xBC902E8706D82EE7, 0xFE60CF6CAF321874, 0x3A80143F5CF17F13, 0x7870F5D4F51B4980, 0xBF61D7E80F251235, 0xFD913603A6CF24A6, 0x73B3727A52B393CC,
0xE224479F47CB76A0, 0xA0D4A674EE214033, 0x67C58448141F1B86, 0x253565A3BDF52D15, 0x31439391FB59A55F, 0xF652B1AD0167FEEA, 0xB4A25046A88DC879, 0xA8E6D8B54074A6AD, 0xEA16395EE99E903E,
0xAB1721DA49899A7F, 0xE9E7C031E063ACEC, 0x2EF6E20D1A5DF759, 0x6C0603E6B3B7C1CA, 0x2D071B6213A0CB8B, 0x6FF7FA89BA4AFD18, 0xE1D5BEF04E364A72, 0xA3255F1BE7DC7CE1, 0x64347D271DE22754,
0xF6FAE5C07D3274CD, 0xB40A042BD4D8425E, 0x731B26172EE619EB, 0x31EBC7FC870C2F78, 0x26C49CCCB40811C7, 0x5CBD6CC0CC10FAFC, 0x1E4D8D2B65FACC6F, 0xD95CAF179FC497DA, 0x9BAC4EFC362EA149,
0xBFC9838573709812, 0xFD39626EDA9AAE81, 0x3A28405220A4F534, 0x78D8A1B9894EC3A7, 0x158E0A85C2521623, 0x577EEB6E6BB820B0, 0x906FC95291867B05, 0xD29F28B9386C4D96, 0xCEDBA04AD0952342,
0x649C294A61B7AD73, 0x266CC8A1C85D9BE0, 0xE17DEA9D3263C055, 0xA38D0B769B89F6C6, 0x8C2B41A1797F15D1, 0x4B3A639D83414E64, 0x09CA82762AAB78F7, 0x87E8C60FDED7CF9D, 0xC51827E4773DF90E,
0x2DAF4F0F6FF541AC, 0x6F5FAEE4C61F773F, 0xA84E8CD83C212C8A, 0xEABE6D3395CB1A19, 0x020905D88D03A2BB, 0x40F9E43324E99428, 0x2CFFE7D5975E55E2, 0x6E0F063E3EB46371, 0xA91E2402C48A38C4,
0x90C79D3FEDD3F122, 0xD2377CD44439C7B1, 0x15265EE8BE079C04, 0x57D6BF0317EDAA97, 0xEBEEC5E96D600E57, 0x65CC8190991CB93D, 0x273C607B30F68FAE, 0xE02D4247CAC8D41B, 0xA2DDA3AC6322E288,
0xD9F4FB7AE3911DFD, 0x9B041A914A7B2B6E, 0x5C1538ADB04570DB, 0x1EE5D94619AF4648, 0xBE992B5F8BDB8C5C, 0xFC69CAB42231BACF, 0x3B78E888D80FE17A, 0x7988096371E5D7E9, 0xF7AA4D1A85996083,
0x02A151B5F156289C, 0x4051B05E58BC1E0F, 0x87409262A28245BA, 0xC5B073890B687329, 0xB55AACF12C735610, 0x724B8ECDD64D0DA5, 0x30BB6F267FA73B36, 0x4AC29F2A07BFD00D, 0x08327EC1AE55E69E,
0x4B9237F0FF14C443, 0x0962D61B56FEF2D0, 0xCE73F427ACC0A965, 0x8C8315CC052A9FF6, 0xCF235CFD546BBD2B, 0x8DD3BD16FD818BB8, 0x03F1F96F09FD3CD2, 0x41011884A0170A41, 0x86103AB85A2951F4,
0x3A80143F5CF17F13, 0x7870F5D4F51B4980, 0xBF61D7E80F251235, 0xFD913603A6CF24A6, 0xC4E0DB53F3C36767, 0xD8A453A01B3A09B3, 0x9A54B24BB2D03F20, 0x5D45907748EE6495, 0x1FB5719CE1045206,
0x73B3727A52B393CC, 0x31439391FB59A55F, 0xF652B1AD0167FEEA, 0xB4A25046A88DC879, 0x919735E51578E56C, 0xD367D40EBC92D3FF, 0x1476F63246AC884A, 0x568617D9EF46BED9, 0xE085162AB69D5E3C,
0xA8E6D8B54074A6AD, 0xEA16395EE99E903E, 0x2D071B6213A0CB8B, 0x6FF7FA89BA4AFD18, 0xA275F7C11F7768AF, 0x6564D5FDE549331A, 0x279434164CA30589, 0xA9B6706FB8DFB2E3, 0xEB46918411358470,
0xE1D5BEF04E364A72, 0xA3255F1BE7DC7CE1, 0x64347D271DE22754, 0x26C49CCCB40811C7, 0x2C57B3B8EB0BDFC5, 0x6EA7525342E1E956, 0x72E3DAA0AA188782, 0x30133B4B03F2B111, 0xF7021977F9CCEAA4,
0x5CBD6CC0CC10FAFC, 0x1E4D8D2B65FACC6F, 0xD95CAF179FC497DA, 0x9BAC4EFC362EA149, 0xB5F2F89C5026DC37, 0x3BD0BCE5A45A6B5D, 0x79205D0E0DB05DCE, 0xBE317F32F78E067B, 0xFCC19ED95E6430E8,
0x158E0A85C2521623, 0x577EEB6E6BB820B0, 0x906FC95291867B05, 0xD29F28B9386C4D96, 0x86B86ED5267CDBD3, 0xC4488F3E8F96ED40, 0x0359AD0275A8B6F5, 0x41A94CE9DC428066, 0xCF8B0890283E370C,
0xCEDBA04AD0952342, 0x8C2B41A1797F15D1, 0x4B3A639D83414E64, 0x09CA82762AAB78F7, 0x8D7BE97B81D4019F, 0x4A6ACB477BEA5A2A, 0x089A2AACD2006CB9, 0x14DEA25F3AF9026D, 0x562E43B4931334FE,
0x87E8C60FDED7CF9D, 0xC51827E4773DF90E, 0x020905D88D03A2BB, 0x40F9E43324E99428, 0x913F6188692D6F4B, 0xD3CF8063C0C759D8, 0x5DEDC41A34BBEEB2, 0x1F1D25F19D51D821, 0xD80C07CD676F8394,
0x2CFFE7D5975E55E2, 0x6E0F063E3EB46371, 0xA91E2402C48A38C4, 0xEBEEC5E96D600E57, 0x9AFCE626CE85B507,
0x65CC8190991CB93D, 0x273C607B30F68FAE, 0xE02D4247CAC8D41B, 0xA2DDA3AC6322E288,
0xBE992B5F8BDB8C5C, 0xFC69CAB42231BACF, 0x3B78E888D80FE17A, 0x7988096371E5D7E9,
0xF7AA4D1A85996083, 0xB55AACF12C735610, 0x724B8ECDD64D0DA5, 0x30BB6F267FA73B36,
0x4AC29F2A07BFD00D, 0x08327EC1AE55E69E, 0xCF235CFD546BBD2B, 0x8DD3BD16FD818BB8,
0x03F1F96F09FD3CD2, 0x41011884A0170A41, 0x86103AB85A2951F4, 0xC4E0DB53F3C36767,
0xD8A453A01B3A09B3, 0x9A54B24BB2D03F20, 0x5D45907748EE6495, 0x1FB5719CE1045206,
0x919735E51578E56C, 0xD367D40EBC92D3FF, 0x1476F63246AC884A, 0x568617D9EF46BED9,
0xE085162AB69D5E3C, 0xA275F7C11F7768AF, 0x6564D5FDE549331A, 0x279434164CA30589,
0xA9B6706FB8DFB2E3, 0xEB46918411358470, 0x2C57B3B8EB0BDFC5, 0x6EA7525342E1E956,
0x72E3DAA0AA188782, 0x30133B4B03F2B111, 0xF7021977F9CCEAA4, 0xB5F2F89C5026DC37,
0x3BD0BCE5A45A6B5D, 0x79205D0E0DB05DCE, 0xBE317F32F78E067B, 0xFCC19ED95E6430E8,
0x86B86ED5267CDBD3, 0xC4488F3E8F96ED40, 0x0359AD0275A8B6F5, 0x41A94CE9DC428066,
0xCF8B0890283E370C, 0x8D7BE97B81D4019F, 0x4A6ACB477BEA5A2A, 0x089A2AACD2006CB9,
0x14DEA25F3AF9026D, 0x562E43B4931334FE, 0x913F6188692D6F4B, 0xD3CF8063C0C759D8,
0x5DEDC41A34BBEEB2, 0x1F1D25F19D51D821, 0xD80C07CD676F8394, 0x9AFCE626CE85B507,
}; };
if (!data) if (!data)
@ -87,43 +72,37 @@ atUint64 crc64(const atUint8* data, atUint64 length, atUint64 seed, atUint64 fin
return checksum ^ final; return checksum ^ final;
} }
atUint32 crc32(const atUint8* data, atUint64 length, atUint32 seed, atUint32 final) atUint32 crc32(const atUint8* data, atUint64 length, atUint32 seed, atUint32 final) {
{ static const atUint32 crc32Table[256] = {
static const atUint32 crc32Table[256] = 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832,
{ 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A,
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB,
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4,
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525,
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615,
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6,
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7,
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278,
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330,
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D};
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
};
if (!data) if (!data)
return seed; return seed;
@ -137,40 +116,27 @@ atUint32 crc32(const atUint8* data, atUint64 length, atUint32 seed, atUint32 fin
return checksum ^ final; return checksum ^ final;
} }
atUint16 crc16CCITT(const atUint8* data, atUint64 length, atUint16 seed, atUint16 final) atUint16 crc16CCITT(const atUint8* data, atUint64 length, atUint16 seed, atUint16 final) {
{ static const atUint16 crc16CCITTTable[256] = {
static const atUint16 crc16CCITTTable [256] = 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad,
{ 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a,
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b,
0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861,
0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96,
0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87,
0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a,
0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290,
0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e,
0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f,
0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c,
0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83,
0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0};
0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb,
0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0,
0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8,
0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657,
0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9,
0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882,
0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e,
0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07,
0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d,
0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74,
0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};
atUint16 checksum = seed; atUint16 checksum = seed;
int pos = 0; int pos = 0;
@ -181,46 +147,30 @@ atUint16 crc16CCITT(const atUint8* data, atUint64 length, atUint16 seed, atUint1
return checksum ^ final; return checksum ^ final;
} }
atUint16 crc16(const atUint8* data, atUint64 length, atUint16 seed, atUint64 final) atUint16 crc16(const atUint8* data, atUint64 length, atUint16 seed, atUint64 final) {
{
if (data) if (data)
return seed; return seed;
static const atUint16 crc16Table[256] = static const atUint16 crc16Table[256] = {
{ 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1,
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 0xC481, 0x0440, 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1, 0xCB81, 0x0B40,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 0xC901, 0x09C0, 0x0880, 0xC841, 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00, 0xDEC1,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0xF281, 0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, 0x3C00, 0xFCC1, 0xFD81, 0x3D40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 0x2800, 0xE8C1,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, 0x2080, 0xE041, 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, 0xA501, 0x65C0, 0x6480, 0xA441, 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0xAA01, 0x6AC0,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1, 0x9181, 0x5140,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0x9301, 0x53C0, 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, 0x9C01, 0x5CC0,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, 0x4100, 0x81C1, 0x8081, 0x4040};
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
};
atInt32 pos = 0; atInt32 pos = 0;
atUint16 checksum = seed; atUint16 checksum = seed;
@ -231,4 +181,4 @@ atUint16 crc16(const atUint8* data, atUint64 length, atUint16 seed, atUint64 fin
return checksum ^ final; return checksum ^ final;
} }
} // Checksums } // namespace athena::checksums

View File

@ -5,16 +5,14 @@
#include "LZ77/LZType10.hpp" #include "LZ77/LZType10.hpp"
#include "LZ77/LZType11.hpp" #include "LZ77/LZType11.hpp"
namespace athena::io::Compression namespace athena::io::Compression {
{
atInt32 decompressZlib(const atUint8* src, atUint32 srcLen, atUint8* dst, atUint32 dstLen) atInt32 decompressZlib(const atUint8* src, atUint32 srcLen, atUint8* dst, atUint32 dstLen) {
{
z_stream strm = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 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_in = strm.avail_in = srcLen;
strm.total_out = strm.avail_out = dstLen; strm.total_out = strm.avail_out = dstLen;
strm.next_in = (Bytef*) src; strm.next_in = (Bytef*)src;
strm.next_out = (Bytef*) dst; strm.next_out = (Bytef*)dst;
strm.zalloc = Z_NULL; strm.zalloc = Z_NULL;
strm.zfree = Z_NULL; strm.zfree = Z_NULL;
@ -23,22 +21,18 @@ atInt32 decompressZlib(const atUint8* src, atUint32 srcLen, atUint8* dst, atUint
atInt32 err = -1; atInt32 err = -1;
atInt32 ret = -1; atInt32 ret = -1;
err = inflateInit(&strm); //15 window bits, and the +32 tells zlib to to detect if using gzip or zlib err = inflateInit(&strm); // 15 window bits, and the +32 tells zlib to to detect if using gzip or zlib
if (err == Z_OK) if (err == Z_OK) {
{
err = inflate(&strm, Z_FINISH); err = inflate(&strm, Z_FINISH);
if (err == Z_STREAM_END) if (err == Z_STREAM_END)
ret = strm.total_out; ret = strm.total_out;
else else {
{
inflateEnd(&strm); inflateEnd(&strm);
return err; return err;
} }
} } else {
else
{
inflateEnd(&strm); inflateEnd(&strm);
return err; return err;
} }
@ -48,13 +42,12 @@ atInt32 decompressZlib(const atUint8* src, atUint32 srcLen, atUint8* dst, atUint
return ret; return ret;
} }
atInt32 compressZlib(const atUint8* src, atUint32 srcLen, atUint8* dst, atUint32 dstLen) atInt32 compressZlib(const atUint8* src, atUint32 srcLen, atUint8* dst, atUint32 dstLen) {
{
z_stream strm = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 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_in = strm.avail_in = srcLen;
strm.total_out = strm.avail_out = dstLen; strm.total_out = strm.avail_out = dstLen;
strm.next_in = (Bytef*) src; strm.next_in = (Bytef*)src;
strm.next_out = (Bytef*) dst; strm.next_out = (Bytef*)dst;
strm.zalloc = Z_NULL; strm.zalloc = Z_NULL;
strm.zfree = Z_NULL; strm.zfree = Z_NULL;
@ -65,20 +58,16 @@ atInt32 compressZlib(const atUint8* src, atUint32 srcLen, atUint8* dst, atUint32
err = deflateInit(&strm, Z_BEST_COMPRESSION); err = deflateInit(&strm, Z_BEST_COMPRESSION);
if (err == Z_OK) if (err == Z_OK) {
{
err = deflate(&strm, Z_FINISH); err = deflate(&strm, Z_FINISH);
if (err == Z_STREAM_END) if (err == Z_STREAM_END)
ret = strm.total_out; ret = strm.total_out;
else else {
{
deflateEnd(&strm); deflateEnd(&strm);
return err; return err;
} }
} } else {
else
{
deflateEnd(&strm); deflateEnd(&strm);
return err; return err;
} }
@ -88,8 +77,7 @@ atInt32 compressZlib(const atUint8* src, atUint32 srcLen, atUint8* dst, atUint32
return ret; return ret;
} }
atInt32 decompressLZO(const atUint8* source, const atInt32 sourceSize, atUint8* dst, atInt32& dstSize) atInt32 decompressLZO(const atUint8* source, const atInt32 sourceSize, atUint8* dst, atInt32& dstSize) {
{
int srcSize = sourceSize; int srcSize = sourceSize;
lzo_uint size = dstSize; lzo_uint size = dstSize;
int result = lzo1x_decompress_safe(source, srcSize, dst, &size, NULL); int result = lzo1x_decompress_safe(source, srcSize, dst, &size, NULL);
@ -98,36 +86,30 @@ atInt32 decompressLZO(const atUint8* source, const atInt32 sourceSize, atUint8*
return result; return result;
} }
//src points to the yaz0 source data (to the "real" source data, not at the header!) // src points to the yaz0 source data (to the "real" source data, not at the header!)
//dst points to a buffer uncompressedSize bytes large (you get uncompressedSize from // dst points to a buffer uncompressedSize bytes large (you get uncompressedSize from
//the second 4 bytes in the Yaz0 header). // the second 4 bytes in the Yaz0 header).
atUint32 yaz0Decode(const atUint8* src, atUint8* dst, atUint32 uncompressedSize) atUint32 yaz0Decode(const atUint8* src, atUint8* dst, atUint32 uncompressedSize) {
{ atUint32 srcPlace = 0, dstPlace = 0; // current read/write positions
atUint32 srcPlace = 0, dstPlace = 0; //current read/write positions
atInt32 validBitCount = 0; //number of valid bits left in "code" byte atInt32 validBitCount = 0; // number of valid bits left in "code" byte
atUint8 currCodeByte; atUint8 currCodeByte;
while (dstPlace < uncompressedSize) while (dstPlace < uncompressedSize) {
{ // read new "code" byte if the current one is used up
//read new "code" byte if the current one is used up if (validBitCount == 0) {
if (validBitCount == 0)
{
currCodeByte = src[srcPlace]; currCodeByte = src[srcPlace];
++srcPlace; ++srcPlace;
validBitCount = 8; validBitCount = 8;
} }
if ((currCodeByte & 0x80) != 0) if ((currCodeByte & 0x80) != 0) {
{ // straight copy
//straight copy
dst[dstPlace] = src[srcPlace]; dst[dstPlace] = src[srcPlace];
dstPlace++; dstPlace++;
srcPlace++; srcPlace++;
} } else {
else // RLE part
{
//RLE part
atUint8 byte1 = src[srcPlace]; atUint8 byte1 = src[srcPlace];
atUint8 byte2 = src[srcPlace + 1]; atUint8 byte2 = src[srcPlace + 1];
srcPlace += 2; srcPlace += 2;
@ -137,24 +119,21 @@ atUint32 yaz0Decode(const atUint8* src, atUint8* dst, atUint32 uncompressedSize)
atUint32 numBytes = byte1 >> 4; atUint32 numBytes = byte1 >> 4;
if (numBytes == 0) if (numBytes == 0) {
{
numBytes = src[srcPlace] + 0x12; numBytes = src[srcPlace] + 0x12;
srcPlace++; srcPlace++;
} } else
else
numBytes += 2; numBytes += 2;
//copy run // copy run
for (atUint32 i = 0; i < numBytes; ++i) for (atUint32 i = 0; i < numBytes; ++i) {
{
dst[dstPlace] = dst[copySource]; dst[dstPlace] = dst[copySource];
copySource++; copySource++;
dstPlace++; dstPlace++;
} }
} }
//use next bit from "code" byte // use next bit from "code" byte
currCodeByte <<= 1; currCodeByte <<= 1;
validBitCount -= 1; validBitCount -= 1;
} }
@ -163,43 +142,37 @@ atUint32 yaz0Decode(const atUint8* src, atUint8* dst, atUint32 uncompressedSize)
} }
// Yaz0 encode // Yaz0 encode
typedef struct typedef struct {
{
atUint32 srcPos, dstPos; atUint32 srcPos, dstPos;
} yaz0_Ret; } yaz0_Ret;
atUint32 simpleEnc(const atUint8* src, atInt32 size, atInt32 pos, atUint32* pMatchPos); atUint32 simpleEnc(const atUint8* src, atInt32 size, atInt32 pos, atUint32* pMatchPos);
atUint32 nintendoEnc(const atUint8* src, atInt32 size, atInt32 pos, atUint32* pMatchPos); atUint32 nintendoEnc(const atUint8* src, atInt32 size, atInt32 pos, atUint32* pMatchPos);
atUint32 yaz0Encode(const atUint8* src, atUint32 srcSize, atUint8* data) atUint32 yaz0Encode(const atUint8* src, atUint32 srcSize, atUint8* data) {
{ yaz0_Ret r = {0, 0};
yaz0_Ret r = { 0, 0 };
atInt32 pos = 0; atInt32 pos = 0;
atUint8 dst[24]; // 8 codes * 3 bytes maximum atUint8 dst[24]; // 8 codes * 3 bytes maximum
atUint32 dstSize = 0; atUint32 dstSize = 0;
atUint32 i; atUint32 i;
atUint32 validBitCount = 0; //number of valid bits left in "code" byte atUint32 validBitCount = 0; // number of valid bits left in "code" byte
atUint8 currCodeByte = 0; atUint8 currCodeByte = 0;
while (r.srcPos < srcSize) while (r.srcPos < srcSize) {
{
atUint32 numBytes; atUint32 numBytes;
atUint32 matchPos; atUint32 matchPos;
numBytes = nintendoEnc(src, srcSize, r.srcPos, &matchPos); numBytes = nintendoEnc(src, srcSize, r.srcPos, &matchPos);
if (numBytes < 3) if (numBytes < 3) {
{ // straight copy
//straight copy
dst[r.dstPos] = src[r.srcPos]; dst[r.dstPos] = src[r.srcPos];
r.dstPos++; r.dstPos++;
r.srcPos++; r.srcPos++;
//set flag for straight copy // set flag for straight copy
currCodeByte |= (0x80 >> validBitCount); currCodeByte |= (0x80 >> validBitCount);
} } else {
else // RLE part
{
//RLE part
atUint32 dist = r.srcPos - matchPos - 1; atUint32 dist = r.srcPos - matchPos - 1;
atUint8 byte1, byte2, byte3; atUint8 byte1, byte2, byte3;
@ -216,8 +189,7 @@ atUint32 yaz0Encode(const atUint8* src, atUint32 srcSize, atUint8* data)
byte3 = numBytes - 0x12; byte3 = numBytes - 0x12;
dst[r.dstPos++] = byte3; dst[r.dstPos++] = byte3;
} } else // 2 byte encoding
else // 2 byte encoding
{ {
byte1 = ((numBytes - 2) << 4) | (dist >> 8); byte1 = ((numBytes - 2) << 4) | (dist >> 8);
byte2 = dist & 0xff; byte2 = dist & 0xff;
@ -230,13 +202,12 @@ atUint32 yaz0Encode(const atUint8* src, atUint32 srcSize, atUint8* data)
validBitCount++; validBitCount++;
//write eight codes // write eight codes
if (validBitCount == 8) if (validBitCount == 8) {
{
data[pos] = currCodeByte; data[pos] = currCodeByte;
pos++; pos++;
for (i = 0; i </*=*/r.dstPos; pos++, i++) for (i = 0; i < /*=*/r.dstPos; pos++, i++)
data[pos] = dst[i]; data[pos] = dst[i];
dstSize += r.dstPos + 1; dstSize += r.dstPos + 1;
@ -247,12 +218,11 @@ atUint32 yaz0Encode(const atUint8* src, atUint32 srcSize, atUint8* data)
} }
} }
if (validBitCount > 0) if (validBitCount > 0) {
{
data[pos] = currCodeByte; data[pos] = currCodeByte;
pos++; pos++;
for (i = 0; i </*=*/r.dstPos; pos++, i++) for (i = 0; i < /*=*/r.dstPos; pos++, i++)
data[pos] = dst[i]; data[pos] = dst[i];
dstSize += r.dstPos + 1; dstSize += r.dstPos + 1;
@ -266,8 +236,7 @@ atUint32 yaz0Encode(const atUint8* src, atUint32 srcSize, atUint8* data)
} }
// a lookahead encoding scheme for ngc Yaz0 // a lookahead encoding scheme for ngc Yaz0
atUint32 nintendoEnc(const atUint8* src, atInt32 size, atInt32 pos, atUint32* pMatchPos) atUint32 nintendoEnc(const atUint8* src, atInt32 size, atInt32 pos, atUint32* pMatchPos) {
{
atUint32 numBytes = 1; atUint32 numBytes = 1;
static atUint32 numBytes1; static atUint32 numBytes1;
static atUint32 matchPos; static atUint32 matchPos;
@ -275,8 +244,7 @@ atUint32 nintendoEnc(const atUint8* src, atInt32 size, atInt32 pos, atUint32* pM
// if prevFlag is set, it means that the previous position was determined by look-ahead try. // if prevFlag is set, it means that the previous position was determined by look-ahead try.
// so just use it. this is not the best optimization, but nintendo's choice for speed. // so just use it. this is not the best optimization, but nintendo's choice for speed.
if (prevFlag == 1) if (prevFlag == 1) {
{
*pMatchPos = matchPos; *pMatchPos = matchPos;
prevFlag = 0; prevFlag = 0;
return numBytes1; return numBytes1;
@ -287,14 +255,12 @@ atUint32 nintendoEnc(const atUint8* src, atInt32 size, atInt32 pos, atUint32* pM
*pMatchPos = matchPos; *pMatchPos = matchPos;
// if this position is RLE encoded, then compare to copying 1 byte and next position(pos+1) encoding // if this position is RLE encoded, then compare to copying 1 byte and next position(pos+1) encoding
if (numBytes >= 3) if (numBytes >= 3) {
{
numBytes1 = simpleEnc(src, size, pos + 1, &matchPos); numBytes1 = simpleEnc(src, size, pos + 1, &matchPos);
// if the next position encoding is +2 longer than current position, choose it. // if the next position encoding is +2 longer than current position, choose it.
// this does not guarantee the best optimization, but fairly good optimization with speed. // this does not guarantee the best optimization, but fairly good optimization with speed.
if (numBytes1 >= numBytes + 2) if (numBytes1 >= numBytes + 2) {
{
numBytes = 1; numBytes = 1;
prevFlag = 1; prevFlag = 1;
} }
@ -304,8 +270,7 @@ atUint32 nintendoEnc(const atUint8* src, atInt32 size, atInt32 pos, atUint32* pM
} }
// simple and straight encoding scheme for Yaz0 // simple and straight encoding scheme for Yaz0
atUint32 simpleEnc(const atUint8* src, atInt32 size, atInt32 pos, atUint32* pMatchPos) atUint32 simpleEnc(const atUint8* src, atInt32 size, atInt32 pos, atUint32* pMatchPos) {
{
int startPos = pos - 0x1000, j, i; int startPos = pos - 0x1000, j, i;
atUint32 numBytes = 1; atUint32 numBytes = 1;
atUint32 matchPos = 0; atUint32 matchPos = 0;
@ -313,16 +278,13 @@ atUint32 simpleEnc(const atUint8* src, atInt32 size, atInt32 pos, atUint32* pMat
if (startPos < 0) if (startPos < 0)
startPos = 0; startPos = 0;
for (i = startPos; i < pos; i++) for (i = startPos; i < pos; i++) {
{ for (j = 0; j < size - pos; j++) {
for (j = 0; j < size - pos; j++)
{
if (src[i + j] != src[j + pos]) if (src[i + j] != src[j + pos])
break; break;
} }
if ((atUint32)j > numBytes) if ((atUint32)j > numBytes) {
{
numBytes = j; numBytes = j;
matchPos = i; matchPos = i;
} }
@ -336,20 +298,18 @@ atUint32 simpleEnc(const atUint8* src, atInt32 size, atInt32 pos, atUint32* pMat
return numBytes; return numBytes;
} }
atUint32 decompressLZ77(const atUint8* src, atUint32 srcLen, atUint8** dst) atUint32 decompressLZ77(const atUint8* src, atUint32 srcLen, atUint8** dst) {
{
if (*(atUint8*)src == 0x11) if (*(atUint8*)src == 0x11)
return LZType11().decompress(src, dst, srcLen); return LZType11().decompress(src, dst, srcLen);
return LZType10(2).decompress(src, dst, srcLen); return LZType10(2).decompress(src, dst, srcLen);
} }
atUint32 compressLZ77(const atUint8* src, atUint32 srcLen, atUint8** dst, bool extended) atUint32 compressLZ77(const atUint8* src, atUint32 srcLen, atUint8** dst, bool extended) {
{
if (extended) if (extended)
return LZType11().compress(src, dst, srcLen); return LZType11().compress(src, dst, srcLen);
return LZType10(2).compress(src, dst, srcLen); return LZType10(2).compress(src, dst, srcLen);
} }
} // Compression } // namespace athena::io::Compression

File diff suppressed because it is too large Load Diff

View File

@ -18,20 +18,12 @@
#define realpath(__name, __resolved) _fullpath((__name), (__resolved), 4096) #define realpath(__name, __resolved) _fullpath((__name), (__resolved), 4096)
#endif #endif
namespace athena namespace athena {
{ Dir::Dir(std::string_view path) : m_path(path) {}
Dir::Dir(std::string_view path)
: m_path(path)
{
}
std::string Dir::absolutePath() const std::string Dir::absolutePath() const { return FileInfo(m_path).absoluteFilePath(); }
{
return FileInfo(m_path).absoluteFilePath();
}
bool Dir::isDir() const bool Dir::isDir() const {
{
atStat64_t st; atStat64_t st;
int e = atStat64(m_path.c_str(), &st); int e = atStat64(m_path.c_str(), &st);
if (e < 0) if (e < 0)
@ -40,11 +32,9 @@ bool Dir::isDir() const
return (S_ISDIR(st.st_mode)); return (S_ISDIR(st.st_mode));
} }
bool Dir::cd(std::string_view path) bool Dir::cd(std::string_view path) {
{
Dir tmp(path); Dir tmp(path);
if (tmp.isDir()) if (tmp.isDir()) {
{
m_path = path; m_path = path;
return true; return true;
} }
@ -52,13 +42,9 @@ bool Dir::cd(std::string_view path)
return false; return false;
} }
bool Dir::rm(std::string_view path) bool Dir::rm(std::string_view path) { return !(remove((m_path + "/" + path.data()).c_str()) < 0); }
{
return !(remove((m_path + "/" + path.data()).c_str()) < 0);
}
bool Dir::touch() bool Dir::touch() {
{
srand(time(NULL)); srand(time(NULL));
atUint64 tmp = utility::rand64(); atUint64 tmp = utility::rand64();
std::string tmpFile = utility::sprintf("%" PRIX64 ".tmp", tmp); std::string tmpFile = utility::sprintf("%" PRIX64 ".tmp", tmp);
@ -68,8 +54,7 @@ bool Dir::touch()
return false; return false;
} }
bool Dir::mkdir(std::string_view dir, mode_t mode) bool Dir::mkdir(std::string_view dir, mode_t mode) {
{
#if _WIN32 #if _WIN32
return !(::_mkdir(dir.data()) < 0); return !(::_mkdir(dir.data()) < 0);
#else #else
@ -77,8 +62,7 @@ bool Dir::mkdir(std::string_view dir, mode_t mode)
#endif #endif
} }
bool Dir::mkpath(std::string_view path, mode_t mode) bool Dir::mkpath(std::string_view path, mode_t mode) {
{
std::vector<std::string> dirs = utility::split(path, '/'); std::vector<std::string> dirs = utility::split(path, '/');
if (dirs.empty()) if (dirs.empty())
dirs = utility::split(path, '\\'); dirs = utility::split(path, '\\');
@ -87,10 +71,8 @@ bool Dir::mkpath(std::string_view path, mode_t mode)
bool ret = false; bool ret = false;
std::string newPath; std::string newPath;
for (const std::string& dir : dirs) for (const std::string& dir : dirs) {
{ if (dir.size() == 2 && dir[1] == ':') {
if (dir.size() == 2 && dir[1] == ':')
{
newPath += dir + "//"; newPath += dir + "//";
continue; continue;
} }
@ -102,5 +84,4 @@ bool Dir::mkpath(std::string_view path, mode_t mode)
return ret; return ret;
} }
} } // namespace athena

View File

@ -29,16 +29,11 @@
#define realpath(__name, __resolved) _fullpath((__resolved), (__name), 4096) #define realpath(__name, __resolved) _fullpath((__resolved), (__name), 4096)
#endif #endif
namespace athena namespace athena {
{
FileInfo::FileInfo(std::string_view path) FileInfo::FileInfo(std::string_view path) : m_path(path) {}
: m_path(path)
{
}
std::string FileInfo::absolutePath() const std::string FileInfo::absolutePath() const {
{
std::string path = absoluteFilePath(); std::string path = absoluteFilePath();
size_t pos = path.find_last_of('/'); size_t pos = path.find_last_of('/');
if (pos == std::string::npos) if (pos == std::string::npos)
@ -46,18 +41,16 @@ std::string FileInfo::absolutePath() const
if (pos == std::string::npos) if (pos == std::string::npos)
return path; return path;
return path.substr(0, pos+1); return path.substr(0, pos + 1);
} }
std::string FileInfo::absoluteFilePath() const std::string FileInfo::absoluteFilePath() const {
{
char ret[4096]; char ret[4096];
realpath(m_path.c_str(), ret); realpath(m_path.c_str(), ret);
return ret; return ret;
} }
std::string FileInfo::filename() const std::string FileInfo::filename() const {
{
size_t pos = m_path.find_last_of('/'); size_t pos = m_path.find_last_of('/');
if (pos == std::string::npos) if (pos == std::string::npos)
pos = m_path.find_last_of('\\'); pos = m_path.find_last_of('\\');
@ -66,8 +59,7 @@ std::string FileInfo::filename() const
return m_path.substr(pos + 1); return m_path.substr(pos + 1);
} }
std::string FileInfo::extension() const std::string FileInfo::extension() const {
{
size_t pos = m_path.find_last_of('.'); size_t pos = m_path.find_last_of('.');
if (pos == std::string::npos) if (pos == std::string::npos)
return std::string(); return std::string();
@ -75,13 +67,9 @@ std::string FileInfo::extension() const
return m_path.substr(pos + 1); return m_path.substr(pos + 1);
} }
atUint64 FileInfo::size() const atUint64 FileInfo::size() const { return utility::fileSize(m_path); }
{
return utility::fileSize(m_path);
}
bool FileInfo::exists() const bool FileInfo::exists() const {
{
atStat64_t st; atStat64_t st;
int e = atStat64(m_path.c_str(), &st); int e = atStat64(m_path.c_str(), &st);
@ -91,8 +79,7 @@ bool FileInfo::exists() const
return (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)); return (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode));
} }
bool FileInfo::isLink() const bool FileInfo::isLink() const {
{
atStat64_t st; atStat64_t st;
int e = atStat64(m_path.c_str(), &st); int e = atStat64(m_path.c_str(), &st);
if (e < 0) if (e < 0)
@ -101,8 +88,7 @@ bool FileInfo::isLink() const
return (S_ISLNK(st.st_mode)); return (S_ISLNK(st.st_mode));
} }
bool FileInfo::isFile() const bool FileInfo::isFile() const {
{
atStat64_t st; atStat64_t st;
int e = atStat64(m_path.c_str(), &st); int e = atStat64(m_path.c_str(), &st);
if (e < 0) if (e < 0)
@ -111,8 +97,7 @@ bool FileInfo::isFile() const
return (S_ISREG(st.st_mode)); return (S_ISREG(st.st_mode));
} }
bool FileInfo::touch() const bool FileInfo::touch() const {
{
#if defined(__GNUC__) && !(defined(HW_DOL) || defined(HW_RVL) || defined(GEKKO)) #if defined(__GNUC__) && !(defined(HW_DOL) || defined(HW_RVL) || defined(GEKKO))
atStat64_t st; atStat64_t st;
if (atStat64(m_path.c_str(), &st) < 0) { if (atStat64(m_path.c_str(), &st) < 0) {
@ -137,16 +122,14 @@ bool FileInfo::touch() const
/* /*
* Use GetFileTime() to get the file modification time. * Use GetFileTime() to get the file modification time.
*/ */
if (GetFileTime(fh, NULL, NULL, &modtime) == 0) if (GetFileTime(fh, NULL, NULL, &modtime) == 0) {
{
CloseHandle(fh); CloseHandle(fh);
return false; return false;
} }
FileTimeToSystemTime(&modtime, &st); FileTimeToSystemTime(&modtime, &st);
if (GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, date, sizeof date / sizeof date[0]) == 0 || if (GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, date, sizeof date / sizeof date[0]) == 0 ||
GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, time, sizeof time / sizeof time[0]) == 0) GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, time, sizeof time / sizeof time[0]) == 0) {
{
CloseHandle(fh); CloseHandle(fh);
return false; return false;
} }
@ -157,14 +140,12 @@ bool FileInfo::touch() const
*/ */
GetSystemTime(&st); GetSystemTime(&st);
if (GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, date, sizeof date / sizeof date[0]) == 0 || if (GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, date, sizeof date / sizeof date[0]) == 0 ||
GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, time, sizeof time / sizeof time[0]) == 0) GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, time, sizeof time / sizeof time[0]) == 0) {
{
CloseHandle(fh); CloseHandle(fh);
return false; return false;
} }
SystemTimeToFileTime(&st, &modtime); SystemTimeToFileTime(&st, &modtime);
if (SetFileTime(fh, NULL, NULL, &modtime) == 0) if (SetFileTime(fh, NULL, NULL, &modtime) == 0) {
{
CloseHandle(fh); CloseHandle(fh);
return false; return false;
} }
@ -193,4 +174,4 @@ bool FileInfo::touch() const
return true; return true;
} }
} } // namespace athena

View File

@ -7,42 +7,30 @@
#include "osx_largefilewrapper.h" #include "osx_largefilewrapper.h"
#endif #endif
namespace athena::io namespace athena::io {
{
FileReader::FileReader(std::string_view filename, atInt32 cacheSize, bool globalErr) FileReader::FileReader(std::string_view filename, atInt32 cacheSize, bool globalErr)
: m_fileHandle(nullptr), : m_fileHandle(nullptr), m_cacheData(nullptr), m_offset(0), m_globalErr(globalErr) {
m_cacheData(nullptr),
m_offset(0),
m_globalErr(globalErr)
{
m_filename = filename; m_filename = filename;
open(); open();
setCacheSize(cacheSize); setCacheSize(cacheSize);
} }
FileReader::FileReader(std::wstring_view filename, atInt32 cacheSize, bool globalErr) FileReader::FileReader(std::wstring_view filename, atInt32 cacheSize, bool globalErr)
: m_fileHandle(nullptr), : m_fileHandle(nullptr), m_cacheData(nullptr), m_offset(0), m_globalErr(globalErr) {
m_cacheData(nullptr),
m_offset(0),
m_globalErr(globalErr)
{
m_filename = utility::wideToUtf8(filename); m_filename = utility::wideToUtf8(filename);
open(); open();
setCacheSize(cacheSize); setCacheSize(cacheSize);
} }
FileReader::~FileReader() FileReader::~FileReader() {
{
if (isOpen()) if (isOpen())
close(); close();
} }
void FileReader::open() void FileReader::open() {
{
m_fileHandle = fopen(m_filename.c_str(), "rb"); m_fileHandle = fopen(m_filename.c_str(), "rb");
if (!m_fileHandle) if (!m_fileHandle) {
{
std::string _filename = filename(); std::string _filename = filename();
if (m_globalErr) if (m_globalErr)
atError("File not found '%s'", _filename.c_str()); atError("File not found '%s'", _filename.c_str());
@ -54,10 +42,8 @@ void FileReader::open()
m_hasError = false; m_hasError = false;
} }
void FileReader::close() void FileReader::close() {
{ if (!m_fileHandle) {
if (!m_fileHandle)
{
if (m_globalErr) if (m_globalErr)
atError("Cannot close an unopened stream"); atError("Cannot close an unopened stream");
setError(); setError();
@ -69,17 +55,14 @@ void FileReader::close()
return; return;
} }
void FileReader::seek(atInt64 pos, SeekOrigin origin) void FileReader::seek(atInt64 pos, SeekOrigin origin) {
{
if (!isOpen()) if (!isOpen())
return; return;
// check block position // check block position
if (m_blockSize > 0) if (m_blockSize > 0) {
{
atUint64 oldOff = m_offset; atUint64 oldOff = m_offset;
switch(origin) switch (origin) {
{
case SeekOrigin::Begin: case SeekOrigin::Begin:
m_offset = pos; m_offset = pos;
break; break;
@ -90,8 +73,7 @@ void FileReader::seek(atInt64 pos, SeekOrigin origin)
m_offset = length() - pos; m_offset = length() - pos;
break; break;
} }
if (m_offset > length()) if (m_offset > length()) {
{
oldOff = m_offset; oldOff = m_offset;
if (m_globalErr) if (m_globalErr)
atError("Unable to seek in file"); atError("Unable to seek in file");
@ -100,25 +82,20 @@ void FileReader::seek(atInt64 pos, SeekOrigin origin)
} }
size_t block = m_offset / m_blockSize; size_t block = m_offset / m_blockSize;
if (block != m_curBlock) if (block != m_curBlock) {
{
fseeko64(m_fileHandle, block * m_blockSize, SEEK_SET); fseeko64(m_fileHandle, block * m_blockSize, SEEK_SET);
fread(m_cacheData.get(), 1, m_blockSize, m_fileHandle); fread(m_cacheData.get(), 1, m_blockSize, m_fileHandle);
m_curBlock = (atInt32)block; m_curBlock = (atInt32)block;
} }
} } else if (fseeko64(m_fileHandle, pos, (int)origin) != 0) {
else if (fseeko64(m_fileHandle, pos, (int)origin) != 0)
{
if (m_globalErr) if (m_globalErr)
atError("Unable to seek in file"); atError("Unable to seek in file");
setError(); setError();
} }
} }
atUint64 FileReader::position() const atUint64 FileReader::position() const {
{ if (!isOpen()) {
if (!isOpen())
{
if (m_globalErr) if (m_globalErr)
atError("File not open"); atError("File not open");
return 0; return 0;
@ -130,10 +107,8 @@ atUint64 FileReader::position() const
return ftello64(m_fileHandle); return ftello64(m_fileHandle);
} }
atUint64 FileReader::length() const atUint64 FileReader::length() const {
{ if (!isOpen()) {
if (!isOpen())
{
if (m_globalErr) if (m_globalErr)
atError("File not open"); atError("File not open");
return 0; return 0;
@ -142,10 +117,8 @@ atUint64 FileReader::length() const
return utility::fileSize(m_filename); return utility::fileSize(m_filename);
} }
atUint64 FileReader::readUBytesToBuf(void* buf, atUint64 len) atUint64 FileReader::readUBytesToBuf(void* buf, atUint64 len) {
{ if (!isOpen()) {
if (!isOpen())
{
if (m_globalErr) if (m_globalErr)
atError("File not open for reading"); atError("File not open for reading");
setError(); setError();
@ -154,8 +127,7 @@ atUint64 FileReader::readUBytesToBuf(void* buf, atUint64 len)
if (m_blockSize <= 0) if (m_blockSize <= 0)
return fread(buf, 1, len, m_fileHandle); return fread(buf, 1, len, m_fileHandle);
else else {
{
atUint64 fs = utility::fileSize(m_filename); atUint64 fs = utility::fileSize(m_filename);
if (m_offset >= fs) if (m_offset >= fs)
return 0; return 0;
@ -168,10 +140,8 @@ atUint64 FileReader::readUBytesToBuf(void* buf, atUint64 len)
atUint64 rem = len; atUint64 rem = len;
atUint8* dst = (atUint8*)buf; atUint8* dst = (atUint8*)buf;
while (rem) while (rem) {
{ if (block != m_curBlock) {
if (block != m_curBlock)
{
fseeko64(m_fileHandle, block * m_blockSize, SEEK_SET); fseeko64(m_fileHandle, block * m_blockSize, SEEK_SET);
fread(m_cacheData.get(), 1, m_blockSize, m_fileHandle); fread(m_cacheData.get(), 1, m_blockSize, m_fileHandle);
m_curBlock = (atInt32)block; m_curBlock = (atInt32)block;
@ -192,8 +162,7 @@ atUint64 FileReader::readUBytesToBuf(void* buf, atUint64 len)
} }
} }
void FileReader::setCacheSize(const atInt32 blockSize) void FileReader::setCacheSize(const atInt32 blockSize) {
{
m_blockSize = blockSize; m_blockSize = blockSize;
if (m_blockSize > length()) if (m_blockSize > length())
@ -204,4 +173,4 @@ void FileReader::setCacheSize(const atInt32 blockSize)
m_cacheData.reset(new atUint8[m_blockSize]); m_cacheData.reset(new atUint8[m_blockSize]);
} }
} // Athena } // namespace athena::io

View File

@ -1,52 +1,38 @@
#include "athena/FileReader.hpp" #include "athena/FileReader.hpp"
#include "win32_largefilewrapper.h" #include "win32_largefilewrapper.h"
namespace athena::io namespace athena::io {
{
FileReader::FileReader(std::string_view filename, atInt32 cacheSize, bool globalErr) FileReader::FileReader(std::string_view filename, atInt32 cacheSize, bool globalErr)
: m_fileHandle(nullptr), : m_fileHandle(nullptr), m_cacheData(nullptr), m_offset(0), m_globalErr(globalErr) {
m_cacheData(nullptr),
m_offset(0),
m_globalErr(globalErr)
{
m_filename = utility::utf8ToWide(filename); m_filename = utility::utf8ToWide(filename);
open(); open();
setCacheSize(cacheSize); setCacheSize(cacheSize);
} }
FileReader::FileReader(std::wstring_view filename, atInt32 cacheSize, bool globalErr) FileReader::FileReader(std::wstring_view filename, atInt32 cacheSize, bool globalErr)
: m_fileHandle(nullptr), : m_fileHandle(nullptr), m_cacheData(nullptr), m_offset(0), m_globalErr(globalErr) {
m_cacheData(nullptr),
m_offset(0),
m_globalErr(globalErr)
{
m_filename = filename; m_filename = filename;
open(); open();
setCacheSize(cacheSize); setCacheSize(cacheSize);
} }
FileReader::~FileReader() FileReader::~FileReader() {
{
if (isOpen()) if (isOpen())
close(); close();
} }
void FileReader::open() void FileReader::open() {
{
int attempt = 0; int attempt = 0;
do do {
{
#if WINDOWS_STORE #if WINDOWS_STORE
m_fileHandle = CreateFile2(m_filename.c_str(), GENERIC_READ, FILE_SHARE_READ, m_fileHandle = CreateFile2(m_filename.c_str(), GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr);
OPEN_EXISTING, nullptr);
#else #else
m_fileHandle = CreateFileW(m_filename.c_str(), GENERIC_READ, FILE_SHARE_READ, m_fileHandle = CreateFileW(m_filename.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); FILE_ATTRIBUTE_NORMAL, nullptr);
#endif #endif
} while (m_fileHandle == INVALID_HANDLE_VALUE && attempt++ < 100); } while (m_fileHandle == INVALID_HANDLE_VALUE && attempt++ < 100);
if (m_fileHandle == INVALID_HANDLE_VALUE) if (m_fileHandle == INVALID_HANDLE_VALUE) {
{
m_fileHandle = 0; m_fileHandle = 0;
std::string _filename = filename(); std::string _filename = filename();
if (m_globalErr) if (m_globalErr)
@ -59,10 +45,8 @@ void FileReader::open()
m_hasError = false; m_hasError = false;
} }
void FileReader::close() void FileReader::close() {
{ if (!m_fileHandle) {
if (!m_fileHandle)
{
if (m_globalErr) if (m_globalErr)
atError("Cannot close an unopened stream"); atError("Cannot close an unopened stream");
setError(); setError();
@ -74,17 +58,14 @@ void FileReader::close()
return; return;
} }
void FileReader::seek(atInt64 pos, SeekOrigin origin) void FileReader::seek(atInt64 pos, SeekOrigin origin) {
{
if (!isOpen()) if (!isOpen())
return; return;
// check block position // check block position
if (m_blockSize > 0) if (m_blockSize > 0) {
{
atUint64 oldOff = m_offset; atUint64 oldOff = m_offset;
switch(origin) switch (origin) {
{
case SeekOrigin::Begin: case SeekOrigin::Begin:
m_offset = pos; m_offset = pos;
break; break;
@ -95,8 +76,7 @@ void FileReader::seek(atInt64 pos, SeekOrigin origin)
m_offset = length() - pos; m_offset = length() - pos;
break; break;
} }
if (m_offset > length()) if (m_offset > length()) {
{
oldOff = m_offset; oldOff = m_offset;
if (m_globalErr) if (m_globalErr)
atError("Unable to seek in file"); atError("Unable to seek in file");
@ -105,21 +85,17 @@ void FileReader::seek(atInt64 pos, SeekOrigin origin)
} }
size_t block = m_offset / m_blockSize; size_t block = m_offset / m_blockSize;
if (block != m_curBlock) if (block != m_curBlock) {
{
LARGE_INTEGER li; LARGE_INTEGER li;
li.QuadPart = block * m_blockSize; li.QuadPart = block * m_blockSize;
SetFilePointerEx(m_fileHandle, li, nullptr, FILE_BEGIN); SetFilePointerEx(m_fileHandle, li, nullptr, FILE_BEGIN);
ReadFile(m_fileHandle, m_cacheData.get(), m_blockSize, nullptr, nullptr); ReadFile(m_fileHandle, m_cacheData.get(), m_blockSize, nullptr, nullptr);
m_curBlock = (atInt32)block; m_curBlock = (atInt32)block;
} }
} } else {
else
{
LARGE_INTEGER li; LARGE_INTEGER li;
li.QuadPart = pos; li.QuadPart = pos;
if (!SetFilePointerEx(m_fileHandle, li, nullptr, DWORD(origin))) if (!SetFilePointerEx(m_fileHandle, li, nullptr, DWORD(origin))) {
{
if (m_globalErr) if (m_globalErr)
atError("Unable to seek in file"); atError("Unable to seek in file");
setError(); setError();
@ -127,10 +103,8 @@ void FileReader::seek(atInt64 pos, SeekOrigin origin)
} }
} }
atUint64 FileReader::position() const atUint64 FileReader::position() const {
{ if (!isOpen()) {
if (!isOpen())
{
if (m_globalErr) if (m_globalErr)
atError("File not open"); atError("File not open");
return 0; return 0;
@ -138,8 +112,7 @@ atUint64 FileReader::position() const
if (m_blockSize > 0) if (m_blockSize > 0)
return m_offset; return m_offset;
else else {
{
LARGE_INTEGER li = {}; LARGE_INTEGER li = {};
LARGE_INTEGER res; LARGE_INTEGER res;
SetFilePointerEx(m_fileHandle, li, &res, FILE_CURRENT); SetFilePointerEx(m_fileHandle, li, &res, FILE_CURRENT);
@ -147,10 +120,8 @@ atUint64 FileReader::position() const
} }
} }
atUint64 FileReader::length() const atUint64 FileReader::length() const {
{ if (!isOpen()) {
if (!isOpen())
{
if (m_globalErr) if (m_globalErr)
atError("File not open"); atError("File not open");
return 0; return 0;
@ -161,24 +132,19 @@ atUint64 FileReader::length() const
return res.QuadPart; return res.QuadPart;
} }
atUint64 FileReader::readUBytesToBuf(void* buf, atUint64 len) atUint64 FileReader::readUBytesToBuf(void* buf, atUint64 len) {
{ if (!isOpen()) {
if (!isOpen())
{
if (m_globalErr) if (m_globalErr)
atError("File not open for reading"); atError("File not open for reading");
setError(); setError();
return 0; return 0;
} }
if (m_blockSize <= 0) if (m_blockSize <= 0) {
{
DWORD ret = 0; DWORD ret = 0;
ReadFile(m_fileHandle, buf, len, &ret, nullptr); ReadFile(m_fileHandle, buf, len, &ret, nullptr);
return ret; return ret;
} } else {
else
{
LARGE_INTEGER fs; LARGE_INTEGER fs;
GetFileSizeEx(m_fileHandle, &fs); GetFileSizeEx(m_fileHandle, &fs);
if (m_offset >= atUint64(fs.QuadPart)) if (m_offset >= atUint64(fs.QuadPart))
@ -192,10 +158,8 @@ atUint64 FileReader::readUBytesToBuf(void* buf, atUint64 len)
atUint64 rem = len; atUint64 rem = len;
atUint8* dst = (atUint8*)buf; atUint8* dst = (atUint8*)buf;
while (rem) while (rem) {
{ if (block != m_curBlock) {
if (block != m_curBlock)
{
LARGE_INTEGER li; LARGE_INTEGER li;
li.QuadPart = block * m_blockSize; li.QuadPart = block * m_blockSize;
SetFilePointerEx(m_fileHandle, li, nullptr, FILE_BEGIN); SetFilePointerEx(m_fileHandle, li, nullptr, FILE_BEGIN);
@ -218,8 +182,7 @@ atUint64 FileReader::readUBytesToBuf(void* buf, atUint64 len)
} }
} }
void FileReader::setCacheSize(const atInt32 blockSize) void FileReader::setCacheSize(const atInt32 blockSize) {
{
m_blockSize = blockSize; m_blockSize = blockSize;
if (m_blockSize > length()) if (m_blockSize > length())
@ -230,4 +193,4 @@ void FileReader::setCacheSize(const atInt32 blockSize)
m_cacheData.reset(new atUint8[m_blockSize]); m_cacheData.reset(new atUint8[m_blockSize]);
} }
} // Athena } // namespace athena::io

View File

@ -1,11 +1,8 @@
#include "athena/FileWriter.hpp" #include "athena/FileWriter.hpp"
namespace athena::io namespace athena::io {
{ void TransactionalFileWriter::seek(atInt64 pos, SeekOrigin origin) {
void TransactionalFileWriter::seek(atInt64 pos, SeekOrigin origin) switch (origin) {
{
switch (origin)
{
case SeekOrigin::Begin: case SeekOrigin::Begin:
m_position = pos; m_position = pos;
break; break;
@ -17,11 +14,9 @@ void TransactionalFileWriter::seek(atInt64 pos, SeekOrigin origin)
} }
} }
void TransactionalFileWriter::writeUBytes(const atUint8* data, atUint64 len) void TransactionalFileWriter::writeUBytes(const atUint8* data, atUint64 len) {
{
atUint64 neededSz = m_position + len; atUint64 neededSz = m_position + len;
if (neededSz > m_deferredBuffer.size()) if (neededSz > m_deferredBuffer.size()) {
{
m_deferredBuffer.reserve(neededSz * 2); m_deferredBuffer.reserve(neededSz * 2);
m_deferredBuffer.resize(neededSz); m_deferredBuffer.resize(neededSz);
} }
@ -29,4 +24,4 @@ void TransactionalFileWriter::writeUBytes(const atUint8* data, atUint64 len)
memmove(m_deferredBuffer.data() + m_position, data, len); memmove(m_deferredBuffer.data() + m_position, data, len);
m_position += len; m_position += len;
} }
} } // namespace athena::io

View File

@ -9,12 +9,9 @@
#include <unistd.h> #include <unistd.h>
namespace athena::io namespace athena::io {
{
FileWriter::FileWriter(std::string_view filename, bool overwrite, bool globalErr) FileWriter::FileWriter(std::string_view filename, bool overwrite, bool globalErr)
: m_fileHandle(NULL), : m_fileHandle(NULL), m_globalErr(globalErr) {
m_globalErr(globalErr)
{
#if _WIN32 #if _WIN32
m_filename = utility::utf8ToWide(filename); m_filename = utility::utf8ToWide(filename);
#else #else
@ -24,9 +21,7 @@ FileWriter::FileWriter(std::string_view filename, bool overwrite, bool globalErr
} }
FileWriter::FileWriter(std::wstring_view filename, bool overwrite, bool globalErr) FileWriter::FileWriter(std::wstring_view filename, bool overwrite, bool globalErr)
: m_fileHandle(NULL), : m_fileHandle(NULL), m_globalErr(globalErr) {
m_globalErr(globalErr)
{
#if _WIN32 #if _WIN32
m_filename = filename; m_filename = filename;
#else #else
@ -35,31 +30,24 @@ FileWriter::FileWriter(std::wstring_view filename, bool overwrite, bool globalEr
open(overwrite); open(overwrite);
} }
FileWriter::~FileWriter() FileWriter::~FileWriter() {
{
if (isOpen()) if (isOpen())
close(); close();
} }
void FileWriter::open(bool overwrite) void FileWriter::open(bool overwrite) {
{ if (overwrite) {
if (overwrite)
{
std::string tmpFilename = m_filename + '~'; std::string tmpFilename = m_filename + '~';
m_fileHandle = fopen(tmpFilename.c_str(), "w+b"); m_fileHandle = fopen(tmpFilename.c_str(), "w+b");
} } else {
else
{
m_fileHandle = fopen(m_filename.c_str(), "a+b"); m_fileHandle = fopen(m_filename.c_str(), "a+b");
if (m_fileHandle) if (m_fileHandle) {
{
fclose(m_fileHandle); fclose(m_fileHandle);
m_fileHandle = fopen(m_filename.c_str(), "r+b"); m_fileHandle = fopen(m_filename.c_str(), "r+b");
} }
} }
if (!m_fileHandle) if (!m_fileHandle) {
{
if (m_globalErr) if (m_globalErr)
atError("Unable to open file '%s'", filename().c_str()); atError("Unable to open file '%s'", filename().c_str());
setError(); setError();
@ -70,10 +58,8 @@ void FileWriter::open(bool overwrite)
m_hasError = false; m_hasError = false;
} }
void FileWriter::close() void FileWriter::close() {
{ if (!m_fileHandle) {
if (!m_fileHandle)
{
if (m_globalErr) if (m_globalErr)
atError("Cannot close an unopened stream"); atError("Cannot close an unopened stream");
setError(); setError();
@ -85,55 +71,44 @@ void FileWriter::close()
std::string tmpFilename = m_filename + '~'; std::string tmpFilename = m_filename + '~';
#ifdef __SWITCH__ #ifdef __SWITCH__
/* Due to Horizon not being a fully POSIX compatible OS, we need to make sure the file *does not* exist before attempting to rename */ /* Due to Horizon not being a fully POSIX compatible OS, we need to make sure the file *does not* exist before
* attempting to rename */
unlink(m_filename.c_str()); unlink(m_filename.c_str());
#endif #endif
rename(tmpFilename.c_str(), m_filename.c_str()); rename(tmpFilename.c_str(), m_filename.c_str());
} }
void FileWriter::seek(atInt64 pos, SeekOrigin origin) void FileWriter::seek(atInt64 pos, SeekOrigin origin) {
{ if (!isOpen()) {
if (!isOpen())
{
if (m_globalErr) if (m_globalErr)
atError("Unable to seek in file, not open"); atError("Unable to seek in file, not open");
setError(); setError();
return; return;
} }
if (fseeko64(m_fileHandle, pos, (int)origin) != 0) if (fseeko64(m_fileHandle, pos, (int)origin) != 0) {
{
if (m_globalErr) if (m_globalErr)
atError("Unable to seek in file"); atError("Unable to seek in file");
setError(); setError();
} }
} }
atUint64 FileWriter::position() const atUint64 FileWriter::position() const { return ftello64(m_fileHandle); }
{
return ftello64(m_fileHandle);
}
atUint64 FileWriter::length() const atUint64 FileWriter::length() const { return utility::fileSize(m_filename); }
{
return utility::fileSize(m_filename);
}
void FileWriter::writeUBytes(const atUint8* data, atUint64 len) void FileWriter::writeUBytes(const atUint8* data, atUint64 len) {
{ if (!isOpen()) {
if (!isOpen())
{
if (m_globalErr) if (m_globalErr)
atError("File not open for writing"); atError("File not open for writing");
setError(); setError();
return; return;
} }
if (fwrite(data, 1, len, m_fileHandle) != len) if (fwrite(data, 1, len, m_fileHandle) != len) {
{
if (m_globalErr) if (m_globalErr)
atError("Unable to write to stream"); atError("Unable to write to stream");
setError(); setError();
} }
} }
} // Athena } // namespace athena::io

View File

@ -1,60 +1,46 @@
#include "athena/FileWriter.hpp" #include "athena/FileWriter.hpp"
#include "win32_largefilewrapper.h" #include "win32_largefilewrapper.h"
namespace athena::io namespace athena::io {
{
FileWriter::FileWriter(std::string_view filename, bool overwrite, bool globalErr) FileWriter::FileWriter(std::string_view filename, bool overwrite, bool globalErr)
: m_fileHandle(0), : m_fileHandle(0), m_globalErr(globalErr) {
m_globalErr(globalErr)
{
m_filename = utility::utf8ToWide(filename); m_filename = utility::utf8ToWide(filename);
open(overwrite); open(overwrite);
} }
FileWriter::FileWriter(std::wstring_view filename, bool overwrite, bool globalErr) FileWriter::FileWriter(std::wstring_view filename, bool overwrite, bool globalErr)
: m_fileHandle(0), : m_fileHandle(0), m_globalErr(globalErr) {
m_globalErr(globalErr)
{
m_filename = filename; m_filename = filename;
open(overwrite); open(overwrite);
} }
FileWriter::~FileWriter() FileWriter::~FileWriter() {
{
if (isOpen()) if (isOpen())
close(); close();
} }
void FileWriter::open(bool overwrite) void FileWriter::open(bool overwrite) {
{
int attempt = 0; int attempt = 0;
do do {
{ if (overwrite) {
if (overwrite)
{
std::wstring tmpFilename = m_filename + L'~'; std::wstring tmpFilename = m_filename + L'~';
#if WINDOWS_STORE #if WINDOWS_STORE
m_fileHandle = CreateFile2(tmpFilename.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, m_fileHandle = CreateFile2(tmpFilename.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, CREATE_ALWAYS, nullptr);
CREATE_ALWAYS, nullptr);
#else #else
m_fileHandle = CreateFileW(tmpFilename.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, m_fileHandle = CreateFileW(tmpFilename.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS,
nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); FILE_ATTRIBUTE_NORMAL, nullptr);
#endif #endif
} } else {
else
{
#if WINDOWS_STORE #if WINDOWS_STORE
m_fileHandle = CreateFile2(m_filename.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, m_fileHandle = CreateFile2(m_filename.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, OPEN_ALWAYS, nullptr);
OPEN_ALWAYS, nullptr);
#else #else
m_fileHandle = CreateFileW(m_filename.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, m_fileHandle = CreateFileW(m_filename.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, OPEN_ALWAYS,
nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); FILE_ATTRIBUTE_NORMAL, nullptr);
#endif #endif
} }
} while (m_fileHandle == INVALID_HANDLE_VALUE && attempt++ < 100); } while (m_fileHandle == INVALID_HANDLE_VALUE && attempt++ < 100);
if (m_fileHandle == INVALID_HANDLE_VALUE) if (m_fileHandle == INVALID_HANDLE_VALUE) {
{
m_fileHandle = 0; m_fileHandle = 0;
if (m_globalErr) if (m_globalErr)
atError("Unable to open file '%s'", filename().c_str()); atError("Unable to open file '%s'", filename().c_str());
@ -66,10 +52,8 @@ void FileWriter::open(bool overwrite)
m_hasError = false; m_hasError = false;
} }
void FileWriter::close() void FileWriter::close() {
{ if (!m_fileHandle) {
if (!m_fileHandle)
{
if (m_globalErr) if (m_globalErr)
atError("Cannot close an unopened stream"); atError("Cannot close an unopened stream");
setError(); setError();
@ -84,10 +68,8 @@ void FileWriter::close()
MoveFileExW(tmpFilename.c_str(), m_filename.c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH); MoveFileExW(tmpFilename.c_str(), m_filename.c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH);
} }
void FileWriter::seek(atInt64 pos, SeekOrigin origin) void FileWriter::seek(atInt64 pos, SeekOrigin origin) {
{ if (!isOpen()) {
if (!isOpen())
{
if (m_globalErr) if (m_globalErr)
atError("Unable to seek in file, not open"); atError("Unable to seek in file, not open");
setError(); setError();
@ -96,31 +78,24 @@ void FileWriter::seek(atInt64 pos, SeekOrigin origin)
LARGE_INTEGER li; LARGE_INTEGER li;
li.QuadPart = pos; li.QuadPart = pos;
if (!SetFilePointerEx(m_fileHandle, li, nullptr, DWORD(origin))) if (!SetFilePointerEx(m_fileHandle, li, nullptr, DWORD(origin))) {
{
if (m_globalErr) if (m_globalErr)
atError("Unable to seek in file"); atError("Unable to seek in file");
setError(); setError();
} }
} }
atUint64 FileWriter::position() const atUint64 FileWriter::position() const {
{
LARGE_INTEGER li = {}; LARGE_INTEGER li = {};
LARGE_INTEGER res; LARGE_INTEGER res;
SetFilePointerEx(m_fileHandle, li, &res, FILE_CURRENT); SetFilePointerEx(m_fileHandle, li, &res, FILE_CURRENT);
return res.QuadPart; return res.QuadPart;
} }
atUint64 FileWriter::length() const atUint64 FileWriter::length() const { return utility::fileSize(m_filename); }
{
return utility::fileSize(m_filename);
}
void FileWriter::writeUBytes(const atUint8* data, atUint64 len) void FileWriter::writeUBytes(const atUint8* data, atUint64 len) {
{ if (!isOpen()) {
if (!isOpen())
{
if (m_globalErr) if (m_globalErr)
atError("File not open for writing"); atError("File not open for writing");
setError(); setError();
@ -129,12 +104,11 @@ void FileWriter::writeUBytes(const atUint8* data, atUint64 len)
DWORD ret = 0; DWORD ret = 0;
WriteFile(m_fileHandle, data, len, &ret, nullptr); WriteFile(m_fileHandle, data, len, &ret, nullptr);
if (ret != len) if (ret != len) {
{
if (m_globalErr) if (m_globalErr)
atError("Unable to write to stream"); atError("Unable to write to stream");
setError(); setError();
} }
} }
} // Athena } // namespace athena::io

View File

@ -4,10 +4,8 @@
#include <cstdarg> #include <cstdarg>
#include <cstdlib> #include <cstdlib>
std::ostream& operator<<(std::ostream& os, const athena::SeekOrigin& origin) std::ostream& operator<<(std::ostream& os, const athena::SeekOrigin& origin) {
{ switch (origin) {
switch (origin)
{
case athena::SeekOrigin::Begin: case athena::SeekOrigin::Begin:
os << "Begin"; os << "Begin";
break; break;
@ -24,11 +22,8 @@ std::ostream& operator<<(std::ostream& os, const athena::SeekOrigin& origin)
return os; return os;
} }
std::ostream& operator<<(std::ostream& os, const athena::Endian& endian) {
std::ostream& operator<<(std::ostream& os, const athena::Endian& endian) switch (endian) {
{
switch (endian)
{
case athena::Endian::Little: case athena::Endian::Little:
os << "LittleEndian"; os << "LittleEndian";
break; break;
@ -41,12 +36,10 @@ std::ostream& operator<<(std::ostream& os, const athena::Endian& endian)
return os; return os;
} }
static void __defaultExceptionHandler(athena::error::Level level, const char* file, const char* function, int line,
static void __defaultExceptionHandler(athena::error::Level level, const char* file, const char* function, int line, const char* fmt, ...) const char* fmt, ...) {
{
std::string levelStr; std::string levelStr;
switch (level) switch (level) {
{
case athena::error::Level::Warning: case athena::error::Level::Warning:
levelStr = "[WARNING] "; levelStr = "[WARNING] ";
break; break;
@ -56,7 +49,8 @@ static void __defaultExceptionHandler(athena::error::Level level, const char* fi
case athena::error::Level::Fatal: case athena::error::Level::Fatal:
levelStr = "[FATAL ] "; levelStr = "[FATAL ] ";
break; break;
default: break; default:
break;
} }
va_list vl; va_list vl;
@ -68,14 +62,9 @@ static void __defaultExceptionHandler(athena::error::Level level, const char* fi
static atEXCEPTION_HANDLER g_atExceptionHandler = __defaultExceptionHandler; static atEXCEPTION_HANDLER g_atExceptionHandler = __defaultExceptionHandler;
atEXCEPTION_HANDLER atGetExceptionHandler() atEXCEPTION_HANDLER atGetExceptionHandler() { return g_atExceptionHandler; }
{
return g_atExceptionHandler;
}
void atSetExceptionHandler(atEXCEPTION_HANDLER func) {
void atSetExceptionHandler(atEXCEPTION_HANDLER func)
{
if (func) if (func)
g_atExceptionHandler = func; g_atExceptionHandler = func;
else else

View File

@ -1,22 +1,17 @@
#include "athena/MCFile.hpp" #include "athena/MCFile.hpp"
namespace athena namespace athena {
{
const char MCFile::VERSION_EU_JP[33] = "AGBZELDA:THE MINISH CAP:ZELDA 3\0"; const char MCFile::VERSION_EU_JP[33] = "AGBZELDA:THE MINISH CAP:ZELDA 3\0";
const char MCFile::VERSION_US[33] = "AGBZELDA:THE MINISH CAP:ZELDA 5\0"; const char MCFile::VERSION_US[33] = "AGBZELDA:THE MINISH CAP:ZELDA 5\0";
MCFile::MCFile() MCFile::MCFile() {}
{
}
// TODO: Rewrite this to be more optimized, the current solution takes quite a few cycles // TODO: Rewrite this to be more optimized, the current solution takes quite a few cycles
atUint8* reverse(atUint8* data, atUint32 length) atUint8* reverse(atUint8* data, atUint32 length) {
{
atUint32 a = 0; atUint32 a = 0;
atUint32 swap; atUint32 swap;
for (; a < --length; a++) for (; a < --length; a++) {
{
swap = data[a]; swap = data[a];
data[a] = data[length]; data[a] = data[length];
data[length] = swap; data[length] = swap;
@ -25,13 +20,11 @@ atUint8* reverse(atUint8* data, atUint32 length)
return data; return data;
} }
atUint8* MCFile::unscramble(atUint8* data, atUint64 length) atUint8* MCFile::unscramble(atUint8* data, atUint64 length) {
{
if (!data) if (!data)
return nullptr; return nullptr;
for (atUint32 i = 0; i < length; i += 8) for (atUint32 i = 0; i < length; i += 8) {
{
atUint32 block1 = *(atUint32*)reverse((data + i), 4); atUint32 block1 = *(atUint32*)reverse((data + i), 4);
atUint32 block2 = *(atUint32*)reverse((data + i + 4), 4); atUint32 block2 = *(atUint32*)reverse((data + i + 4), 4);
*(atUint32*)(data + i) = block2; *(atUint32*)(data + i) = block2;
@ -41,4 +34,4 @@ atUint8* MCFile::unscramble(atUint8* data, atUint64 length)
return data; return data;
} }
} // zelda } // namespace athena

View File

@ -1,24 +1,15 @@
#include "athena/MCFileReader.hpp" #include "athena/MCFileReader.hpp"
#include "athena/MCFile.hpp" #include "athena/MCFile.hpp"
namespace athena namespace athena {
{
namespace io namespace io {
{
static const atUint32 SCRAMBLE_VALUE = 0x5A424741; static const atUint32 SCRAMBLE_VALUE = 0x5A424741;
MCFileReader::MCFileReader(atUint8* data, atUint64 length) MCFileReader::MCFileReader(atUint8* data, atUint64 length) : MemoryCopyReader(data, length) {}
: MemoryCopyReader(data, length)
{
}
MCFileReader::MCFileReader(const std::string& filename) MCFileReader::MCFileReader(const std::string& filename) : MemoryCopyReader(filename) {}
: MemoryCopyReader(filename)
{
}
MCFile* MCFileReader::readFile() MCFile* MCFileReader::readFile() {
{
bool isScrambled = readUint32() != SCRAMBLE_VALUE; bool isScrambled = readUint32() != SCRAMBLE_VALUE;
m_position = 0; m_position = 0;
@ -28,6 +19,5 @@ MCFile* MCFileReader::readFile()
return nullptr; return nullptr;
} }
} // namespace io
} // io } // namespace athena
} // zelda

View File

@ -1,23 +1,15 @@
#include "athena/MCFileWriter.hpp" #include "athena/MCFileWriter.hpp"
namespace athena::io namespace athena::io {
{
MCFileWriter::MCFileWriter(atUint8* data, atUint64 length) MCFileWriter::MCFileWriter(atUint8* data, atUint64 length) : MemoryCopyWriter(data, length) {}
: MemoryCopyWriter(data, length)
{
}
MCFileWriter::MCFileWriter(const std::string& filename) MCFileWriter::MCFileWriter(const std::string& filename) : MemoryCopyWriter(filename) {}
: MemoryCopyWriter(filename)
{
}
// TODO: Check the implementation, it seems to work fine, however it's not exactly correct, // TODO: Check the implementation, it seems to work fine, however it's not exactly correct,
// looking at the disassembly, MC seems to do some weird checking that isn't being done with this solution // looking at the disassembly, MC seems to do some weird checking that isn't being done with this solution
// need to figure out what it's doing and whether it's relevant to the checksum. // need to figure out what it's doing and whether it's relevant to the checksum.
atUint16 MCFileWriter::calculateSlotChecksum(atUint32 game) atUint16 MCFileWriter::calculateSlotChecksum(atUint32 game) {
{
atUint16 first = calculateChecksum((m_data + 0x34 + (0x10 * game)), 4); atUint16 first = calculateChecksum((m_data + 0x34 + (0x10 * game)), 4);
atUint16 second = calculateChecksum((m_data + 0x80 + (0x500 * game)), 0x500); atUint16 second = calculateChecksum((m_data + 0x80 + (0x500 * game)), 0x500);
@ -30,13 +22,11 @@ atUint16 MCFileWriter::calculateSlotChecksum(atUint32 game)
return result; return result;
} }
atUint16 MCFileWriter::calculateChecksum(atUint8* data, atUint32 length) atUint16 MCFileWriter::calculateChecksum(atUint8* data, atUint32 length) {
{
atUint16 sum = 0; atUint16 sum = 0;
int i = length; int i = length;
for (atUint32 j = 0; j < length; j += 2) for (atUint32 j = 0; j < length; j += 2) {
{
sum += *(atUint16*)(data + j) ^ i; sum += *(atUint16*)(data + j) ^ i;
i -= 2; i -= 2;
} }
@ -46,4 +36,4 @@ atUint16 MCFileWriter::calculateChecksum(atUint8* data, atUint32 length)
return sum; return sum;
} }
} // zelda } // namespace athena::io

View File

@ -1,11 +1,8 @@
#include "athena/MCSlot.hpp" #include "athena/MCSlot.hpp"
namespace athena namespace athena {
{
MCSlot::MCSlot(std::unique_ptr<atUint8[]>&& data, atUint32 length) MCSlot::MCSlot(std::unique_ptr<atUint8[]>&& data, atUint32 length)
: ZQuestFile(ZQuestFile::MC, Endian::Little, std::move(data), length) : ZQuestFile(ZQuestFile::MC, Endian::Little, std::move(data), length) {}
{
}
} // Athena } // namespace athena

View File

@ -14,17 +14,10 @@
#undef min #undef min
#undef max #undef max
namespace athena::io namespace athena::io {
{
MemoryReader::MemoryReader(const void* data, atUint64 length, bool takeOwnership, bool globalErr) MemoryReader::MemoryReader(const void* data, atUint64 length, bool takeOwnership, bool globalErr)
: m_data(data), : m_data(data), m_length(length), m_position(0), m_owns(takeOwnership), m_globalErr(globalErr) {
m_length(length), if (!data) {
m_position(0),
m_owns(takeOwnership),
m_globalErr(globalErr)
{
if (!data)
{
if (m_globalErr) if (m_globalErr)
atError("data cannot be NULL"); atError("data cannot be NULL");
setError(); setError();
@ -32,17 +25,13 @@ MemoryReader::MemoryReader(const void* data, atUint64 length, bool takeOwnership
} }
} }
MemoryReader::~MemoryReader() MemoryReader::~MemoryReader() {
{
if (m_owns) if (m_owns)
delete[] reinterpret_cast<const atUint8*>(m_data); delete[] reinterpret_cast<const atUint8*>(m_data);
} }
MemoryCopyReader::MemoryCopyReader(const void* data, atUint64 length) MemoryCopyReader::MemoryCopyReader(const void* data, atUint64 length) : MemoryReader(data, length, false) {
: MemoryReader(data, length, false) if (!data) {
{
if (!data)
{
if (m_globalErr) if (m_globalErr)
atError("data cannot be NULL"); atError("data cannot be NULL");
setError(); setError();
@ -54,13 +43,10 @@ MemoryCopyReader::MemoryCopyReader(const void* data, atUint64 length)
memmove(m_dataCopy.get(), data, m_length); memmove(m_dataCopy.get(), data, m_length);
} }
void MemoryReader::seek(atInt64 position, SeekOrigin origin) void MemoryReader::seek(atInt64 position, SeekOrigin origin) {
{ switch (origin) {
switch (origin)
{
case SeekOrigin::Begin: case SeekOrigin::Begin:
if ((position < 0 || (atInt64)position > (atInt64)m_length)) if ((position < 0 || (atInt64)position > (atInt64)m_length)) {
{
if (m_globalErr) if (m_globalErr)
atFatal("Position %0.8X outside stream bounds ", position); atFatal("Position %0.8X outside stream bounds ", position);
m_position = m_length; m_position = m_length;
@ -72,8 +58,7 @@ void MemoryReader::seek(atInt64 position, SeekOrigin origin)
break; break;
case SeekOrigin::Current: case SeekOrigin::Current:
if ((((atInt64)m_position + position) < 0 || (m_position + position) > m_length)) if ((((atInt64)m_position + position) < 0 || (m_position + position) > m_length)) {
{
if (m_globalErr) if (m_globalErr)
atFatal("Position %0.8X outside stream bounds ", position); atFatal("Position %0.8X outside stream bounds ", position);
m_position = m_length; m_position = m_length;
@ -85,8 +70,7 @@ void MemoryReader::seek(atInt64 position, SeekOrigin origin)
break; break;
case SeekOrigin::End: case SeekOrigin::End:
if ((((atInt64)m_length - position < 0) || (m_length - position) > m_length)) if ((((atInt64)m_length - position < 0) || (m_length - position) > m_length)) {
{
if (m_globalErr) if (m_globalErr)
atFatal("Position %0.8X outside stream bounds ", position); atFatal("Position %0.8X outside stream bounds ", position);
m_position = m_length; m_position = m_length;
@ -99,8 +83,7 @@ void MemoryReader::seek(atInt64 position, SeekOrigin origin)
} }
} }
void MemoryReader::setData(const atUint8* data, atUint64 length, bool takeOwnership) void MemoryReader::setData(const atUint8* data, atUint64 length, bool takeOwnership) {
{
if (m_owns) if (m_owns)
delete[] static_cast<const atUint8*>(m_data); delete[] static_cast<const atUint8*>(m_data);
m_data = (atUint8*)data; m_data = (atUint8*)data;
@ -109,8 +92,7 @@ void MemoryReader::setData(const atUint8* data, atUint64 length, bool takeOwners
m_owns = takeOwnership; m_owns = takeOwnership;
} }
void MemoryCopyReader::setData(const atUint8* data, atUint64 length) void MemoryCopyReader::setData(const atUint8* data, atUint64 length) {
{
m_dataCopy.reset(new atUint8[length]); m_dataCopy.reset(new atUint8[length]);
m_data = m_dataCopy.get(); m_data = m_dataCopy.get();
memmove(m_dataCopy.get(), data, length); memmove(m_dataCopy.get(), data, length);
@ -118,18 +100,15 @@ void MemoryCopyReader::setData(const atUint8* data, atUint64 length)
m_position = 0; m_position = 0;
} }
atUint8* MemoryReader::data() const atUint8* MemoryReader::data() const {
{
atUint8* ret = new atUint8[m_length]; atUint8* ret = new atUint8[m_length];
memset(ret, 0, m_length); memset(ret, 0, m_length);
memmove(ret, m_data, m_length); memmove(ret, m_data, m_length);
return ret; return ret;
} }
atUint64 MemoryReader::readUBytesToBuf(void* buf, atUint64 length) atUint64 MemoryReader::readUBytesToBuf(void* buf, atUint64 length) {
{ if (m_position >= m_length) {
if (m_position >= m_length)
{
if (m_globalErr) if (m_globalErr)
atFatal("Position %0.8X outside stream bounds ", m_position); atFatal("Position %0.8X outside stream bounds ", m_position);
m_position = m_length; m_position = m_length;
@ -143,14 +122,12 @@ atUint64 MemoryReader::readUBytesToBuf(void* buf, atUint64 length)
return length; return length;
} }
void MemoryCopyReader::loadData() void MemoryCopyReader::loadData() {
{
FILE* in; FILE* in;
atUint64 length; atUint64 length;
in = fopen(m_filepath.c_str(), "rb"); in = fopen(m_filepath.c_str(), "rb");
if (!in) if (!in) {
{
if (m_globalErr) if (m_globalErr)
atError("Unable to open file '%s'", m_filepath.c_str()); atError("Unable to open file '%s'", m_filepath.c_str());
setError(); setError();
@ -166,32 +143,27 @@ void MemoryCopyReader::loadData()
atUint64 done = 0; atUint64 done = 0;
atUint64 blocksize = BLOCKSZ; atUint64 blocksize = BLOCKSZ;
do do {
{
if (blocksize > length - done) if (blocksize > length - done)
blocksize = length - done; blocksize = length - done;
atInt64 ret = fread(m_dataCopy.get() + done, 1, blocksize, in); atInt64 ret = fread(m_dataCopy.get() + done, 1, blocksize, in);
if (ret < 0) if (ret < 0) {
{
if (m_globalErr) if (m_globalErr)
atError("Error reading data from disk"); atError("Error reading data from disk");
setError(); setError();
return; return;
} } else if (ret == 0)
else if (ret == 0)
break; break;
done += ret; done += ret;
} while (done < length);
}
while (done < length);
fclose(in); fclose(in);
m_length = length; m_length = length;
m_position = 0; m_position = 0;
} }
} } // namespace athena::io

View File

@ -9,40 +9,31 @@
#include <malloc.h> #include <malloc.h>
#endif // HW_RVL #endif // HW_RVL
namespace athena::io namespace athena::io {
{
MemoryWriter::MemoryWriter(atUint8* data, atUint64 length, bool takeOwnership) MemoryWriter::MemoryWriter(atUint8* data, atUint64 length, bool takeOwnership)
: m_data((atUint8*)data), : m_data((atUint8*)data), m_length(length), m_position(0), m_bufferOwned(takeOwnership) {
m_length(length), if (!data) {
m_position(0),
m_bufferOwned(takeOwnership)
{
if (!data)
{
atError("data cannot be NULL"); atError("data cannot be NULL");
setError(); setError();
return; return;
} }
} }
MemoryWriter::~MemoryWriter() MemoryWriter::~MemoryWriter() {
{
if (m_bufferOwned) if (m_bufferOwned)
delete m_data; delete m_data;
m_data = nullptr; m_data = nullptr;
m_length = 0; m_length = 0;
} }
MemoryCopyWriter::MemoryCopyWriter(atUint8* data, atUint64 length) MemoryCopyWriter::MemoryCopyWriter(atUint8* data, atUint64 length) {
{
m_data = data; m_data = data;
m_length = length; m_length = length;
m_position = 0; m_position = 0;
m_bufferOwned = false; m_bufferOwned = false;
if (length == 0) if (length == 0) {
{
atError("length cannot be 0"); atError("length cannot be 0");
setError(); setError();
return; return;
@ -53,8 +44,7 @@ MemoryCopyWriter::MemoryCopyWriter(atUint8* data, atUint64 length)
memmove(m_data, data, length); memmove(m_data, data, length);
} }
MemoryCopyWriter::MemoryCopyWriter(std::string_view filename) MemoryCopyWriter::MemoryCopyWriter(std::string_view filename) {
{
m_filepath = filename; m_filepath = filename;
m_length = 0x10; m_length = 0x10;
m_position = 0; m_position = 0;
@ -62,28 +52,23 @@ MemoryCopyWriter::MemoryCopyWriter(std::string_view filename)
m_data = m_dataCopy.get(); m_data = m_dataCopy.get();
m_bufferOwned = false; m_bufferOwned = false;
if (!m_data) if (!m_data) {
{
atError("Could not allocate memory!"); atError("Could not allocate memory!");
setError(); setError();
return; return;
} }
} }
void MemoryWriter::seek(atInt64 position, SeekOrigin origin) void MemoryWriter::seek(atInt64 position, SeekOrigin origin) {
{ switch (origin) {
switch (origin)
{
case SeekOrigin::Begin: case SeekOrigin::Begin:
if (position < 0) if (position < 0) {
{
atError("Position outside stream bounds"); atError("Position outside stream bounds");
setError(); setError();
return; return;
} }
if ((atUint64)position > m_length) if ((atUint64)position > m_length) {
{
atError("data exceeds available buffer space"); atError("data exceeds available buffer space");
setError(); setError();
return; return;
@ -93,15 +78,13 @@ void MemoryWriter::seek(atInt64 position, SeekOrigin origin)
break; break;
case SeekOrigin::Current: case SeekOrigin::Current:
if ((((atInt64)m_position + position) < 0)) if ((((atInt64)m_position + position) < 0)) {
{
atError("Position outside stream bounds"); atError("Position outside stream bounds");
setError(); setError();
return; return;
} }
if (m_position + position > m_length) if (m_position + position > m_length) {
{
atError("data exceeds available buffer space"); atError("data exceeds available buffer space");
setError(); setError();
return; return;
@ -111,15 +94,13 @@ void MemoryWriter::seek(atInt64 position, SeekOrigin origin)
break; break;
case SeekOrigin::End: case SeekOrigin::End:
if (((atInt64)m_length - position) < 0) if (((atInt64)m_length - position) < 0) {
{
atError("Position outside stream bounds"); atError("Position outside stream bounds");
setError(); setError();
return; return;
} }
if ((atUint64)position > m_length) if ((atUint64)position > m_length) {
{
atError("data exceeds available buffer space"); atError("data exceeds available buffer space");
setError(); setError();
return; return;
@ -130,13 +111,10 @@ void MemoryWriter::seek(atInt64 position, SeekOrigin origin)
} }
} }
void MemoryCopyWriter::seek(atInt64 position, SeekOrigin origin) void MemoryCopyWriter::seek(atInt64 position, SeekOrigin origin) {
{ switch (origin) {
switch (origin)
{
case SeekOrigin::Begin: case SeekOrigin::Begin:
if (position < 0) if (position < 0) {
{
atError("Position outside stream bounds"); atError("Position outside stream bounds");
setError(); setError();
return; return;
@ -149,8 +127,7 @@ void MemoryCopyWriter::seek(atInt64 position, SeekOrigin origin)
break; break;
case SeekOrigin::Current: case SeekOrigin::Current:
if ((((atInt64)m_position + position) < 0)) if ((((atInt64)m_position + position) < 0)) {
{
atError("Position outside stream bounds"); atError("Position outside stream bounds");
setError(); setError();
return; return;
@ -163,8 +140,7 @@ void MemoryCopyWriter::seek(atInt64 position, SeekOrigin origin)
break; break;
case SeekOrigin::End: case SeekOrigin::End:
if (((atInt64)m_length - position) < 0) if (((atInt64)m_length - position) < 0) {
{
atError("Position outside stream bounds"); atError("Position outside stream bounds");
setError(); setError();
return; return;
@ -178,8 +154,7 @@ void MemoryCopyWriter::seek(atInt64 position, SeekOrigin origin)
} }
} }
void MemoryWriter::setData(atUint8* data, atUint64 length, bool takeOwnership) void MemoryWriter::setData(atUint8* data, atUint64 length, bool takeOwnership) {
{
if (m_bufferOwned) if (m_bufferOwned)
delete m_data; delete m_data;
@ -189,8 +164,7 @@ void MemoryWriter::setData(atUint8* data, atUint64 length, bool takeOwnership)
m_bufferOwned = takeOwnership; m_bufferOwned = takeOwnership;
} }
void MemoryCopyWriter::setData(const atUint8* data, atUint64 length) void MemoryCopyWriter::setData(const atUint8* data, atUint64 length) {
{
m_dataCopy.reset(new atUint8[length]); m_dataCopy.reset(new atUint8[length]);
m_data = m_dataCopy.get(); m_data = m_dataCopy.get();
memmove(m_data, data, length); memmove(m_data, data, length);
@ -199,19 +173,15 @@ void MemoryCopyWriter::setData(const atUint8* data, atUint64 length)
m_bufferOwned = false; m_bufferOwned = false;
} }
atUint8* MemoryWriter::data() const atUint8* MemoryWriter::data() const {
{
atUint8* ret = new atUint8[m_length]; atUint8* ret = new atUint8[m_length];
memset(ret, 0, m_length); memset(ret, 0, m_length);
memmove(ret, m_data, m_length); memmove(ret, m_data, m_length);
return ret; return ret;
} }
void MemoryWriter::save(std::string_view filename) {
void MemoryWriter::save(std::string_view filename) if (filename.empty() && m_filepath.empty()) {
{
if (filename.empty() && m_filepath.empty())
{
atError("No file specified, cannot save."); atError("No file specified, cannot save.");
setError(); setError();
return; return;
@ -222,8 +192,7 @@ void MemoryWriter::save(std::string_view filename)
FILE* out = fopen(m_filepath.c_str(), "wb"); FILE* out = fopen(m_filepath.c_str(), "wb");
if (!out) if (!out) {
{
atError("Unable to open file '%s'", m_filepath.c_str()); atError("Unable to open file '%s'", m_filepath.c_str());
setError(); setError();
return; return;
@ -232,40 +201,33 @@ void MemoryWriter::save(std::string_view filename)
atUint64 done = 0; atUint64 done = 0;
atUint64 blocksize = BLOCKSZ; atUint64 blocksize = BLOCKSZ;
do do {
{
if (blocksize > m_length - done) if (blocksize > m_length - done)
blocksize = m_length - done; blocksize = m_length - done;
atInt64 ret = fwrite(m_data + done, 1, blocksize, out); atInt64 ret = fwrite(m_data + done, 1, blocksize, out);
if (ret < 0) if (ret < 0) {
{
atError("Error writing data to disk"); atError("Error writing data to disk");
setError(); setError();
return; return;
} } else if (ret == 0)
else if (ret == 0)
break; break;
done += blocksize; done += blocksize;
} } while (done < m_length);
while (done < m_length);
fclose(out); fclose(out);
} }
void MemoryWriter::writeUBytes(const atUint8* data, atUint64 length) void MemoryWriter::writeUBytes(const atUint8* data, atUint64 length) {
{ if (!data) {
if (!data)
{
atError("data cannnot be NULL"); atError("data cannnot be NULL");
setError(); setError();
return; return;
} }
if (m_position + length > m_length) if (m_position + length > m_length) {
{
atError("data length exceeds available buffer space"); atError("data length exceeds available buffer space");
setError(); setError();
return; return;
@ -276,10 +238,8 @@ void MemoryWriter::writeUBytes(const atUint8* data, atUint64 length)
m_position += length; m_position += length;
} }
void MemoryCopyWriter::writeUBytes(const atUint8* data, atUint64 length) void MemoryCopyWriter::writeUBytes(const atUint8* data, atUint64 length) {
{ if (!data) {
if (!data)
{
atError("data cannnot be NULL"); atError("data cannnot be NULL");
setError(); setError();
return; return;
@ -293,10 +253,8 @@ void MemoryCopyWriter::writeUBytes(const atUint8* data, atUint64 length)
m_position += length; m_position += length;
} }
void MemoryCopyWriter::resize(atUint64 newSize) void MemoryCopyWriter::resize(atUint64 newSize) {
{ if (newSize < m_length) {
if (newSize < m_length)
{
atError("New size cannot be less to the old size."); atError("New size cannot be less to the old size.");
return; return;
} }
@ -314,4 +272,4 @@ void MemoryCopyWriter::resize(atUint64 newSize)
m_length = newSize; m_length = newSize;
} }
} // Athena } // namespace athena::io

View File

@ -3,13 +3,9 @@
#include "athena/FileNotFoundException.hpp" #include "athena/FileNotFoundException.hpp"
#include "athena/IOException.hpp" #include "athena/IOException.hpp"
namespace athena::io namespace athena::io {
{
PHYSFSFileReader::PHYSFSFileReader(const std::string& path) PHYSFSFileReader::PHYSFSFileReader(const std::string& path) : m_path(path), m_endian(Endian::LittleEndian) {
: m_path(path),
m_endian(Endian::LittleEndian)
{
if (!PHYSFS_exists(m_path.c_str())) if (!PHYSFS_exists(m_path.c_str()))
THROW_FILE_NOT_FOUND_EXCEPTION(path); THROW_FILE_NOT_FOUND_EXCEPTION(path);
@ -17,32 +13,18 @@ PHYSFSFileReader::PHYSFSFileReader(const std::string& path)
m_length = PHYSFS_fileLength(m_handle); m_length = PHYSFS_fileLength(m_handle);
} }
atUint8* PHYSFSFileReader::data() atUint8* PHYSFSFileReader::data() { return readUBytes(length()); }
{
return readUBytes(length());
}
atUint64 PHYSFSFileReader::length() const atUint64 PHYSFSFileReader::length() const { return m_length; }
{
return m_length;
}
atUint64 PHYSFSFileReader::position() const atUint64 PHYSFSFileReader::position() const { return PHYSFS_tell(m_handle); }
{
return PHYSFS_tell(m_handle);
}
bool PHYSFSFileReader::isOpen() const bool PHYSFSFileReader::isOpen() const { return (m_handle != nullptr); }
{
return (m_handle != nullptr);
}
void PHYSFSFileReader::seek(atInt64 position, SeekOrigin origin) void PHYSFSFileReader::seek(atInt64 position, SeekOrigin origin) {
{
atInt64 curPos = PHYSFS_tell(m_handle); atInt64 curPos = PHYSFS_tell(m_handle);
switch (origin) switch (origin) {
{
case SeekOrigin::Begin: case SeekOrigin::Begin:
if ((position < 0 || (atInt64)position > (atInt64)m_length)) if ((position < 0 || (atInt64)position > (atInt64)m_length))
THROW_IO_EXCEPTION("Position %0.16X outside stream bounds ", position); THROW_IO_EXCEPTION("Position %0.16X outside stream bounds ", position);
@ -66,8 +48,7 @@ void PHYSFSFileReader::seek(atInt64 position, SeekOrigin origin)
} }
} }
atUint8 PHYSFSFileReader::readUByte() atUint8 PHYSFSFileReader::readUByte() {
{
atUint8 val; atUint8 val;
if (!PHYSFS_read(m_handle, &val, 1, 1)) if (!PHYSFS_read(m_handle, &val, 1, 1))
@ -76,13 +57,9 @@ atUint8 PHYSFSFileReader::readUByte()
return val; return val;
} }
atInt8 PHYSFSFileReader::readByte() atInt8 PHYSFSFileReader::readByte() { return readUByte(); }
{
return readUByte();
}
atUint8* PHYSFSFileReader::readUBytes(atUint64 length) atUint8* PHYSFSFileReader::readUBytes(atUint64 length) {
{
atUint8* data = new atUint8[length]; atUint8* data = new atUint8[length];
if (PHYSFS_read(m_handle, data, 1, length) == length) if (PHYSFS_read(m_handle, data, 1, length) == length)
@ -92,111 +69,66 @@ atUint8* PHYSFSFileReader::readUBytes(atUint64 length)
THROW_IO_EXCEPTION("Position outside stream bounds"); THROW_IO_EXCEPTION("Position outside stream bounds");
} }
atInt8* PHYSFSFileReader::readBytes(atUint64 length) atInt8* PHYSFSFileReader::readBytes(atUint64 length) { return (atInt8*)readUBytes(length); }
{
return (atInt8*)readUBytes(length);
}
atUint16 PHYSFSFileReader::readUint16() atUint16 PHYSFSFileReader::readUint16() {
{
atUint16 val; atUint16 val;
if (m_endian == Endian::BigEndian) if (m_endian == Endian::BigEndian) {
{
if (!PHYSFS_readUBE16(m_handle, &val)) if (!PHYSFS_readUBE16(m_handle, &val))
THROW_IO_EXCEPTION("Position outside stream bounds"); THROW_IO_EXCEPTION("Position outside stream bounds");
} } else if (!PHYSFS_readULE16(m_handle, &val))
else if (!PHYSFS_readULE16(m_handle, &val))
THROW_IO_EXCEPTION("Position outside stream bounds"); THROW_IO_EXCEPTION("Position outside stream bounds");
return val; return val;
} }
atInt16 PHYSFSFileReader::readInt16() atInt16 PHYSFSFileReader::readInt16() { return readUint16(); }
{
return readUint16();
}
atUint32 PHYSFSFileReader::readUint32() atUint32 PHYSFSFileReader::readUint32() {
{
atUint32 val; atUint32 val;
if (m_endian == Endian::BigEndian) if (m_endian == Endian::BigEndian) {
{
if (!PHYSFS_readUBE32(m_handle, &val)) if (!PHYSFS_readUBE32(m_handle, &val))
THROW_IO_EXCEPTION("Position outside stream bounds"); THROW_IO_EXCEPTION("Position outside stream bounds");
} } else if (!PHYSFS_readULE32(m_handle, &val))
else if (!PHYSFS_readULE32(m_handle, &val))
THROW_IO_EXCEPTION("Position outside stream bounds"); THROW_IO_EXCEPTION("Position outside stream bounds");
return val; return val;
} }
atInt32 PHYSFSFileReader::readInt32() atInt32 PHYSFSFileReader::readInt32() { return readUint32(); }
{
return readUint32();
}
atUint64 PHYSFSFileReader::readUint64() atUint64 PHYSFSFileReader::readUint64() {
{
atUint64 val; atUint64 val;
if (m_endian == Endian::BigEndian) if (m_endian == Endian::BigEndian) {
{
if (!PHYSFS_readUBE64(m_handle, &val)) if (!PHYSFS_readUBE64(m_handle, &val))
THROW_IO_EXCEPTION("Position outside stream bounds"); THROW_IO_EXCEPTION("Position outside stream bounds");
} } else if (!PHYSFS_readUBE64(m_handle, &val))
else if (!PHYSFS_readUBE64(m_handle, &val))
THROW_IO_EXCEPTION("Position outside stream bounds"); THROW_IO_EXCEPTION("Position outside stream bounds");
return val; return val;
} }
atInt64 PHYSFSFileReader::readInt64() atInt64 PHYSFSFileReader::readInt64() { return readUint64(); }
{
return readUint64();
}
double PHYSFSFileReader::readDouble() double PHYSFSFileReader::readDouble() { return static_cast<double>(readUint64()); }
{
return static_cast<double>(readUint64());
}
float PHYSFSFileReader::readFloat() float PHYSFSFileReader::readFloat() { return static_cast<float>(readUint32()); }
{
return static_cast<float>(readUint32());
}
bool PHYSFSFileReader::readBool() bool PHYSFSFileReader::readBool() { return (readByte() != 0); }
{
return (readByte() != 0);
}
bool PHYSFSFileReader::atEnd() const bool PHYSFSFileReader::atEnd() const { return PHYSFS_eof(m_handle); }
{
return PHYSFS_eof(m_handle);
}
void PHYSFSFileReader::setEndian(Endian endian) void PHYSFSFileReader::setEndian(Endian endian) { m_endian = endian; }
{
m_endian = endian;
}
Endian PHYSFSFileReader::endian() const Endian PHYSFSFileReader::endian() const { return m_endian; }
{
return m_endian;
}
bool PHYSFSFileReader::isBigEndian() const bool PHYSFSFileReader::isBigEndian() const { return m_endian == Endian::BigEndian; }
{
return m_endian == Endian::BigEndian;
}
bool PHYSFSFileReader::isLittleEndian() const bool PHYSFSFileReader::isLittleEndian() const { return m_endian == Endian::LittleEndian; }
{
return m_endian == Endian::LittleEndian;
}
} } // namespace athena::io
#endif #endif

View File

@ -1,26 +1,15 @@
#include "athena/SkywardSwordFile.hpp" #include "athena/SkywardSwordFile.hpp"
#include "athena/SkywardSwordQuest.hpp" #include "athena/SkywardSwordQuest.hpp"
namespace athena namespace athena {
{
SkywardSwordFile::SkywardSwordFile() SkywardSwordFile::SkywardSwordFile() : m_numQuests(0) {}
: m_numQuests(0)
{
}
SkywardSwordFile::SkywardSwordFile(std::vector<SkywardSwordQuest*> quests) SkywardSwordFile::SkywardSwordFile(std::vector<SkywardSwordQuest*> quests) : m_numQuests(0) { m_quests = quests; }
: m_numQuests(0)
{
m_quests = quests;
}
SkywardSwordFile::~SkywardSwordFile() SkywardSwordFile::~SkywardSwordFile() {}
{
}
void SkywardSwordFile::addQuest(athena::SkywardSwordQuest* q) void SkywardSwordFile::addQuest(athena::SkywardSwordQuest* q) {
{
// Do not allow more than 3 quests // Do not allow more than 3 quests
if (m_quests.size() >= 3) if (m_quests.size() >= 3)
return; return;
@ -28,10 +17,8 @@ void SkywardSwordFile::addQuest(athena::SkywardSwordQuest* q)
m_quests.push_back(q); m_quests.push_back(q);
} }
SkywardSwordQuest* SkywardSwordFile::quest(atUint32 id) SkywardSwordQuest* SkywardSwordFile::quest(atUint32 id) {
{ if (id > m_quests.size() - 1) {
if (id > m_quests.size() - 1)
{
atWarning("index out of range"); atWarning("index out of range");
return nullptr; return nullptr;
} }
@ -39,20 +26,10 @@ SkywardSwordQuest* SkywardSwordFile::quest(atUint32 id)
return m_quests[id]; return m_quests[id];
} }
std::vector<SkywardSwordQuest*> SkywardSwordFile::questList() const std::vector<SkywardSwordQuest*> SkywardSwordFile::questList() const { return m_quests; }
{
return m_quests;
}
void SkywardSwordFile::setRegion(Region region) void SkywardSwordFile::setRegion(Region region) { m_region = region; }
{
m_region = region;
}
Region SkywardSwordFile::region() const Region SkywardSwordFile::region() const { return m_region; }
{
return m_region;
}
} // namespace athena
} // zelda

View File

@ -3,35 +3,27 @@
#include "athena/SkywardSwordQuest.hpp" #include "athena/SkywardSwordQuest.hpp"
#include <iostream> #include <iostream>
namespace athena::io namespace athena::io {
{
SkywardSwordFileReader::SkywardSwordFileReader(atUint8* data, atUint64 length) SkywardSwordFileReader::SkywardSwordFileReader(atUint8* data, atUint64 length) : MemoryCopyReader(data, length) {
: MemoryCopyReader(data, length)
{
setEndian(Endian::Big); setEndian(Endian::Big);
} }
SkywardSwordFileReader::SkywardSwordFileReader(const std::string& filename) SkywardSwordFileReader::SkywardSwordFileReader(const std::string& filename) : MemoryCopyReader(filename) {
: MemoryCopyReader(filename)
{
setEndian(Endian::Big); setEndian(Endian::Big);
} }
SkywardSwordFile* SkywardSwordFileReader::read() SkywardSwordFile* SkywardSwordFileReader::read() {
{
SkywardSwordFile* file = NULL; SkywardSwordFile* file = NULL;
if (length() != 0xFBE0) if (length() != 0xFBE0) {
{
atError("File not the expected size of 0xFBE0"); atError("File not the expected size of 0xFBE0");
return nullptr; return nullptr;
} }
atUint32 magic = readUint32(); atUint32 magic = readUint32();
if (magic != SkywardSwordFile::USMagic && magic != SkywardSwordFile::JAMagic && magic != SkywardSwordFile::EUMagic) if (magic != SkywardSwordFile::USMagic && magic != SkywardSwordFile::JAMagic && magic != SkywardSwordFile::EUMagic) {
{
atError("Not a valid Skyward Sword save file"); atError("Not a valid Skyward Sword save file");
return nullptr; return nullptr;
} }
@ -39,18 +31,18 @@ SkywardSwordFile* SkywardSwordFileReader::read()
seek(0x01C, SeekOrigin::Begin); seek(0x01C, SeekOrigin::Begin);
atUint32 headerSize = readUint32(); // Seems to be (headerSize - 1) atUint32 headerSize = readUint32(); // Seems to be (headerSize - 1)
if (headerSize != 0x1D) if (headerSize != 0x1D) {
{
atError("Invalid header size, Corrupted data?"); atError("Invalid header size, Corrupted data?");
return nullptr; return nullptr;
} }
// Time to read in each slot // Time to read in each slot
file = new SkywardSwordFile; file = new SkywardSwordFile;
file->setRegion((magic == SkywardSwordFile::USMagic ? Region::NTSC : (magic == SkywardSwordFile::JAMagic ? Region::NTSCJ : Region::PAL))); file->setRegion((magic == SkywardSwordFile::USMagic
? Region::NTSC
: (magic == SkywardSwordFile::JAMagic ? Region::NTSCJ : Region::PAL)));
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++) {
{
SkywardSwordQuest* q = new SkywardSwordQuest(readUBytes(0x53C0), 0x53C0); SkywardSwordQuest* q = new SkywardSwordQuest(readUBytes(0x53C0), 0x53C0);
atUint64 pos = position(); atUint64 pos = position();
// seek to the skip data for this particular quest // seek to the skip data for this particular quest
@ -63,4 +55,4 @@ SkywardSwordFile* SkywardSwordFileReader::read()
return file; return file;
} }
} // zelda } // namespace athena::io

View File

@ -2,31 +2,25 @@
#include "athena/SkywardSwordFile.hpp" #include "athena/SkywardSwordFile.hpp"
#include "athena/SkywardSwordQuest.hpp" #include "athena/SkywardSwordQuest.hpp"
namespace athena::io namespace athena::io {
{
SkywardSwordFileWriter::SkywardSwordFileWriter(atUint8* data, atUint64 len) SkywardSwordFileWriter::SkywardSwordFileWriter(atUint8* data, atUint64 len) : MemoryCopyWriter(data, len) {
: MemoryCopyWriter(data, len)
{
setEndian(Endian::Big); setEndian(Endian::Big);
} }
SkywardSwordFileWriter::SkywardSwordFileWriter(const std::string& filename) SkywardSwordFileWriter::SkywardSwordFileWriter(const std::string& filename) : MemoryCopyWriter(filename) {
: MemoryCopyWriter(filename)
{
setEndian(Endian::Big); setEndian(Endian::Big);
} }
void SkywardSwordFileWriter::write(SkywardSwordFile* file) void SkywardSwordFileWriter::write(SkywardSwordFile* file) {
{ if (!file) {
if (!file)
{
atError("file cannot be NULL"); atError("file cannot be NULL");
return; return;
} }
atUint32 magic = (file->region() == Region::NTSC ? SkywardSwordFile::USMagic : atUint32 magic = (file->region() == Region::NTSC
(file->region() == Region::NTSCJ ? SkywardSwordFile::JAMagic : SkywardSwordFile::EUMagic)); ? SkywardSwordFile::USMagic
: (file->region() == Region::NTSCJ ? SkywardSwordFile::JAMagic : SkywardSwordFile::EUMagic));
writeUint32(magic); writeUint32(magic);
seek(0x1C, SeekOrigin::Begin); seek(0x1C, SeekOrigin::Begin);
@ -35,10 +29,8 @@ void SkywardSwordFileWriter::write(SkywardSwordFile* file)
std::vector<SkywardSwordQuest*> quests = file->questList(); std::vector<SkywardSwordQuest*> quests = file->questList();
int i = 0; int i = 0;
for (SkywardSwordQuest* q : quests) for (SkywardSwordQuest* q : quests) {
{ if (q->length() != 0x53C0) {
if (q->length() != 0x53C0)
{
atError("q->data() not 0x53C0 bytes in length"); atError("q->data() not 0x53C0 bytes in length");
return; return;
} }
@ -60,4 +52,4 @@ void SkywardSwordFileWriter::write(SkywardSwordFile* file)
save(); save();
} }
} // zelda } // namespace athena::io

Some files were not shown because too many files have changed in this diff Show More