mirror of https://github.com/libAthena/athena.git
* Removal of remaining exceptions
This commit is contained in:
parent
4d13caeaab
commit
1de67f30b8
|
@ -40,51 +40,42 @@ SkywardSwordFile* SkywardSwordFileReader::read()
|
||||||
{
|
{
|
||||||
SkywardSwordFile* file = NULL;
|
SkywardSwordFile* file = NULL;
|
||||||
|
|
||||||
try
|
if (base::length() != 0xFBE0)
|
||||||
{
|
{
|
||||||
if (base::length() != 0xFBE0)
|
atError("File not the expected size of 0xFBE0");
|
||||||
{
|
return nullptr;
|
||||||
atError("File not the expected size of 0xFBE0");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
atUint32 magic = base::readUint32();
|
|
||||||
|
|
||||||
if (magic != SkywardSwordFile::USMagic && magic != SkywardSwordFile::JAMagic && magic != SkywardSwordFile::EUMagic)
|
|
||||||
{
|
|
||||||
atError("Not a valid Skyward Sword save file");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
base::seek(0x01C, SeekOrigin::Begin);
|
|
||||||
atUint32 headerSize = base::readUint32(); // Seems to be (headerSize - 1)
|
|
||||||
|
|
||||||
if (headerSize != 0x1D)
|
|
||||||
{
|
|
||||||
atError("Invalid header size, Corrupted data?");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Time to read in each slot
|
|
||||||
file = new SkywardSwordFile;
|
|
||||||
file->setRegion((magic == SkywardSwordFile::USMagic ? Region::NTSC : (magic == SkywardSwordFile::JAMagic ? Region::NTSCJ : Region::PAL)));
|
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
SkywardSwordQuest* q = new SkywardSwordQuest(base::readUBytes(0x53C0), 0x53C0);
|
|
||||||
atUint64 pos = base::position();
|
|
||||||
// seek to the skip data for this particular quest
|
|
||||||
base::seek(0xFB60 + (i * 0x24), SeekOrigin::Begin);
|
|
||||||
q->setSkipData(base::readUBytes(0x24));
|
|
||||||
base::seek(pos, SeekOrigin::Begin);
|
|
||||||
file->addQuest(q);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (...)
|
|
||||||
|
atUint32 magic = base::readUint32();
|
||||||
|
|
||||||
|
if (magic != SkywardSwordFile::USMagic && magic != SkywardSwordFile::JAMagic && magic != SkywardSwordFile::EUMagic)
|
||||||
{
|
{
|
||||||
delete file;
|
atError("Not a valid Skyward Sword save file");
|
||||||
file = NULL;
|
return nullptr;
|
||||||
throw;
|
}
|
||||||
|
|
||||||
|
base::seek(0x01C, SeekOrigin::Begin);
|
||||||
|
atUint32 headerSize = base::readUint32(); // Seems to be (headerSize - 1)
|
||||||
|
|
||||||
|
if (headerSize != 0x1D)
|
||||||
|
{
|
||||||
|
atError("Invalid header size, Corrupted data?");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Time to read in each slot
|
||||||
|
file = new SkywardSwordFile;
|
||||||
|
file->setRegion((magic == SkywardSwordFile::USMagic ? Region::NTSC : (magic == SkywardSwordFile::JAMagic ? Region::NTSCJ : Region::PAL)));
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
SkywardSwordQuest* q = new SkywardSwordQuest(base::readUBytes(0x53C0), 0x53C0);
|
||||||
|
atUint64 pos = base::position();
|
||||||
|
// seek to the skip data for this particular quest
|
||||||
|
base::seek(0xFB60 + (i * 0x24), SeekOrigin::Begin);
|
||||||
|
q->setSkipData(base::readUBytes(0x24));
|
||||||
|
base::seek(pos, SeekOrigin::Begin);
|
||||||
|
file->addQuest(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
|
|
|
@ -40,193 +40,184 @@ Sakura::SpriteFile* SpriteFileReader::readFile()
|
||||||
{
|
{
|
||||||
Sakura::SpriteFile* ret = NULL;
|
Sakura::SpriteFile* ret = NULL;
|
||||||
|
|
||||||
try
|
atUint32 magic = base::readUint32();
|
||||||
{
|
|
||||||
atUint32 magic = base::readUint32();
|
|
||||||
|
|
||||||
if (magic != Sakura::SpriteFile::Magic)
|
if (magic != Sakura::SpriteFile::Magic)
|
||||||
|
{
|
||||||
|
atError("Not a valid Sakura Sprite container");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
atUint32 version = base::readUint32();
|
||||||
|
|
||||||
|
// TODO: Make this more verbose
|
||||||
|
if (version != Sakura::SpriteFile::Version)
|
||||||
|
{
|
||||||
|
atError("Unsupported version");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// After reading in the magic and version we need to load some
|
||||||
|
// metadata about the file.
|
||||||
|
// Such as the texture count, it's dimensions, and it's origin.
|
||||||
|
// After that we have the number of sprites contained in this
|
||||||
|
// sprite container.
|
||||||
|
atUint16 textureCount = base::readUint16(); // Having it as a Uint16 gives us the ability to have up to 65536 different states
|
||||||
|
// This is probably overkill, but it's better safe than sorry.
|
||||||
|
atUint32 width = base::readUint32();
|
||||||
|
atUint32 height = base::readUint32();
|
||||||
|
float originX = base::readFloat();
|
||||||
|
float originY = base::readFloat();
|
||||||
|
atUint16 spriteCount = base::readUint16();
|
||||||
|
|
||||||
|
// Lets go ahead and create or new container.
|
||||||
|
ret = new Sakura::SpriteFile(width, height, originX, originY);
|
||||||
|
|
||||||
|
// The next four bytes are reserved to keep the header 32 byte aligned.
|
||||||
|
// This isn't necessary for most systems, but it's eventually planned
|
||||||
|
// to migrate this code to Big Endian based systems, such as the wii
|
||||||
|
// which require data to be 32 byte aligned, or it causes some issues.
|
||||||
|
// It's also convenient to have this, for later expansion.
|
||||||
|
atUint32 reserved = base::readUint32();
|
||||||
|
UNUSED(reserved);
|
||||||
|
|
||||||
|
// Next we have to load the textures
|
||||||
|
// If we tried to add them one at a time to the sprite container
|
||||||
|
// it will be slow as hell, so we store them in a vector locally
|
||||||
|
// then give that vector the the container, this bypasses the de-reference
|
||||||
|
// for each texture
|
||||||
|
#ifndef ATHENA_USE_QT
|
||||||
|
std::vector<Sakura::STexture*> textures;
|
||||||
|
#else
|
||||||
|
QList<Sakura::STexture*> textures;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (atUint16 i = 0; i < textureCount; i++)
|
||||||
|
{
|
||||||
|
Sakura::STexture* texture = new Sakura::STexture;
|
||||||
|
texture->Filepath = base::readString();
|
||||||
|
texture->Preload = base::readBool();
|
||||||
|
textures.push_back(texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret->setTextures(textures);
|
||||||
|
|
||||||
|
// Now for the sprites
|
||||||
|
// The sprites are a bit more difficult, they are stored in an unordered_map
|
||||||
|
// with it's name as the key, this means we can't have two sprites with the same name
|
||||||
|
// Normally this isn't a problem, but someone may decide to copy and paste a sprite
|
||||||
|
// and forget to change the name, that needs to be handled, but it's outside the scope
|
||||||
|
// of this reader.
|
||||||
|
#ifndef ATHENA_USE_QT
|
||||||
|
std::unordered_map <std::string, Sakura::Sprite*> sprites;
|
||||||
|
#else
|
||||||
|
QMap<QString, Sakura::Sprite*> sprites;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (atUint16 i = 0; i < spriteCount; i++)
|
||||||
|
{
|
||||||
|
Sakura::Sprite* sprite = new Sakura::Sprite(ret);
|
||||||
|
#ifndef ATHENA_USE_QT
|
||||||
|
std::string name = base::readString();
|
||||||
|
#else
|
||||||
|
QString name = QString::fromStdString(base::readString());
|
||||||
|
#endif
|
||||||
|
sprite->setName(name);
|
||||||
|
atUint16 frameCount = base::readUint16();
|
||||||
|
atUint16 stateCount = base::readUint16();
|
||||||
|
|
||||||
|
// Each state id corresponds to a texture held in the parent class
|
||||||
|
std::vector<int> stateIds;
|
||||||
|
|
||||||
|
for (int j = 0; j < stateCount; j++)
|
||||||
|
stateIds.push_back(base::readUint16());
|
||||||
|
|
||||||
|
|
||||||
|
sprite->setStateIds(stateIds);
|
||||||
|
|
||||||
|
// Now to read the sprite parts.
|
||||||
|
// The parts allow us to build retro style sprites very easily
|
||||||
|
// making it possible to use one texture atlas for all possible
|
||||||
|
// frame combinations, this reduces the amount of memory overhead
|
||||||
|
// and the storage footprint, while Sakura supports packs and zips
|
||||||
|
// it's still a bad idea to have a metric ton of texture resources
|
||||||
|
// littering the place
|
||||||
|
#ifndef ATHENA_USE_QT
|
||||||
|
std::vector<Sakura::SpriteFrame*> frames;
|
||||||
|
#else
|
||||||
|
QList<Sakura::SpriteFrame*> frames;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (atUint32 k = 0; k < frameCount; k++)
|
||||||
{
|
{
|
||||||
atError("Not a valid Sakura Sprite container");
|
Sakura::SpriteFrame* frame = new Sakura::SpriteFrame(sprite);
|
||||||
|
frame->setFrameTime(base::readFloat());
|
||||||
|
atUint16 partCount = base::readUint16();
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef ATHENA_USE_QT
|
||||||
|
std::vector<Sakura::SpritePart*> parts;
|
||||||
|
#else
|
||||||
|
QList<Sakura::SpritePart*> parts;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (atUint8 j = 0; j < partCount; j++)
|
||||||
|
{
|
||||||
|
Sakura::SpritePart* part = new Sakura::SpritePart(frame);
|
||||||
|
#ifndef ATHENA_USE_QT
|
||||||
|
std::string name = base::readString();
|
||||||
|
#else
|
||||||
|
QString name = QString::fromStdString(base::readString());
|
||||||
|
#endif
|
||||||
|
part->setName(name);
|
||||||
|
part->setCollision(base::readBool());
|
||||||
|
|
||||||
|
float xOff = base::readFloat();
|
||||||
|
float yOff = base::readFloat();
|
||||||
|
part->setOffset(xOff, yOff);
|
||||||
|
float texXOff = base::readFloat();
|
||||||
|
float texYOff = base::readFloat();
|
||||||
|
part->setTextureOffset(texXOff, texYOff);
|
||||||
|
atUint32 width = base::readUint32();
|
||||||
|
atUint32 height = base::readUint32();
|
||||||
|
part->setSize(width, height);
|
||||||
|
bool flippedH = base::readBool();
|
||||||
|
part->setFlippedHorizontally(flippedH);
|
||||||
|
bool flippedV = base::readBool();
|
||||||
|
part->setFlippedVertically(flippedV);
|
||||||
|
|
||||||
|
parts.push_back(part);
|
||||||
|
}
|
||||||
|
|
||||||
|
frame->setParts(parts);
|
||||||
|
frames.push_back(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
sprite->setFrames(frames);
|
||||||
|
#ifndef ATHENA_USE_QT
|
||||||
|
|
||||||
|
if (sprite->name() != std::string())
|
||||||
|
{
|
||||||
|
std::string nameLow(sprite->name());
|
||||||
|
Athena::utility::tolower(nameLow);
|
||||||
|
sprites[nameLow] = sprite;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
if (!sprite->name().isEmpty())
|
||||||
|
sprites[sprite->name().toLower()] = sprite;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
{
|
||||||
|
atError("Sprite names cannot be empty");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
atUint32 version = base::readUint32();
|
|
||||||
|
|
||||||
// TODO: Make this more verbose
|
|
||||||
if (version != Sakura::SpriteFile::Version)
|
|
||||||
{
|
|
||||||
atError("Unsupported version");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// After reading in the magic and version we need to load some
|
|
||||||
// metadata about the file.
|
|
||||||
// Such as the texture count, it's dimensions, and it's origin.
|
|
||||||
// After that we have the number of sprites contained in this
|
|
||||||
// sprite container.
|
|
||||||
atUint16 textureCount = base::readUint16(); // Having it as a Uint16 gives us the ability to have up to 65536 different states
|
|
||||||
// This is probably overkill, but it's better safe than sorry.
|
|
||||||
atUint32 width = base::readUint32();
|
|
||||||
atUint32 height = base::readUint32();
|
|
||||||
float originX = base::readFloat();
|
|
||||||
float originY = base::readFloat();
|
|
||||||
atUint16 spriteCount = base::readUint16();
|
|
||||||
|
|
||||||
// Lets go ahead and create or new container.
|
|
||||||
ret = new Sakura::SpriteFile(width, height, originX, originY);
|
|
||||||
|
|
||||||
// The next four bytes are reserved to keep the header 32 byte aligned.
|
|
||||||
// This isn't necessary for most systems, but it's eventually planned
|
|
||||||
// to migrate this code to Big Endian based systems, such as the wii
|
|
||||||
// which require data to be 32 byte aligned, or it causes some issues.
|
|
||||||
// It's also convenient to have this, for later expansion.
|
|
||||||
atUint32 reserved = base::readUint32();
|
|
||||||
UNUSED(reserved);
|
|
||||||
|
|
||||||
// Next we have to load the textures
|
|
||||||
// If we tried to add them one at a time to the sprite container
|
|
||||||
// it will be slow as hell, so we store them in a vector locally
|
|
||||||
// then give that vector the the container, this bypasses the de-reference
|
|
||||||
// for each texture
|
|
||||||
#ifndef ATHENA_USE_QT
|
|
||||||
std::vector<Sakura::STexture*> textures;
|
|
||||||
#else
|
|
||||||
QList<Sakura::STexture*> textures;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (atUint16 i = 0; i < textureCount; i++)
|
|
||||||
{
|
|
||||||
Sakura::STexture* texture = new Sakura::STexture;
|
|
||||||
texture->Filepath = base::readString();
|
|
||||||
texture->Preload = base::readBool();
|
|
||||||
textures.push_back(texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret->setTextures(textures);
|
|
||||||
|
|
||||||
// Now for the sprites
|
|
||||||
// The sprites are a bit more difficult, they are stored in an unordered_map
|
|
||||||
// with it's name as the key, this means we can't have two sprites with the same name
|
|
||||||
// Normally this isn't a problem, but someone may decide to copy and paste a sprite
|
|
||||||
// and forget to change the name, that needs to be handled, but it's outside the scope
|
|
||||||
// of this reader.
|
|
||||||
#ifndef ATHENA_USE_QT
|
|
||||||
std::unordered_map <std::string, Sakura::Sprite*> sprites;
|
|
||||||
#else
|
|
||||||
QMap<QString, Sakura::Sprite*> sprites;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (atUint16 i = 0; i < spriteCount; i++)
|
|
||||||
{
|
|
||||||
Sakura::Sprite* sprite = new Sakura::Sprite(ret);
|
|
||||||
#ifndef ATHENA_USE_QT
|
|
||||||
std::string name = base::readString();
|
|
||||||
#else
|
|
||||||
QString name = QString::fromStdString(base::readString());
|
|
||||||
#endif
|
|
||||||
sprite->setName(name);
|
|
||||||
atUint16 frameCount = base::readUint16();
|
|
||||||
atUint16 stateCount = base::readUint16();
|
|
||||||
|
|
||||||
// Each state id corresponds to a texture held in the parent class
|
|
||||||
std::vector<int> stateIds;
|
|
||||||
|
|
||||||
for (int j = 0; j < stateCount; j++)
|
|
||||||
stateIds.push_back(base::readUint16());
|
|
||||||
|
|
||||||
|
|
||||||
sprite->setStateIds(stateIds);
|
|
||||||
|
|
||||||
// Now to read the sprite parts.
|
|
||||||
// The parts allow us to build retro style sprites very easily
|
|
||||||
// making it possible to use one texture atlas for all possible
|
|
||||||
// frame combinations, this reduces the amount of memory overhead
|
|
||||||
// and the storage footprint, while Sakura supports packs and zips
|
|
||||||
// it's still a bad idea to have a metric ton of texture resources
|
|
||||||
// littering the place
|
|
||||||
#ifndef ATHENA_USE_QT
|
|
||||||
std::vector<Sakura::SpriteFrame*> frames;
|
|
||||||
#else
|
|
||||||
QList<Sakura::SpriteFrame*> frames;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (atUint32 k = 0; k < frameCount; k++)
|
|
||||||
{
|
|
||||||
Sakura::SpriteFrame* frame = new Sakura::SpriteFrame(sprite);
|
|
||||||
frame->setFrameTime(base::readFloat());
|
|
||||||
atUint16 partCount = base::readUint16();
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef ATHENA_USE_QT
|
|
||||||
std::vector<Sakura::SpritePart*> parts;
|
|
||||||
#else
|
|
||||||
QList<Sakura::SpritePart*> parts;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (atUint8 j = 0; j < partCount; j++)
|
|
||||||
{
|
|
||||||
Sakura::SpritePart* part = new Sakura::SpritePart(frame);
|
|
||||||
#ifndef ATHENA_USE_QT
|
|
||||||
std::string name = base::readString();
|
|
||||||
#else
|
|
||||||
QString name = QString::fromStdString(base::readString());
|
|
||||||
#endif
|
|
||||||
part->setName(name);
|
|
||||||
part->setCollision(base::readBool());
|
|
||||||
|
|
||||||
float xOff = base::readFloat();
|
|
||||||
float yOff = base::readFloat();
|
|
||||||
part->setOffset(xOff, yOff);
|
|
||||||
float texXOff = base::readFloat();
|
|
||||||
float texYOff = base::readFloat();
|
|
||||||
part->setTextureOffset(texXOff, texYOff);
|
|
||||||
atUint32 width = base::readUint32();
|
|
||||||
atUint32 height = base::readUint32();
|
|
||||||
part->setSize(width, height);
|
|
||||||
bool flippedH = base::readBool();
|
|
||||||
part->setFlippedHorizontally(flippedH);
|
|
||||||
bool flippedV = base::readBool();
|
|
||||||
part->setFlippedVertically(flippedV);
|
|
||||||
|
|
||||||
parts.push_back(part);
|
|
||||||
}
|
|
||||||
|
|
||||||
frame->setParts(parts);
|
|
||||||
frames.push_back(frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
sprite->setFrames(frames);
|
|
||||||
#ifndef ATHENA_USE_QT
|
|
||||||
|
|
||||||
if (sprite->name() != std::string())
|
|
||||||
{
|
|
||||||
std::string nameLow(sprite->name());
|
|
||||||
Athena::utility::tolower(nameLow);
|
|
||||||
sprites[nameLow] = sprite;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
if (!sprite->name().isEmpty())
|
|
||||||
sprites[sprite->name().toLower()] = sprite;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
{
|
|
||||||
atError("Sprite names cannot be empty");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret->setSprites(sprites);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
delete ret;
|
|
||||||
ret = NULL;
|
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret->setSprites(sprites);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
} // io
|
} // io
|
||||||
|
|
|
@ -51,73 +51,63 @@ WiiSave* WiiSaveReader::readSave()
|
||||||
{
|
{
|
||||||
WiiSave* ret = new WiiSave;
|
WiiSave* ret = new WiiSave;
|
||||||
|
|
||||||
try
|
if (length() < 0xF0C0)
|
||||||
{
|
{
|
||||||
if (length() < 0xF0C0)
|
atError("Not a valid WiiSave");
|
||||||
{
|
return nullptr;
|
||||||
atError("Not a valid WiiSave");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
WiiBanner* banner = this->readBanner();
|
|
||||||
|
|
||||||
if (!banner)
|
|
||||||
{
|
|
||||||
atError("Invalid banner");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret->setBanner(banner);
|
|
||||||
atUint32 bkVer = base::readUint32();
|
|
||||||
|
|
||||||
if (bkVer != 0x00000070)
|
|
||||||
{
|
|
||||||
atError("Invalid BacKup header size");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
atUint32 bkMagic = base::readUint32();
|
|
||||||
|
|
||||||
if (bkMagic != 0x426B0001)
|
|
||||||
{
|
|
||||||
atError("Invalid BacKup header magic");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*atUint32 ngId =*/ base::readUint32();
|
|
||||||
atUint32 numFiles = base::readUint32();
|
|
||||||
|
|
||||||
/*int fileSize =*/ base::readUint32();
|
|
||||||
base::seek(8); // skip unknown data;
|
|
||||||
|
|
||||||
atUint32 totalSize = base::readUint32();
|
|
||||||
base::seek(64); // Unknown (Most likely padding)
|
|
||||||
base::seek(8);
|
|
||||||
base::seek(6);
|
|
||||||
base::seek(2);
|
|
||||||
base::seek(0x10);
|
|
||||||
|
|
||||||
std::vector<WiiFile*> files;
|
|
||||||
|
|
||||||
for (atUint32 i = 0; i < numFiles; ++i)
|
|
||||||
{
|
|
||||||
WiiFile* file = readFile();
|
|
||||||
|
|
||||||
if (file)
|
|
||||||
files.push_back(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret->setRoot(buildTree(files));
|
|
||||||
|
|
||||||
readCerts(totalSize);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
delete ret;
|
|
||||||
ret = NULL;
|
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WiiBanner* banner = this->readBanner();
|
||||||
|
|
||||||
|
if (!banner)
|
||||||
|
{
|
||||||
|
atError("Invalid banner");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret->setBanner(banner);
|
||||||
|
atUint32 bkVer = base::readUint32();
|
||||||
|
|
||||||
|
if (bkVer != 0x00000070)
|
||||||
|
{
|
||||||
|
atError("Invalid BacKup header size");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
atUint32 bkMagic = base::readUint32();
|
||||||
|
|
||||||
|
if (bkMagic != 0x426B0001)
|
||||||
|
{
|
||||||
|
atError("Invalid BacKup header magic");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*atUint32 ngId =*/ base::readUint32();
|
||||||
|
atUint32 numFiles = base::readUint32();
|
||||||
|
|
||||||
|
/*int fileSize =*/ base::readUint32();
|
||||||
|
base::seek(8); // skip unknown data;
|
||||||
|
|
||||||
|
atUint32 totalSize = base::readUint32();
|
||||||
|
base::seek(64); // Unknown (Most likely padding)
|
||||||
|
base::seek(8);
|
||||||
|
base::seek(6);
|
||||||
|
base::seek(2);
|
||||||
|
base::seek(0x10);
|
||||||
|
|
||||||
|
std::vector<WiiFile*> files;
|
||||||
|
|
||||||
|
for (atUint32 i = 0; i < numFiles; ++i)
|
||||||
|
{
|
||||||
|
WiiFile* file = readFile();
|
||||||
|
|
||||||
|
if (file)
|
||||||
|
files.push_back(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret->setRoot(buildTree(files));
|
||||||
|
|
||||||
|
readCerts(totalSize);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue