mirror of https://github.com/libAthena/athena.git
Merge pull request #25 from libAthena/smart-ptrs
Refactored readBytes() and readUBytes() to return std::unique_ptr
This commit is contained in:
commit
9ed090b126
|
@ -97,13 +97,13 @@ public:
|
||||||
* \brief setInventory
|
* \brief setInventory
|
||||||
* \param inv
|
* \param inv
|
||||||
*/
|
*/
|
||||||
void setInventory(ALTTPInventory* inv);
|
void setInventory(const ALTTPInventory& inv);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief inventory
|
* \brief inventory
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
ALTTPInventory* inventory() const;
|
const ALTTPInventory& inventory() const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief setRupeeMax
|
* \brief setRupeeMax
|
||||||
|
@ -641,7 +641,7 @@ public:
|
||||||
private:
|
private:
|
||||||
std::vector<ALTTPRoomFlags*> m_roomFlags;
|
std::vector<ALTTPRoomFlags*> m_roomFlags;
|
||||||
std::vector<ALTTPOverworldEvent*> m_overworldEvents;
|
std::vector<ALTTPOverworldEvent*> m_overworldEvents;
|
||||||
ALTTPInventory* m_inventory;
|
ALTTPInventory m_inventory;
|
||||||
atUint16 m_rupeeMax;
|
atUint16 m_rupeeMax;
|
||||||
atUint16 m_rupeeCurrent;
|
atUint16 m_rupeeCurrent;
|
||||||
ALTTPDungeonItemFlags m_compasses;
|
ALTTPDungeonItemFlags m_compasses;
|
||||||
|
|
|
@ -89,14 +89,23 @@ public:
|
||||||
*
|
*
|
||||||
* \return Uint8* The buffer at the current position from the given length.
|
* \return Uint8* The buffer at the current position from the given length.
|
||||||
*/
|
*/
|
||||||
inline atInt8* readBytes(atUint64 length)
|
inline std::unique_ptr<atInt8[]> readBytes(atUint64 length)
|
||||||
{atInt8* buf = new atInt8[length]; readUBytesToBuf(buf, length); return buf;}
|
{
|
||||||
|
atInt8* buf = new atInt8[length];
|
||||||
|
readUBytesToBuf(buf, length);
|
||||||
|
return std::unique_ptr<atInt8[]>(buf);
|
||||||
|
}
|
||||||
|
|
||||||
/*! \brief Reads a byte at the current position and advances the current position.
|
/*! \brief Reads a byte at the current position and advances the current position.
|
||||||
*
|
*
|
||||||
* \return Int8* The buffer at the current position from the given length.
|
* \return Int8* The buffer at the current position from the given length.
|
||||||
*/
|
*/
|
||||||
inline atUint8* readUBytes(atUint64 length) {return (atUint8*)readBytes(length);}
|
inline std::unique_ptr<atUint8[]> readUBytes(atUint64 length)
|
||||||
|
{
|
||||||
|
atUint8* buf = new atUint8[length];
|
||||||
|
readUBytesToBuf(buf, length);
|
||||||
|
return std::unique_ptr<atUint8[]>(buf);
|
||||||
|
}
|
||||||
|
|
||||||
inline atUint64 readBytesToBuf(void* buf, atUint64 len) {return readUBytesToBuf(buf, len);}
|
inline atUint64 readBytesToBuf(void* buf, atUint64 len) {return readUBytesToBuf(buf, len);}
|
||||||
virtual atUint64 readUBytesToBuf(void* buf, atUint64 len)=0;
|
virtual atUint64 readUBytesToBuf(void* buf, atUint64 len)=0;
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace Athena
|
||||||
class MCSlot : public ZQuestFile
|
class MCSlot : public ZQuestFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MCSlot(atUint8* data, atUint32 length);
|
MCSlot(std::unique_ptr<atUint8[]>&& data, atUint32 length);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Athena
|
} // Athena
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
Seeds
|
Seeds
|
||||||
};
|
};
|
||||||
|
|
||||||
SkywardSwordQuest(atUint8* data, atUint32 len);
|
SkywardSwordQuest(std::unique_ptr<atUint8[]>&& data, atUint32 len);
|
||||||
|
|
||||||
void setPlayerName(const std::string& name);
|
void setPlayerName(const std::string& name);
|
||||||
std::string playerName() const;
|
std::string playerName() const;
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
std::string currentArea();
|
std::string currentArea();
|
||||||
std::string currentLocationCopy();
|
std::string currentLocationCopy();
|
||||||
|
|
||||||
void setSkipData(const atUint8* data);
|
void setSkipData(std::unique_ptr<atUint8[]>&& data);
|
||||||
atUint8* skipData() const;
|
atUint8* skipData() const;
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
void setNew(bool isNew);
|
void setNew(bool isNew);
|
||||||
bool isNew() const;
|
bool isNew() const;
|
||||||
private:
|
private:
|
||||||
atUint8* m_skipData;
|
std::unique_ptr<atUint8[]> m_skipData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#ifndef WIIIMAGE_HPP
|
#ifndef WIIIMAGE_HPP
|
||||||
#define WIIIMAGE_HPP
|
#define WIIIMAGE_HPP
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include "Athena/Types.hpp"
|
#include "Athena/Types.hpp"
|
||||||
|
|
||||||
namespace Athena
|
namespace Athena
|
||||||
|
@ -38,12 +39,7 @@ public:
|
||||||
* \param height
|
* \param height
|
||||||
* \param data
|
* \param data
|
||||||
*/
|
*/
|
||||||
WiiImage(atUint32 width, atUint32 height, atUint8* data);
|
WiiImage(atUint32 width, atUint32 height, std::unique_ptr<atUint8[]>&& data);
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief ~WiiImage
|
|
||||||
*/
|
|
||||||
~WiiImage();
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief setWidth
|
* \brief setWidth
|
||||||
|
@ -90,7 +86,7 @@ public:
|
||||||
private:
|
private:
|
||||||
atUint32 m_width;
|
atUint32 m_width;
|
||||||
atUint32 m_height;
|
atUint32 m_height;
|
||||||
atUint8* m_data;
|
std::unique_ptr<atUint8[]> m_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // zelda
|
} // zelda
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "Athena/Global.hpp"
|
#include "Athena/Global.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#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))
|
||||||
|
@ -98,8 +99,7 @@ public:
|
||||||
* \param data
|
* \param data
|
||||||
* \param length
|
* \param length
|
||||||
*/
|
*/
|
||||||
ZQuestFile(Game game, Endian endian, 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());
|
||||||
~ZQuestFile();
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief setGame
|
* \brief setGame
|
||||||
|
@ -130,7 +130,7 @@ public:
|
||||||
* \param data The data to assign
|
* \param data The data to assign
|
||||||
* \param length The length of the data
|
* \param length The length of the data
|
||||||
*/
|
*/
|
||||||
void setData(atUint8* data, atUint32 length);
|
void setData(std::unique_ptr<atUint8[]>&& data, atUint32 length);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief data
|
* \brief data
|
||||||
|
@ -156,7 +156,7 @@ protected:
|
||||||
Game m_game;
|
Game m_game;
|
||||||
std::string m_gameString;
|
std::string m_gameString;
|
||||||
Endian m_endian;
|
Endian m_endian;
|
||||||
atUint8* m_data;
|
std::unique_ptr<atUint8[]> m_data;
|
||||||
atUint32 m_length;
|
atUint32 m_length;
|
||||||
|
|
||||||
// Game strings support
|
// Game strings support
|
||||||
|
|
|
@ -68,7 +68,7 @@ ALTTPFile* ALTTPFileReader::readFile()
|
||||||
|
|
||||||
quest->setOverworldEvents(owEvents);
|
quest->setOverworldEvents(owEvents);
|
||||||
|
|
||||||
quest->setInventory((ALTTPInventory*)base::readBytes(sizeof(ALTTPInventory)));
|
quest->setInventory(*(ALTTPInventory*)base::readBytes(sizeof(ALTTPInventory)).get());
|
||||||
quest->setRupeeMax(base::readUint16());
|
quest->setRupeeMax(base::readUint16());
|
||||||
quest->setRupeeCurrent(base::readUint16());
|
quest->setRupeeCurrent(base::readUint16());
|
||||||
quest->setCompasses(readDungeonFlags());
|
quest->setCompasses(readDungeonFlags());
|
||||||
|
@ -109,8 +109,8 @@ ALTTPFile* ALTTPFileReader::readFile()
|
||||||
abilities.Read = (abilitiesByte >> 6) & 1;
|
abilities.Read = (abilitiesByte >> 6) & 1;
|
||||||
abilities.Unknown2 = (abilitiesByte >> 7) & 1;
|
abilities.Unknown2 = (abilitiesByte >> 7) & 1;
|
||||||
quest->setAbilityFlags(abilities);
|
quest->setAbilityFlags(abilities);
|
||||||
quest->setCrystals((ALTTPCrystals&)*base::readBytes(sizeof(ALTTPCrystals)));
|
quest->setCrystals(*(ALTTPCrystals*)base::readBytes(sizeof(ALTTPCrystals)).get());
|
||||||
quest->setMagicUsage((ALTTPMagicUsage&)*base::readBytes(sizeof(ALTTPMagicUsage)));
|
quest->setMagicUsage(*(ALTTPMagicUsage*)base::readBytes(sizeof(ALTTPMagicUsage)).get());
|
||||||
|
|
||||||
j = 0x10;
|
j = 0x10;
|
||||||
|
|
||||||
|
@ -122,11 +122,11 @@ ALTTPFile* ALTTPFileReader::readFile()
|
||||||
quest->setDungeonKeys(dungeonKeys);
|
quest->setDungeonKeys(dungeonKeys);
|
||||||
base::seek(0x039);
|
base::seek(0x039);
|
||||||
quest->setProgressIndicator((ALTTPProgressIndicator)base::readByte());
|
quest->setProgressIndicator((ALTTPProgressIndicator)base::readByte());
|
||||||
quest->setProgressFlags1((ALTTPProgressFlags1&)*base::readBytes(sizeof(ALTTPProgressFlags1)));
|
quest->setProgressFlags1(*(ALTTPProgressFlags1*)base::readBytes(sizeof(ALTTPProgressFlags1)).get());
|
||||||
quest->setMapIcon((ALTTPMapIcon)base::readByte());
|
quest->setMapIcon((ALTTPMapIcon)base::readByte());
|
||||||
quest->setStartLocation((ALTTPStartLocation)base::readByte());
|
quest->setStartLocation((ALTTPStartLocation)base::readByte());
|
||||||
quest->setProgressFlags2((ALTTPProgressFlags2&)*base::readBytes(sizeof(ALTTPProgressFlags2)));
|
quest->setProgressFlags2(*(ALTTPProgressFlags2*)base::readBytes(sizeof(ALTTPProgressFlags2)).get());
|
||||||
quest->setLightDarkWorldIndicator((ALTTPLightDarkWorldIndicator&)*base::readBytes(1));
|
quest->setLightDarkWorldIndicator(*(ALTTPLightDarkWorldIndicator*)base::readBytes(1).get());
|
||||||
base::seek(1);
|
base::seek(1);
|
||||||
quest->setTagAlong((ALTTPTagAlong)base::readByte());
|
quest->setTagAlong((ALTTPTagAlong)base::readByte());
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ void ALTTPFileWriter::writeFile(ALTTPFile* file)
|
||||||
writeOverworldEvent(quest->overworldEvent(j));
|
writeOverworldEvent(quest->overworldEvent(j));
|
||||||
}
|
}
|
||||||
|
|
||||||
base::writeBytes((atInt8*)quest->inventory(), sizeof(ALTTPInventory));
|
base::writeBytes((atInt8*)&quest->inventory(), sizeof(ALTTPInventory));
|
||||||
base::writeUint16(quest->rupeeMax());
|
base::writeUint16(quest->rupeeMax());
|
||||||
base::writeUint16(quest->rupeeCurrent());
|
base::writeUint16(quest->rupeeCurrent());
|
||||||
writeDungeonItems(quest->compasses());
|
writeDungeonItems(quest->compasses());
|
||||||
|
|
|
@ -79,12 +79,12 @@ ALTTPOverworldEvent* ALTTPQuest::overworldEvent(atUint32 id) const
|
||||||
return m_overworldEvents[id];
|
return m_overworldEvents[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
void ALTTPQuest::setInventory(ALTTPInventory* inv)
|
void ALTTPQuest::setInventory(const ALTTPInventory& inv)
|
||||||
{
|
{
|
||||||
m_inventory = inv;
|
m_inventory = inv;
|
||||||
}
|
}
|
||||||
|
|
||||||
ALTTPInventory* ALTTPQuest::inventory() const
|
const ALTTPInventory& ALTTPQuest::inventory() const
|
||||||
{
|
{
|
||||||
return m_inventory;
|
return m_inventory;
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,8 +122,7 @@ std::unique_ptr<YAMLNode> YAMLDocReader::ParseEvents(yaml_parser_t* doc)
|
||||||
if (nodeStack.empty())
|
if (nodeStack.empty())
|
||||||
{
|
{
|
||||||
atWarning("YAML parser stack empty; skipping scalar node");
|
atWarning("YAML parser stack empty; skipping scalar node");
|
||||||
yaml_event_delete(&event);
|
break;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
std::unique_ptr<YAMLNode> newScalar(new YAMLNode(YAML_SCALAR_NODE));
|
std::unique_ptr<YAMLNode> newScalar(new YAMLNode(YAML_SCALAR_NODE));
|
||||||
newScalar->m_scalarString.assign((char*)event.data.scalar.value, event.data.scalar.length);
|
newScalar->m_scalarString.assign((char*)event.data.scalar.value, event.data.scalar.length);
|
||||||
|
@ -236,7 +235,7 @@ bool YAMLDocWriter::RecursiveFinish(yaml_emitter_t* doc, const YAMLNode& node)
|
||||||
goto err;
|
goto err;
|
||||||
for (const auto& item : node.m_seqChildren)
|
for (const auto& item : node.m_seqChildren)
|
||||||
{
|
{
|
||||||
if (!RecursiveFinish(doc, *item.get()))
|
if (!RecursiveFinish(doc, *item))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (!yaml_sequence_end_event_initialize(&event) ||
|
if (!yaml_sequence_end_event_initialize(&event) ||
|
||||||
|
@ -252,7 +251,7 @@ bool YAMLDocWriter::RecursiveFinish(yaml_emitter_t* doc, const YAMLNode& node)
|
||||||
{
|
{
|
||||||
if (!EmitKeyScalar(doc, item.first.c_str()))
|
if (!EmitKeyScalar(doc, item.first.c_str()))
|
||||||
goto err;
|
goto err;
|
||||||
if (!RecursiveFinish(doc, *item.second.get()))
|
if (!RecursiveFinish(doc, *item.second))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
event.type = YAML_MAPPING_END_EVENT;
|
event.type = YAML_MAPPING_END_EVENT;
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
namespace Athena
|
namespace Athena
|
||||||
{
|
{
|
||||||
|
|
||||||
MCSlot::MCSlot(atUint8* data, atUint32 length)
|
MCSlot::MCSlot(std::unique_ptr<atUint8[]>&& data, atUint32 length)
|
||||||
: ZQuestFile(ZQuestFile::MC, Endian::LittleEndian, data, length)
|
: ZQuestFile(ZQuestFile::MC, Endian::LittleEndian, std::move(data), length)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ SkywardSwordFile* SkywardSwordFileReader::read()
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
SkywardSwordQuest* q = new SkywardSwordQuest((atUint8*)base::readBytes(0x53C0), 0x53C0);
|
SkywardSwordQuest* q = new SkywardSwordQuest(base::readUBytes(0x53C0), 0x53C0);
|
||||||
atUint64 pos = base::position();
|
atUint64 pos = base::position();
|
||||||
// seek to the skip data for this particular quest
|
// seek to the skip data for this particular quest
|
||||||
base::seek(0xFB60 + (i * 0x24), SeekOrigin::Begin);
|
base::seek(0xFB60 + (i * 0x24), SeekOrigin::Begin);
|
||||||
|
|
|
@ -54,26 +54,19 @@ union AmmoValues
|
||||||
atUint32 value;
|
atUint32 value;
|
||||||
};
|
};
|
||||||
|
|
||||||
SkywardSwordQuest::SkywardSwordQuest(atUint8* data, atUint32 len)
|
SkywardSwordQuest::SkywardSwordQuest(std::unique_ptr<atUint8[]>&& data, atUint32 len)
|
||||||
: ZQuestFile(ZQuestFile::SS, Endian::BigEndian, data, len),
|
: ZQuestFile(ZQuestFile::SS, Endian::BigEndian, std::move(data), len)
|
||||||
m_skipData(nullptr)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkywardSwordQuest::setSkipData(const atUint8* data)
|
void SkywardSwordQuest::setSkipData(std::unique_ptr<atUint8[]>&& data)
|
||||||
{
|
{
|
||||||
if (m_skipData)
|
m_skipData = std::move(data);
|
||||||
{
|
|
||||||
delete[] m_skipData;
|
|
||||||
m_skipData = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_skipData = (atUint8*)data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
atUint8* SkywardSwordQuest::skipData() const
|
atUint8* SkywardSwordQuest::skipData() const
|
||||||
{
|
{
|
||||||
return m_skipData;
|
return m_skipData.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkywardSwordQuest::setPlayerName(const std::string& name)
|
void SkywardSwordQuest::setPlayerName(const std::string& name)
|
||||||
|
@ -86,7 +79,7 @@ void SkywardSwordQuest::setPlayerName(const std::string& name)
|
||||||
|
|
||||||
for (atUint32 i = 0; i < 8; i++)
|
for (atUint32 i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
atUint16& c = *(atUint16*)(m_data + priv::NAME_OFFSET + (i * 2));
|
atUint16& c = *(atUint16*)(m_data.get() + priv::NAME_OFFSET + (i * 2));
|
||||||
|
|
||||||
if (i >= val.size())
|
if (i >= val.size())
|
||||||
{
|
{
|
||||||
|
@ -105,7 +98,7 @@ std::string SkywardSwordQuest::playerName() const
|
||||||
|
|
||||||
for (atUint32 i = 0; i < 8; i++)
|
for (atUint32 i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
atUint16 c = *(atUint16*)(m_data + priv::NAME_OFFSET + (i * 2));
|
atUint16 c = *(atUint16*)(m_data.get() + priv::NAME_OFFSET + (i * 2));
|
||||||
|
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
break;
|
break;
|
||||||
|
@ -120,20 +113,20 @@ std::string SkywardSwordQuest::playerName() const
|
||||||
|
|
||||||
void SkywardSwordQuest::setRupeeCount(atUint16 value)
|
void SkywardSwordQuest::setRupeeCount(atUint16 value)
|
||||||
{
|
{
|
||||||
atUint16& tmp = *(atUint16*)(m_data + priv::RUPEE_COUNT_OFFSET);
|
atUint16& tmp = *(atUint16*)(m_data.get() + priv::RUPEE_COUNT_OFFSET);
|
||||||
tmp = value;
|
tmp = value;
|
||||||
utility::BigUint16(tmp);
|
utility::BigUint16(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
atUint16 SkywardSwordQuest::rupeeCount()
|
atUint16 SkywardSwordQuest::rupeeCount()
|
||||||
{
|
{
|
||||||
atUint16 ret = *(atUint16*)(m_data + priv::RUPEE_COUNT_OFFSET);
|
atUint16 ret = *(atUint16*)(m_data.get() + priv::RUPEE_COUNT_OFFSET);
|
||||||
return utility::BigUint16(ret);
|
return utility::BigUint16(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkywardSwordQuest::setAmmoCount(SkywardSwordQuest::AmmoType type, atUint32 count)
|
void SkywardSwordQuest::setAmmoCount(SkywardSwordQuest::AmmoType type, atUint32 count)
|
||||||
{
|
{
|
||||||
AmmoValues& values = *(AmmoValues*)(m_data + priv::AMMO_COUNT_OFFSET);
|
AmmoValues& values = *(AmmoValues*)(m_data.get() + priv::AMMO_COUNT_OFFSET);
|
||||||
utility::BigUint32(values.value);
|
utility::BigUint32(values.value);
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
|
@ -156,7 +149,7 @@ void SkywardSwordQuest::setAmmoCount(SkywardSwordQuest::AmmoType type, atUint32
|
||||||
|
|
||||||
atUint32 SkywardSwordQuest::ammoCount(AmmoType type)
|
atUint32 SkywardSwordQuest::ammoCount(AmmoType type)
|
||||||
{
|
{
|
||||||
AmmoValues values = *(AmmoValues*)(m_data + priv::AMMO_COUNT_OFFSET);
|
AmmoValues values = *(AmmoValues*)(m_data.get() + priv::AMMO_COUNT_OFFSET);
|
||||||
utility::BigUint32(values.value);
|
utility::BigUint32(values.value);
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
|
@ -177,12 +170,12 @@ atUint32 SkywardSwordQuest::ammoCount(AmmoType type)
|
||||||
|
|
||||||
void SkywardSwordQuest::setMaxHP(atUint16 val)
|
void SkywardSwordQuest::setMaxHP(atUint16 val)
|
||||||
{
|
{
|
||||||
*(atUint16*)(m_data + priv::MAX_HP_OFFSET) = utility::BigUint16(val);
|
*(atUint16*)(m_data.get() + priv::MAX_HP_OFFSET) = utility::BigUint16(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
atUint16 SkywardSwordQuest::maxHP()
|
atUint16 SkywardSwordQuest::maxHP()
|
||||||
{
|
{
|
||||||
atUint16 ret = *(atUint16*)(m_data + priv::MAX_HP_OFFSET);
|
atUint16 ret = *(atUint16*)(m_data.get() + priv::MAX_HP_OFFSET);
|
||||||
return utility::BigUint16(ret);
|
return utility::BigUint16(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,12 +186,12 @@ float SkywardSwordQuest::maxHearts()
|
||||||
|
|
||||||
void SkywardSwordQuest::setSpawnHP(atUint16 val)
|
void SkywardSwordQuest::setSpawnHP(atUint16 val)
|
||||||
{
|
{
|
||||||
*(atUint16*)(m_data + priv::SPAWN_HP_OFFSET) = utility::BigUint16(val);
|
*(atUint16*)(m_data.get() + priv::SPAWN_HP_OFFSET) = utility::BigUint16(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
atUint16 SkywardSwordQuest::spawnHP()
|
atUint16 SkywardSwordQuest::spawnHP()
|
||||||
{
|
{
|
||||||
atUint16 ret = *(atUint16*)(m_data + priv::SPAWN_HP_OFFSET);
|
atUint16 ret = *(atUint16*)(m_data.get() + priv::SPAWN_HP_OFFSET);
|
||||||
return utility::BigUint16(ret);
|
return utility::BigUint16(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,12 +202,12 @@ float SkywardSwordQuest::spawnHearts()
|
||||||
|
|
||||||
void SkywardSwordQuest::setCurrentHP(atUint16 val)
|
void SkywardSwordQuest::setCurrentHP(atUint16 val)
|
||||||
{
|
{
|
||||||
*(atUint16*)(m_data + priv::CURRENT_HP_OFFSET) = utility::BigUint16(val);
|
*(atUint16*)(m_data.get() + priv::CURRENT_HP_OFFSET) = utility::BigUint16(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
atUint16 SkywardSwordQuest::currentHP()
|
atUint16 SkywardSwordQuest::currentHP()
|
||||||
{
|
{
|
||||||
atUint16 ret = *(atUint16*)(m_data + priv::CURRENT_HP_OFFSET);
|
atUint16 ret = *(atUint16*)(m_data.get() + priv::CURRENT_HP_OFFSET);
|
||||||
return utility::BigUint16(ret);
|
return utility::BigUint16(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,22 +218,22 @@ float SkywardSwordQuest::currentHearts()
|
||||||
|
|
||||||
std::string SkywardSwordQuest::currentLocation()
|
std::string SkywardSwordQuest::currentLocation()
|
||||||
{
|
{
|
||||||
return std::string((char*)m_data + priv::CURRENT_LOCATION_OFFSET);
|
return std::string((char*)m_data.get() + priv::CURRENT_LOCATION_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SkywardSwordQuest::currentArea()
|
std::string SkywardSwordQuest::currentArea()
|
||||||
{
|
{
|
||||||
return std::string((char*)m_data + priv::CURRENT_AREA_OFFSET);
|
return std::string((char*)m_data.get() + priv::CURRENT_AREA_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SkywardSwordQuest::currentLocationCopy()
|
std::string SkywardSwordQuest::currentLocationCopy()
|
||||||
{
|
{
|
||||||
return std::string((char*)m_data + priv::CURRENT_LOCATION_COPY_OFFSET);
|
return std::string((char*)m_data.get() + priv::CURRENT_LOCATION_COPY_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
atUint32 SkywardSwordQuest::slotChecksum()
|
atUint32 SkywardSwordQuest::slotChecksum()
|
||||||
{
|
{
|
||||||
atUint32 ret = *(atUint32*)(m_data + priv::CHECKSUM_OFFSET);
|
atUint32 ret = *(atUint32*)(m_data.get() + priv::CHECKSUM_OFFSET);
|
||||||
utility::BigUint32(ret);
|
utility::BigUint32(ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -248,7 +241,7 @@ atUint32 SkywardSwordQuest::slotChecksum()
|
||||||
|
|
||||||
atUint32 SkywardSwordQuest::skipChecksum()
|
atUint32 SkywardSwordQuest::skipChecksum()
|
||||||
{
|
{
|
||||||
atUint32 ret = *(atUint32*)(m_skipData + priv::SKIP_CHECKSUM_OFFSET);
|
atUint32 ret = *(atUint32*)(m_skipData.get() + priv::SKIP_CHECKSUM_OFFSET);
|
||||||
utility::BigUint32(ret);
|
utility::BigUint32(ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -256,23 +249,23 @@ atUint32 SkywardSwordQuest::skipChecksum()
|
||||||
|
|
||||||
void SkywardSwordQuest::fixChecksums()
|
void SkywardSwordQuest::fixChecksums()
|
||||||
{
|
{
|
||||||
atUint32 checksum = Checksums::crc32(m_data, priv::CHECKSUM_OFFSET);
|
atUint32 checksum = Checksums::crc32(m_data.get(), priv::CHECKSUM_OFFSET);
|
||||||
utility::BigUint32(checksum);
|
utility::BigUint32(checksum);
|
||||||
*(atUint32*)(m_data + priv::CHECKSUM_OFFSET) = checksum;
|
*(atUint32*)(m_data.get() + priv::CHECKSUM_OFFSET) = checksum;
|
||||||
|
|
||||||
checksum = Checksums::crc32(m_skipData, priv::SKIP_CHECKSUM_OFFSET);
|
checksum = Checksums::crc32(m_skipData.get(), priv::SKIP_CHECKSUM_OFFSET);
|
||||||
utility::BigUint32(checksum);
|
utility::BigUint32(checksum);
|
||||||
*(atUint32*)(m_skipData + priv::SKIP_CHECKSUM_OFFSET) = checksum;
|
*(atUint32*)(m_skipData.get() + priv::SKIP_CHECKSUM_OFFSET) = checksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkywardSwordQuest::setNew(bool isNew)
|
void SkywardSwordQuest::setNew(bool isNew)
|
||||||
{
|
{
|
||||||
*(bool*)(m_data + priv::ISNEW_OFFSET) = isNew;
|
*(bool*)(m_data.get() + priv::ISNEW_OFFSET) = isNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkywardSwordQuest::isNew() const
|
bool SkywardSwordQuest::isNew() const
|
||||||
{
|
{
|
||||||
return *(bool*)(m_data + priv::ISNEW_OFFSET);
|
return *(bool*)(m_data.get() + priv::ISNEW_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // zelda
|
} // zelda
|
||||||
|
|
|
@ -22,24 +22,16 @@
|
||||||
namespace Athena
|
namespace Athena
|
||||||
{
|
{
|
||||||
|
|
||||||
WiiImage::WiiImage(atUint32 width, atUint32 height, atUint8* data) :
|
WiiImage::WiiImage(atUint32 width, atUint32 height, std::unique_ptr<atUint8[]>&& data) :
|
||||||
m_width(width),
|
m_width(width),
|
||||||
m_height(height),
|
m_height(height),
|
||||||
m_data(data)
|
m_data(std::move(data))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
WiiImage::~WiiImage()
|
|
||||||
{
|
|
||||||
if (m_data)
|
|
||||||
delete[] m_data;
|
|
||||||
|
|
||||||
m_data = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
atUint8* WiiImage::data()
|
atUint8* WiiImage::data()
|
||||||
{
|
{
|
||||||
return m_data;
|
return m_data.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
atUint32 WiiImage::width() const
|
atUint32 WiiImage::width() const
|
||||||
|
@ -72,7 +64,7 @@ atUint8* WiiImage::toRGBA()
|
||||||
{
|
{
|
||||||
for (x = x1; x < (x1 + 4); x++)
|
for (x = x1; x < (x1 + 4); x++)
|
||||||
{
|
{
|
||||||
atUint16 oldpixel = *(atUint16*)(m_data + ((iv++) * 2));
|
atUint16 oldpixel = *(atUint16*)(m_data.get() + ((iv++) * 2));
|
||||||
//if((x >= m_width) || (y >= m_height))
|
//if((x >= m_width) || (y >= m_height))
|
||||||
// continue;
|
// continue;
|
||||||
oldpixel = utility::swapU16(oldpixel);
|
oldpixel = utility::swapU16(oldpixel);
|
||||||
|
|
|
@ -125,7 +125,7 @@ WiiBanner* WiiSaveReader::readBanner()
|
||||||
{
|
{
|
||||||
atUint8* dec = new atUint8[0xF0C0];
|
atUint8* dec = new atUint8[0xF0C0];
|
||||||
memset(dec, 0, 0xF0C0);
|
memset(dec, 0, 0xF0C0);
|
||||||
atUint8* data = (atUint8*)base::readBytes(0xF0C0);
|
std::unique_ptr<atUint8[]> data = base::readUBytes(0xF0C0);
|
||||||
atUint8* oldData = base::data();
|
atUint8* oldData = base::data();
|
||||||
atUint64 oldPos = base::position();
|
atUint64 oldPos = base::position();
|
||||||
atUint64 oldLen = base::length();
|
atUint64 oldLen = base::length();
|
||||||
|
@ -140,7 +140,7 @@ WiiBanner* WiiSaveReader::readBanner()
|
||||||
std::cout << "Decrypting: banner.bin...";
|
std::cout << "Decrypting: banner.bin...";
|
||||||
std::unique_ptr<IAES> aes = NewAES();
|
std::unique_ptr<IAES> aes = NewAES();
|
||||||
aes->setKey(SD_KEY);
|
aes->setKey(SD_KEY);
|
||||||
aes->decrypt(tmpIV, data, dec, 0xF0C0);
|
aes->decrypt(tmpIV, data.get(), dec, 0xF0C0);
|
||||||
std::cout << "done" << std::endl;
|
std::cout << "done" << std::endl;
|
||||||
|
|
||||||
memset(md5, 0, 16);
|
memset(md5, 0, 16);
|
||||||
|
@ -260,10 +260,10 @@ WiiBanner* WiiSaveReader::readBanner()
|
||||||
|
|
||||||
WiiImage* WiiSaveReader::readImage(atUint32 width, atUint32 height)
|
WiiImage* WiiSaveReader::readImage(atUint32 width, atUint32 height)
|
||||||
{
|
{
|
||||||
atUint8* image = (atUint8*)base::readBytes(width * height * 2);
|
std::unique_ptr<atUint8[]> image = base::readUBytes(width * height * 2);
|
||||||
|
|
||||||
if (!utility::isEmpty((atInt8*)image, width * height * 2))
|
if (!utility::isEmpty((atInt8*)image.get(), width * height * 2))
|
||||||
return new WiiImage(width, height, image);
|
return new WiiImage(width, height, std::move(image));
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -276,7 +276,6 @@ WiiFile* WiiSaveReader::readFile()
|
||||||
atUint8 attributes;
|
atUint8 attributes;
|
||||||
atUint8 type;
|
atUint8 type;
|
||||||
std::string name;
|
std::string name;
|
||||||
atUint8* filedata;
|
|
||||||
WiiFile* ret;
|
WiiFile* ret;
|
||||||
|
|
||||||
atUint32 magic = base::readUint32();
|
atUint32 magic = base::readUint32();
|
||||||
|
@ -291,27 +290,26 @@ WiiFile* WiiSaveReader::readFile()
|
||||||
permissions = base::readByte();
|
permissions = base::readByte();
|
||||||
attributes = base::readByte();
|
attributes = base::readByte();
|
||||||
type = (WiiFile::Type)base::readByte();
|
type = (WiiFile::Type)base::readByte();
|
||||||
name = std::string((const char*)base::readBytes(0x45));
|
name = std::string((const char*)base::readBytes(0x45).get());
|
||||||
ret = new WiiFile(std::string(name));
|
ret = new WiiFile(std::string(name));
|
||||||
ret->setPermissions(permissions);
|
ret->setPermissions(permissions);
|
||||||
ret->setAttributes(attributes);
|
ret->setAttributes(attributes);
|
||||||
ret->setType((WiiFile::Type)type);
|
ret->setType((WiiFile::Type)type);
|
||||||
atUint8* iv = (atUint8*)base::readBytes(0x10);
|
std::unique_ptr<atUint8[]> iv = base::readUBytes(0x10);
|
||||||
base::seek(0x20);
|
base::seek(0x20);
|
||||||
|
|
||||||
if (type == WiiFile::File)
|
if (type == WiiFile::File)
|
||||||
{
|
{
|
||||||
// Read file data
|
// Read file data
|
||||||
int roundedLen = (fileLen + 63) & ~63;
|
int roundedLen = (fileLen + 63) & ~63;
|
||||||
filedata = (atUint8*)base::readBytes(roundedLen);
|
std::unique_ptr<atUint8[]> filedata = base::readUBytes(roundedLen);
|
||||||
|
|
||||||
// Decrypt file
|
// Decrypt file
|
||||||
std::cout << "Decrypting: " << ret->filename() << "...";
|
std::cout << "Decrypting: " << ret->filename() << "...";
|
||||||
atUint8* decData = new atUint8[roundedLen];
|
atUint8* decData = new atUint8[roundedLen];
|
||||||
std::unique_ptr<IAES> aes = NewAES();
|
std::unique_ptr<IAES> aes = NewAES();
|
||||||
aes->setKey(SD_KEY);
|
aes->setKey(SD_KEY);
|
||||||
aes->decrypt(iv, filedata, decData, roundedLen);
|
aes->decrypt(iv.get(), filedata.get(), decData, roundedLen);
|
||||||
delete filedata;
|
|
||||||
ret->setData(decData);
|
ret->setData(decData);
|
||||||
ret->setLength(fileLen);
|
ret->setLength(fileLen);
|
||||||
std::cout << "done" << std::endl;
|
std::cout << "done" << std::endl;
|
||||||
|
@ -325,18 +323,18 @@ void WiiSaveReader::readCerts(atUint32 totalSize)
|
||||||
{
|
{
|
||||||
std::cout << "Reading certs..." << std::endl;
|
std::cout << "Reading certs..." << std::endl;
|
||||||
atUint32 dataSize = totalSize - 0x340;
|
atUint32 dataSize = totalSize - 0x340;
|
||||||
atUint8* sig = (atUint8*)base::readBytes(0x40);
|
std::unique_ptr<atUint8[]> sig = base::readUBytes(0x40);
|
||||||
atUint8* ngCert = (atUint8*)base::readBytes(0x180);
|
std::unique_ptr<atUint8[]> ngCert = base::readUBytes(0x180);
|
||||||
atUint8* apCert = (atUint8*)base::readBytes(0x180);
|
std::unique_ptr<atUint8[]> apCert = base::readUBytes(0x180);
|
||||||
base::seek(0xF0C0, SeekOrigin::Begin);
|
base::seek(0xF0C0, SeekOrigin::Begin);
|
||||||
atUint8* data = (atUint8*)base::readBytes(dataSize);
|
std::unique_ptr<atUint8[]> data = base::readUBytes(dataSize);
|
||||||
atUint8* hash;
|
atUint8* hash;
|
||||||
|
|
||||||
hash = getSha1(data, dataSize);
|
hash = getSha1(data.get(), dataSize);
|
||||||
atUint8* hash2 = getSha1(hash, 20);
|
atUint8* hash2 = getSha1(hash, 20);
|
||||||
|
|
||||||
std::cout << "validating..." << std::endl;
|
std::cout << "validating..." << std::endl;
|
||||||
std::cout << (check_ec(ngCert, apCert, sig, hash2) ? "ok" : "invalid") << "...";
|
std::cout << (check_ec(ngCert.get(), apCert.get(), sig.get(), hash2) ? "ok" : "invalid") << "...";
|
||||||
std::cout << "done" << std::endl;
|
std::cout << "done" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,17 +56,16 @@ const atUint32 ZQuestFile::Magic = 'Z' | ('Q' << 8) | ('S' << 16) | (('0' + ZQ
|
||||||
ZQuestFile::ZQuestFile()
|
ZQuestFile::ZQuestFile()
|
||||||
: m_game(NoGame),
|
: m_game(NoGame),
|
||||||
m_endian(Endian::LittleEndian),
|
m_endian(Endian::LittleEndian),
|
||||||
m_data(NULL),
|
|
||||||
m_length(0)
|
m_length(0)
|
||||||
{
|
{
|
||||||
initGameStrings();
|
initGameStrings();
|
||||||
}
|
}
|
||||||
|
|
||||||
ZQuestFile::ZQuestFile(ZQuestFile::Game game, Endian endian, atUint8* data, atUint32 length, const std::string& gameString)
|
ZQuestFile::ZQuestFile(ZQuestFile::Game game, Endian endian, std::unique_ptr<atUint8[]>&& data, atUint32 length, const std::string& gameString)
|
||||||
: m_game(game),
|
: m_game(game),
|
||||||
m_gameString(gameString),
|
m_gameString(gameString),
|
||||||
m_endian(endian),
|
m_endian(endian),
|
||||||
m_data(data),
|
m_data(std::move(data)),
|
||||||
m_length(length)
|
m_length(length)
|
||||||
{
|
{
|
||||||
initGameStrings();
|
initGameStrings();
|
||||||
|
@ -75,13 +74,6 @@ ZQuestFile::ZQuestFile(ZQuestFile::Game game, Endian endian, atUint8* data, atUi
|
||||||
m_gameString = GameStrings[m_game];
|
m_gameString = GameStrings[m_game];
|
||||||
}
|
}
|
||||||
|
|
||||||
ZQuestFile::~ZQuestFile()
|
|
||||||
{
|
|
||||||
delete[] m_data;
|
|
||||||
m_data = NULL;
|
|
||||||
m_length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZQuestFile::setGame(ZQuestFile::Game game)
|
void ZQuestFile::setGame(ZQuestFile::Game game)
|
||||||
{
|
{
|
||||||
m_game = game;
|
m_game = game;
|
||||||
|
@ -107,24 +99,15 @@ Endian ZQuestFile::endian() const
|
||||||
return m_endian;
|
return m_endian;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZQuestFile::setData(atUint8* data, atUint32 length)
|
void ZQuestFile::setData(std::unique_ptr<atUint8[]>&& data, atUint32 length)
|
||||||
{
|
{
|
||||||
// ensure we're not overwritting our data without freeing first
|
m_data = std::move(data);
|
||||||
// or assigning unnecessisarily
|
|
||||||
if (!m_data || m_data != data)
|
|
||||||
{
|
|
||||||
delete[] m_data;
|
|
||||||
m_data = new atUint8[length];
|
|
||||||
// Why is this memcpy needed?
|
|
||||||
// I get SIGABRT without it, need to research
|
|
||||||
memcpy(m_data, data, length);
|
|
||||||
m_length = length;
|
m_length = length;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
atUint8* ZQuestFile::data() const
|
atUint8* ZQuestFile::data() const
|
||||||
{
|
{
|
||||||
return m_data;
|
return m_data.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,6 @@ ZQuestFile* ZQuestFileReader::read()
|
||||||
std::string gameString;
|
std::string gameString;
|
||||||
atUint16 BOM;
|
atUint16 BOM;
|
||||||
atUint32 checksum = 0;
|
atUint32 checksum = 0;
|
||||||
atUint8* data;
|
|
||||||
|
|
||||||
magic = base::readUint32();
|
magic = base::readUint32();
|
||||||
|
|
||||||
|
@ -68,7 +67,7 @@ ZQuestFile* ZQuestFileReader::read()
|
||||||
|
|
||||||
if (version >= ZQUEST_VERSION_CHECK(2, 0, 0))
|
if (version >= ZQUEST_VERSION_CHECK(2, 0, 0))
|
||||||
{
|
{
|
||||||
gameString = std::string((const char*)base::readBytes(0x0A), 0x0A);
|
gameString = std::string((const char*)base::readBytes(0x0A).get(), 0x0A);
|
||||||
|
|
||||||
for (size_t i = 0; i < ZQuestFile::gameStringList().size(); i++)
|
for (size_t i = 0; i < ZQuestFile::gameStringList().size(); i++)
|
||||||
{
|
{
|
||||||
|
@ -90,13 +89,12 @@ ZQuestFile* ZQuestFileReader::read()
|
||||||
base::seek(0x0A);
|
base::seek(0x0A);
|
||||||
}
|
}
|
||||||
|
|
||||||
data = (atUint8*)base::readBytes(compressedLen); // compressedLen is always the total file size
|
std::unique_ptr<atUint8[]> data = base::readUBytes(compressedLen); // compressedLen is always the total file size
|
||||||
|
|
||||||
if (version >= ZQUEST_VERSION_CHECK(2, 0, 0))
|
if (version >= ZQUEST_VERSION_CHECK(2, 0, 0))
|
||||||
{
|
{
|
||||||
if (checksum != Athena::Checksums::crc32(data, compressedLen))
|
if (checksum != Athena::Checksums::crc32(data.get(), compressedLen))
|
||||||
{
|
{
|
||||||
delete[] data;
|
|
||||||
atError("Checksum mismatch, data corrupt");
|
atError("Checksum mismatch, data corrupt");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -110,21 +108,19 @@ ZQuestFile* ZQuestFileReader::read()
|
||||||
if (compressedLen != uncompressedLen)
|
if (compressedLen != uncompressedLen)
|
||||||
{
|
{
|
||||||
atUint8* dst = new atUint8[uncompressedLen];
|
atUint8* dst = new atUint8[uncompressedLen];
|
||||||
atUint32 dstLen = io::Compression::decompressZlib(data, compressedLen, dst, uncompressedLen);
|
atUint32 dstLen = io::Compression::decompressZlib(data.get(), compressedLen, dst, uncompressedLen);
|
||||||
|
|
||||||
if (dstLen != uncompressedLen)
|
if (dstLen != uncompressedLen)
|
||||||
{
|
{
|
||||||
delete[] dst;
|
delete[] dst;
|
||||||
delete[] data;
|
|
||||||
atError("Error decompressing data");
|
atError("Error decompressing data");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] data;
|
data.reset(dst);
|
||||||
data = dst;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ZQuestFile(game, BOM == 0xFEFF ? Endian::BigEndian : Endian::LittleEndian, data, uncompressedLen, gameString);
|
return new ZQuestFile(game, BOM == 0xFEFF ? Endian::BigEndian : Endian::LittleEndian, std::move(data), uncompressedLen, gameString);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // io
|
} // io
|
||||||
|
|
Loading…
Reference in New Issue