mirror of https://github.com/libAthena/athena.git
* Fix botched push
This commit is contained in:
parent
cb44123d15
commit
8234d33f0d
|
@ -0,0 +1,73 @@
|
||||||
|
#ifndef ZQUEST_HPP
|
||||||
|
#define ZQUEST_HPP
|
||||||
|
|
||||||
|
#include <Types.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace zelda
|
||||||
|
{
|
||||||
|
class ZQuest
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const Uint32 Major;
|
||||||
|
static const Uint32 Minor;
|
||||||
|
static const Uint32 Revision;
|
||||||
|
static const Uint32 Build;
|
||||||
|
static const Uint32 Version;
|
||||||
|
|
||||||
|
static const Uint32 Magic;
|
||||||
|
|
||||||
|
enum Game
|
||||||
|
{
|
||||||
|
NoGame,
|
||||||
|
LegendofZelda,
|
||||||
|
AdventureOfLink,
|
||||||
|
ALinkToThePast,
|
||||||
|
LinksAwakening,
|
||||||
|
OcarinaOfTime,
|
||||||
|
OcarinaOfTime3D,
|
||||||
|
MajorasMask,
|
||||||
|
OracleOfSeasons,
|
||||||
|
OracleOfAges,
|
||||||
|
FourSwords,
|
||||||
|
WindWaker,
|
||||||
|
FourSwordsAdventures,
|
||||||
|
MinishCap,
|
||||||
|
TwilightPrincess,
|
||||||
|
PhantomHourglass,
|
||||||
|
SpiritTracks,
|
||||||
|
SkywardSword,
|
||||||
|
ALinkBetweenWorlds // Not released
|
||||||
|
};
|
||||||
|
|
||||||
|
ZQuest();
|
||||||
|
ZQuest(Game game, Endian endian, Uint8* data, Uint32 length);
|
||||||
|
~ZQuest();
|
||||||
|
|
||||||
|
void setGame(Game game);
|
||||||
|
Game game() const;
|
||||||
|
|
||||||
|
void setEndian(Endian endian);
|
||||||
|
Endian endian() const;
|
||||||
|
|
||||||
|
void setData(Uint8* data);
|
||||||
|
Uint8* data() const;
|
||||||
|
|
||||||
|
void setLength(Uint32 length);
|
||||||
|
Uint32 length() const;
|
||||||
|
|
||||||
|
std::string gameString() const;
|
||||||
|
private:
|
||||||
|
Game m_game;
|
||||||
|
Endian m_endian;
|
||||||
|
Uint8* m_data;
|
||||||
|
Uint32 m_length;
|
||||||
|
|
||||||
|
// Game strings support
|
||||||
|
std::vector<std::string> m_gameStrings;
|
||||||
|
void initGameStrings();
|
||||||
|
};
|
||||||
|
} // zelda
|
||||||
|
|
||||||
|
#endif // ZQUEST_HPP
|
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef ZQUESTFILEREADER_HPP
|
||||||
|
#define ZQUESTFILEREADER_HPP
|
||||||
|
|
||||||
|
#include "BinaryReader.hpp"
|
||||||
|
|
||||||
|
namespace zelda
|
||||||
|
{
|
||||||
|
class ZQuest;
|
||||||
|
|
||||||
|
class ZQuestFileReader : public io::BinaryReader
|
||||||
|
{
|
||||||
|
BINARYREADER_BASE
|
||||||
|
|
||||||
|
public:
|
||||||
|
ZQuestFileReader(Uint8* data, Uint64 length);
|
||||||
|
ZQuestFileReader(const std::string& filename);
|
||||||
|
|
||||||
|
ZQuest* read();
|
||||||
|
};
|
||||||
|
} // zelda
|
||||||
|
|
||||||
|
#endif // ZQUESTFILEREADER_HPP
|
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef ZQUESTFILEWRITER_HPP
|
||||||
|
#define ZQUESTFILEWRITER_HPP
|
||||||
|
|
||||||
|
#include <BinaryWriter.hpp>
|
||||||
|
|
||||||
|
namespace zelda
|
||||||
|
{
|
||||||
|
class ZQuest;
|
||||||
|
|
||||||
|
class ZQuestFileWriter : public io::BinaryWriter
|
||||||
|
{
|
||||||
|
BINARYWRITER_BASE
|
||||||
|
|
||||||
|
public:
|
||||||
|
ZQuestFileWriter(Uint8* data, Uint64 length);
|
||||||
|
ZQuestFileWriter(const std::string& filename);
|
||||||
|
|
||||||
|
void write(ZQuest* quest, bool compress = true);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif // ZQUESTFILEWRITER_HPP
|
|
@ -0,0 +1,117 @@
|
||||||
|
#include "ZQuest.hpp"
|
||||||
|
|
||||||
|
namespace zelda
|
||||||
|
{
|
||||||
|
|
||||||
|
const Uint32 ZQuest::Major = 1;
|
||||||
|
const Uint32 ZQuest::Minor = 0;
|
||||||
|
const Uint32 ZQuest::Revision = 0;
|
||||||
|
const Uint32 ZQuest::Build = 0;
|
||||||
|
|
||||||
|
const Uint32 ZQuest::Version = Major | (Minor << 8) | (Revision << 16) | (Build << 24);
|
||||||
|
|
||||||
|
const Uint32 ZQuest::Magic = 'Z' | ('Q' << 8) | ('S' << 16) | ('1' << 24);
|
||||||
|
|
||||||
|
ZQuest::ZQuest()
|
||||||
|
: m_game(NoGame),
|
||||||
|
m_endian(LittleEndian),
|
||||||
|
m_data(NULL),
|
||||||
|
m_length(0)
|
||||||
|
{
|
||||||
|
initGameStrings();
|
||||||
|
}
|
||||||
|
|
||||||
|
ZQuest::ZQuest(ZQuest::Game game, Endian endian, Uint8* data, Uint32 length)
|
||||||
|
: m_game(game),
|
||||||
|
m_endian(endian),
|
||||||
|
m_data(data),
|
||||||
|
m_length(length)
|
||||||
|
{
|
||||||
|
initGameStrings();
|
||||||
|
}
|
||||||
|
|
||||||
|
ZQuest::~ZQuest()
|
||||||
|
{
|
||||||
|
delete[] m_data;
|
||||||
|
m_data = NULL;
|
||||||
|
m_length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZQuest::setGame(ZQuest::Game game)
|
||||||
|
{
|
||||||
|
m_game = game;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZQuest::Game ZQuest::game() const
|
||||||
|
{
|
||||||
|
return m_game;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZQuest::setEndian(Endian endian)
|
||||||
|
{
|
||||||
|
m_endian = endian;
|
||||||
|
}
|
||||||
|
|
||||||
|
Endian ZQuest::endian() const
|
||||||
|
{
|
||||||
|
return m_endian;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZQuest::setData(Uint8* data)
|
||||||
|
{
|
||||||
|
// ensure we're not overwritting our data without freeing first
|
||||||
|
// or assigning unnecessisarily
|
||||||
|
if (!m_data || m_data != data)
|
||||||
|
{
|
||||||
|
delete[] m_data;
|
||||||
|
m_data = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint8* ZQuest::data() const
|
||||||
|
{
|
||||||
|
return m_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZQuest::setLength(Uint32 length)
|
||||||
|
{
|
||||||
|
m_length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint32 ZQuest::length() const
|
||||||
|
{
|
||||||
|
return m_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ZQuest::gameString() const
|
||||||
|
{
|
||||||
|
if (m_game > m_gameStrings.size() - 1)
|
||||||
|
return "Unsupported Game";
|
||||||
|
|
||||||
|
return m_gameStrings[m_game];
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZQuest::initGameStrings()
|
||||||
|
{
|
||||||
|
m_gameStrings.push_back("No Game");
|
||||||
|
m_gameStrings.push_back("Legend Of Zelda");
|
||||||
|
m_gameStrings.push_back("Adventure of Link");
|
||||||
|
m_gameStrings.push_back("A Link to the Past");
|
||||||
|
m_gameStrings.push_back("Links Awakening");
|
||||||
|
m_gameStrings.push_back("Ocarina of Time");
|
||||||
|
m_gameStrings.push_back("Ocarina of Time 3D");
|
||||||
|
m_gameStrings.push_back("Majora's Mask");
|
||||||
|
m_gameStrings.push_back("Oracle of Seasons");
|
||||||
|
m_gameStrings.push_back("Oracle of Ages");
|
||||||
|
m_gameStrings.push_back("For Swords");
|
||||||
|
m_gameStrings.push_back("Wind Waker");
|
||||||
|
m_gameStrings.push_back("Four Swords Adventures");
|
||||||
|
m_gameStrings.push_back("Minish Cap");
|
||||||
|
m_gameStrings.push_back("Twilight Princess");
|
||||||
|
m_gameStrings.push_back("Phantom Hourglass");
|
||||||
|
m_gameStrings.push_back("Spirit Tracks");
|
||||||
|
m_gameStrings.push_back("Skyward Sword");
|
||||||
|
m_gameStrings.push_back("A Link Between Worlds (Unreleased)");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
#include "ZQuestFileReader.hpp"
|
||||||
|
#include "ZQuest.hpp"
|
||||||
|
#include "IOException.hpp"
|
||||||
|
#include "Compression.hpp"
|
||||||
|
|
||||||
|
namespace zelda
|
||||||
|
{
|
||||||
|
|
||||||
|
ZQuestFileReader::ZQuestFileReader(Uint8 *data, Uint64 length)
|
||||||
|
: base(data, length)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ZQuestFileReader::ZQuestFileReader(const std::string &filename)
|
||||||
|
: base(filename)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ZQuest *ZQuestFileReader::read()
|
||||||
|
{
|
||||||
|
Uint32 magic, version, compressedLen, uncompressedLen;
|
||||||
|
ZQuest::Game game;
|
||||||
|
Uint16 BOM;
|
||||||
|
Uint8* data;
|
||||||
|
|
||||||
|
magic = base::readUInt32();
|
||||||
|
|
||||||
|
if (magic != ZQuest::Magic)
|
||||||
|
throw IOException("ZQuestFileReader::read -> Not a valid ZQuest file");
|
||||||
|
|
||||||
|
version = base::readUInt32();
|
||||||
|
|
||||||
|
if (version != ZQuest::Version)
|
||||||
|
throw IOException("ZQuestFileReader::read -> Unsupported ZQuest version");
|
||||||
|
|
||||||
|
compressedLen = base::readUInt32();
|
||||||
|
uncompressedLen = base::readUInt32();
|
||||||
|
game = (ZQuest::Game)base::readUInt32();
|
||||||
|
BOM = base::readUInt16();
|
||||||
|
base::seek(0x0A);
|
||||||
|
data = (Uint8*)base::readBytes(compressedLen); // compressedLen is always the total file size
|
||||||
|
|
||||||
|
if (compressedLen != uncompressedLen)
|
||||||
|
{
|
||||||
|
Uint8* dst = new Uint8[uncompressedLen];
|
||||||
|
Uint32 dstLen = io::Compression::decompressZlib(data, compressedLen, dst, uncompressedLen);
|
||||||
|
|
||||||
|
if (dstLen != uncompressedLen)
|
||||||
|
{
|
||||||
|
delete[] dst;
|
||||||
|
delete[] data;
|
||||||
|
throw IOException("ZQuestFileReader::read -> Error decompressing data");
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] data;
|
||||||
|
data = dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ZQuest(game, BOM == 0xFEFF ? BigEndian : LittleEndian, data, uncompressedLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // zelda
|
|
@ -0,0 +1,59 @@
|
||||||
|
#include "ZQuestFileWriter.hpp"
|
||||||
|
#include "InvalidOperationException.hpp"
|
||||||
|
#include "ZQuest.hpp"
|
||||||
|
#include "Compression.hpp"
|
||||||
|
|
||||||
|
namespace zelda
|
||||||
|
{
|
||||||
|
|
||||||
|
ZQuestFileWriter::ZQuestFileWriter(Uint8* data, Uint64 length)
|
||||||
|
: base(data, length)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ZQuestFileWriter::ZQuestFileWriter(const std::string& filename)
|
||||||
|
: base(filename)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZQuestFileWriter::write(ZQuest* quest, bool compress)
|
||||||
|
{
|
||||||
|
if (!quest)
|
||||||
|
throw InvalidOperationException("ZQuestFileWriter::writer -> quest cannot be NULL");
|
||||||
|
|
||||||
|
base::writeUInt32(ZQuest::Magic);
|
||||||
|
base::writeUInt32(ZQuest::Version);
|
||||||
|
Uint8* questData = quest->data();
|
||||||
|
Uint32 compLen = quest->length();
|
||||||
|
if (compress)
|
||||||
|
{
|
||||||
|
Uint8* compData = new Uint8[quest->length() + 0x20]; // add 20 bytes because sometimes the file grows with compression
|
||||||
|
io::Compression::compressZlib(questData, quest->length(), compData, &compLen);
|
||||||
|
|
||||||
|
// if the compressed data is the same length or larger than the original data, just store the original
|
||||||
|
if (compLen >= quest->length())
|
||||||
|
{
|
||||||
|
compLen = quest->length();
|
||||||
|
// Delete the compressed data since we won't be using it
|
||||||
|
delete[] compData;
|
||||||
|
compData = NULL;
|
||||||
|
base::writeUInt32(quest->length());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Don't do delete on data
|
||||||
|
questData = compData;
|
||||||
|
base::writeUInt32(compLen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
base::writeUInt32(quest->length());
|
||||||
|
|
||||||
|
base::writeUInt32(quest->length());
|
||||||
|
base::writeUInt32(quest->game());
|
||||||
|
base::writeUInt16(quest->endian() == BigEndian ? 0xFEFF : 0xFFFE);
|
||||||
|
base::seek(0x0A);
|
||||||
|
base::writeUBytes(questData, compLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // zelda
|
Loading…
Reference in New Issue