* Standardized Exception messages

* Added zelda::error namespace
* Moved all Exceptions to zelda::error
* Moved all Read/Write classes to zelda::io
* Added "base" to all classes that inherit from BinaryReader/Writers
* Changed all references to BinaryReader/Writer functions to base for
readability.
This commit is contained in:
Antidote 2013-07-21 00:49:07 -07:00
parent 0fc335ef14
commit d06c96d3aa
36 changed files with 732 additions and 500 deletions

View File

@ -23,6 +23,9 @@
namespace zelda
{
class ALTTPFile;
namespace io
{
/*! \class ALTTPFileReader
* \brief A Link to the Past save data reader class
@ -31,10 +34,10 @@ namespace zelda
* all work is done using a memory buffer, and not read directly from the disk.
* \sa BinaryReader
*/
class ALTTPFile;
class ALTTPFileReader : public io::BinaryReader
{
BINARYREADER_BASE
public:
/*! \brief This constructor takes an existing buffer to read from.
*
@ -60,5 +63,6 @@ private:
ALTTPDungeonItemFlags readDungeonFlags();
};
} // io
} // zelda
#endif // __ALTTP_FILE_READER_HPP__

View File

@ -23,9 +23,10 @@
namespace zelda
{
class ALTTPFile;
namespace io
{
/*! \class ALTTPFileWriter
* \brief A Link to the Past save data writer class
*
@ -35,6 +36,8 @@ class ALTTPFile;
*/
class ALTTPFileWriter : public io::BinaryWriter
{
BINARYWRITER_BASE
public:
/*! \brief This constructor takes an existing buffer to write to.
*
@ -62,6 +65,7 @@ private:
Uint16 calculateChecksum(Uint32 game);
};
} // io
} // zelda
#endif // __ALTTP_FILE_WRITER_HPP__

View File

@ -1,3 +1,18 @@
// This file is part of libZelda.
//
// libZelda is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// libZelda is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with libZelda. If not, see <http://www.gnu.org/licenses/>
#ifndef COMPRESSION_HPP
#define COMPRESSION_HPP

View File

@ -20,6 +20,8 @@
namespace zelda
{
namespace error
{
/*! \class Exception
* \brief The baseclass for all Exceptions.
@ -49,5 +51,6 @@ protected:
std::string m_message; //!< The error message string
};
} // error
} // zelda
#endif

View File

@ -20,6 +20,8 @@
namespace zelda
{
namespace error
{
/*! \class FileNotFoundException
* \brief An excpeption thrown when a file could not be found at the given path.
@ -48,6 +50,7 @@ private:
std::string m_filename;
};
} // error
} // zelda
#endif

View File

@ -21,6 +21,8 @@
namespace zelda
{
namespace error
{
/*! \class IOException
* \brief An excpeption thrown on inappropriate IO calls.
@ -40,8 +42,9 @@ public:
*/
IOException(const std::string& message) :
Exception("IOException: " + message)
{};
{}
};
} // error
} // zelda
#endif

View File

@ -21,6 +21,8 @@
namespace zelda
{
namespace error
{
/*! \class InvalidOperationException
* \brief An excpeption thrown on Invalid Operations calls.
@ -43,6 +45,7 @@ public:
}
};
} // error
} // zelda
#endif // __INVALID_OPERATION_EXCEPTION_HPP__

View File

@ -24,6 +24,9 @@ namespace zelda
class MCFile;
namespace io
{
/*! \class MCFileReader
* \brief The Minish Cap Save save data reader class
*
@ -33,6 +36,7 @@ class MCFile;
*/
class MCFileReader : public io::BinaryReader
{
BINARYREADER_BASE
public:
/*!
* \brief This constructor takes an existing buffer to read from.
@ -57,6 +61,7 @@ public:
MCFile* readFile();
};
} // io
} // zelda
#endif // __MCFILEREADER_HPP__

View File

@ -33,6 +33,7 @@ class MCFile;
*/
class MCFileWriter : public io::BinaryWriter
{
BINARYWRITER_BASE
public:
/*!
* \brief This constructor takes an existing buffer to write to.

View File

@ -22,73 +22,7 @@
namespace zelda
{
/*!
* \brief The WiiImage class
*/
class WiiImage
{
public:
/*!
* \brief WiiImage
*/
WiiImage();
/*!
* \brief WiiImage
* \param width
* \param height
* \param data
*/
WiiImage(Uint32 width, Uint32 height, Uint8* data);
~WiiImage();
/*!
* \brief setWidth
* \param width
*/
void setWidth(const Uint32 width);
/*!
* \brief width
* \return
*/
Uint32 width() const;
/*!
* \brief setHeight
* \param height
*/
void setHeight(const Uint32 height);
/*!
* \brief height
* \return
*/
Uint32 height() const;
/*!
* \brief setData
* \param data
*/
void setData(const Uint8* data);
/*!
* \brief data
* \return
*/
Uint8* data();
/*!
* \brief toRGBA32 DOES NOT WORK!!! DO NOT USE!!!
* \return
*/
Uint8* toRGBA32();
private:
Uint32 m_width;
Uint32 m_height;
Uint8* m_data;
};
class WiiImage;
/*! \class WiiBanner
* \brief Wii banner container class
*

View File

@ -17,6 +17,9 @@
#include "Types.hpp"
namespace zelda
{
/*!
* \brief The WiiImage class
*/
@ -88,4 +91,6 @@ private:
Uint8* m_data;
};
} // zelda
#endif // WIIIMAGE_HPP

View File

@ -21,12 +21,14 @@
namespace zelda
{
class WiiSave;
class WiiBanner;
class WiiFile;
class WiiImage;
namespace io
{
/*! \class WiiSaveReader
* \brief Wii data.bin reader class
*
@ -36,6 +38,7 @@ class WiiImage;
*/
class WiiSaveReader : public io::BinaryReader
{
BINARYREADER_BASE
public:
/*! \brief This constructor takes an existing buffer to read from.
*
@ -62,5 +65,6 @@ private:
void readCerts(Uint32 totalSize);
};
} // io
} // zelda
#endif // __WII_SAVE_READER_HPP__

View File

@ -28,6 +28,9 @@ class WiiBanner;
class WiiFile;
class WiiImage;
namespace io
{
/*! \class WiiSaveWriter
* \brief Wii data.bin writer class
*
@ -37,6 +40,7 @@ class WiiImage;
*/
class WiiSaveWriter : public io::BinaryWriter
{
BINARYWRITER_BASE
public:
/*! \brief This constructor creates an instance from a file on disk.
*
@ -64,5 +68,6 @@ private:
void writeCerts(Uint32 filesSize, Uint32 ngId, Uint8* ngPriv, Uint8* ngSig, Uint32 ngKeyId);
};
} // io
} // zelda
#endif // __WII_SAVE_WRITER_HPP__

View File

@ -1,3 +1,18 @@
// This file is part of libZelda.
//
// libZelda is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// libZelda is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with libZelda. If not, see <http://www.gnu.org/licenses/>
#ifndef ZQUEST_HPP
#define ZQUEST_HPP
@ -7,17 +22,41 @@
namespace zelda
{
/*!
* \brief The ZQuest class
*/
class ZQuest
{
public:
/*!
* \brief Major
*/
static const Uint32 Major;
/*!
* \brief Minor
*/
static const Uint32 Minor;
/*!
* \brief Revision
*/
static const Uint32 Revision;
/*!
* \brief Build
*/
static const Uint32 Build;
/*!
* \brief Version
*/
static const Uint32 Version;
/*!
* \brief Magic
*/
static const Uint32 Magic;
/*!
* \brief The Game enum
*/
enum Game
{
NoGame,
@ -41,22 +80,73 @@ public:
ALinkBetweenWorlds // Not released
};
/*!
* \brief ZQuest
*/
ZQuest();
/*!
* \brief ZQuest
* \param game
* \param endian
* \param data
* \param length
*/
ZQuest(Game game, Endian endian, Uint8* data, Uint32 length);
~ZQuest();
/*!
* \brief setGame
* \param game
*/
void setGame(Game game);
/*!
* \brief game
* \return
*/
Game game() const;
/*!
* \brief setEndian
* \param endian
*/
void setEndian(Endian endian);
/*!
* \brief endian
* \return
*/
Endian endian() const;
/*!
* \brief setData
* \param data
*/
void setData(Uint8* data);
/*!
* \brief data
* \return
*/
Uint8* data() const;
/*!
* \brief setLength
* \param length
*/
void setLength(Uint32 length);
/*!
* \brief length
* \return
*/
Uint32 length() const;
/*!
* \brief gameString
* \return
*/
std::string gameString() const;
private:
Game m_game;

View File

@ -1,22 +1,57 @@
#ifndef ZQUESTFILEREADER_HPP
#define ZQUESTFILEREADER_HPP
// This file is part of libZelda.
//
// libZelda is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// libZelda is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with libZelda. If not, see <http://www.gnu.org/licenses/>
#ifndef __ZQUESTFILEREADER_HPP__
#define __ZQUESTFILEREADER_HPP__
#include "BinaryReader.hpp"
namespace zelda
{
class ZQuest;
namespace io
{
/*!
* \brief The ZQuestFileReader class
*/
class ZQuestFileReader : public io::BinaryReader
{
BINARYREADER_BASE
public:
/*!
* \brief ZQuestFileReader
* \param data
* \param length
*/
ZQuestFileReader(Uint8* data, Uint64 length);
/*!
* \brief ZQuestFileReader
* \param filename
*/
ZQuestFileReader(const std::string& filename);
/*!
* \brief read
* \return
*/
ZQuest* read();
};
} // io
} // zelda
#endif // ZQUESTFILEREADER_HPP
#endif // __ZQUESTFILEREADER_HPP__

View File

@ -1,5 +1,20 @@
#ifndef ZQUESTFILEWRITER_HPP
#define ZQUESTFILEWRITER_HPP
// This file is part of libZelda.
//
// libZelda is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// libZelda is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with libZelda. If not, see <http://www.gnu.org/licenses/>
#ifndef __ZQUESTFILEWRITER_HPP__
#define __ZQUESTFILEWRITER_HPP__
#include <BinaryWriter.hpp>
@ -7,15 +22,38 @@ namespace zelda
{
class ZQuest;
namespace io
{
/*!
* \brief The ZQuestFileWriter class
*/
class ZQuestFileWriter : public io::BinaryWriter
{
BINARYWRITER_BASE
public:
/*!
* \brief ZQuestFileWriter
* \param data
* \param length
*/
ZQuestFileWriter(Uint8* data, Uint64 length);
/*!
* \brief ZQuestFileWriter
* \param filename
*/
ZQuestFileWriter(const std::string& filename);
/*!
* \brief write
* \param quest
* \param compress
*/
void write(ZQuest* quest, bool compress = true);
};
}
#endif // ZQUESTFILEWRITER_HPP
} // io
} // zelda
#endif // __ZQUESTFILEWRITER_HPP__

View File

@ -1,6 +1,15 @@
CONFIG += staticlib
TEMPLATE=lib
CONFIG(debug, debug|release){
DEFINES += DEBUG
TARGET=zelda-d
}
CONFIG(release, release|debug){
DEFINES -= DEBUG
TARGET=zelda
}
QMAKE_CXXFLAGS += -std=c++0x
INCLUDEPATH += include
@ -42,7 +51,8 @@ HEADERS += \
include/ZQuestFileWriter.hpp \
include/ZQuestFileReader.hpp \
include/ZQuest.hpp \
include/Compression.hpp
include/Compression.hpp \
include/WiiImage.hpp
SOURCES += \
src/utility.cpp \
@ -70,7 +80,8 @@ SOURCES += \
src/ZQuestFileWriter.cpp \
src/ZQuestFileReader.cpp \
src/ZQuest.cpp \
src/Compression.cpp
src/Compression.cpp \
src/WiiImage.cpp
system("exec doxygen libzelda.conf")
#system("cd doc/latex && make")

View File

@ -32,7 +32,7 @@ ALTTPFile::ALTTPFile(std::vector<ALTTPQuest*> quests, std::vector<ALTTPQuest*> b
void ALTTPFile::setQuest(Uint32 id, ALTTPQuest* val)
{
if (id > m_quests.size())
throw InvalidOperationException("ALTTPFile::setQuest(Uint32, ALTTPQuest*) -> index out of range");
throw error::InvalidOperationException("ALTTPFile::setQuest -> index out of range");
m_quests[id] = val;
}
@ -44,7 +44,7 @@ std::vector<ALTTPQuest*> ALTTPFile::questList() const
ALTTPQuest* ALTTPFile::quest(Uint32 id) const
{
if (id > m_quests.size())
throw InvalidOperationException("ALTTPFile::setQuest(Uint32) -> index out of range");
throw error::InvalidOperationException("ALTTPFile::setQuest -> index out of range");
return m_quests[id];
}

View File

@ -20,14 +20,16 @@
namespace zelda
{
namespace io
{
ALTTPFileReader::ALTTPFileReader(Uint8* data, Uint64 length)
: BinaryReader(data, length)
: base(data, length)
{
}
ALTTPFileReader::ALTTPFileReader(const std::string& filename)
: BinaryReader(filename)
: base(filename)
{
}
@ -61,21 +63,21 @@ ALTTPFile* ALTTPFileReader::readFile()
quest->setOverworldEvents(owEvents);
quest->setInventory((ALTTPInventory*)this->readBytes(sizeof(ALTTPInventory)));
quest->setRupeeMax(this->readUInt16());
quest->setRupeeCurrent(this->readUInt16());
quest->setInventory((ALTTPInventory*)base::readBytes(sizeof(ALTTPInventory)));
quest->setRupeeMax(base::readUInt16());
quest->setRupeeCurrent(base::readUInt16());
quest->setCompasses(readDungeonFlags());
quest->setBigKeys(readDungeonFlags());
quest->setDungeonMaps(readDungeonFlags());
quest->setWishingPond(this->readUInt16());
quest->setHealthMax(this->readByte());
quest->setHealth(this->readByte());
quest->setMagicPower(this->readByte());
quest->setKeys(this->readByte());
quest->setBombUpgrades(this->readByte());
quest->setArrowUpgrades(this->readByte());
quest->setHealthFiller(this->readByte());
quest->setMagicFiller(this->readByte());
quest->setWishingPond(base::readUInt16());
quest->setHealthMax(base::readByte());
quest->setHealth(base::readByte());
quest->setMagicPower(base::readByte());
quest->setKeys(base::readByte());
quest->setBombUpgrades(base::readByte());
quest->setArrowUpgrades(base::readByte());
quest->setHealthFiller(base::readByte());
quest->setMagicFiller(base::readByte());
ALTTPPendants pendants;
pendants.Courage = readBit();
pendants.Wisdom = readBit();
@ -86,53 +88,53 @@ ALTTPFile* ALTTPFileReader::readFile()
pendants.Unused4 = false;
pendants.Unused5 = false;
quest->setPendants(pendants);
quest->setBombFiller(this->readByte());
quest->setArrowFiller(this->readByte());
quest->setArrows(this->readByte());
this->seek(1);
quest->setBombFiller(base::readByte());
quest->setArrowFiller(base::readByte());
quest->setArrows(base::readByte());
base::seek(1);
ALTTPAbilities abilities;
abilities.Nothing = this->readBit();
abilities.Swim = this->readBit();
abilities.Dash = this->readBit();
abilities.Pull = this->readBit();
abilities.Unknown1 = this->readBit();
abilities.Talk = this->readBit();
abilities.Read = this->readBit();
abilities.Unknown2 = this->readBit();
abilities.Nothing = base::readBit();
abilities.Swim = base::readBit();
abilities.Dash = base::readBit();
abilities.Pull = base::readBit();
abilities.Unknown1 = base::readBit();
abilities.Talk = base::readBit();
abilities.Read = base::readBit();
abilities.Unknown2 = base::readBit();
quest->setAbilityFlags(abilities);
quest->setCrystals((ALTTPCrystals&)*this->readBytes(sizeof(ALTTPCrystals)));
quest->setMagicUsage((ALTTPMagicUsage&)*this->readBytes(sizeof(ALTTPMagicUsage)));
quest->setCrystals((ALTTPCrystals&)*base::readBytes(sizeof(ALTTPCrystals)));
quest->setMagicUsage((ALTTPMagicUsage&)*base::readBytes(sizeof(ALTTPMagicUsage)));
j = 0x10;
while ((j--) > 0)
{
dungeonKeys.push_back(this->readByte());
dungeonKeys.push_back(base::readByte());
}
quest->setDungeonKeys(dungeonKeys);
seek(0x039);
quest->setProgressIndicator((ALTTPProgressIndicator)this->readByte());
quest->setProgressFlags1((ALTTPProgressFlags1&)*this->readBytes(sizeof(ALTTPProgressFlags1)));
quest->setMapIcon((ALTTPMapIcon)this->readByte());
quest->setStartLocation((ALTTPStartLocation)this->readByte());
quest->setProgressFlags2((ALTTPProgressFlags2&)*this->readBytes(sizeof(ALTTPProgressFlags2)));
quest->setLightDarkWorldIndicator((ALTTPLightDarkWorldIndicator&)*this->readBytes(1));
this->seek(1);
quest->setTagAlong((ALTTPTagAlong)this->readByte());
base::seek(0x039);
quest->setProgressIndicator((ALTTPProgressIndicator)base::readByte());
quest->setProgressFlags1((ALTTPProgressFlags1&)*base::readBytes(sizeof(ALTTPProgressFlags1)));
quest->setMapIcon((ALTTPMapIcon)base::readByte());
quest->setStartLocation((ALTTPStartLocation)base::readByte());
quest->setProgressFlags2((ALTTPProgressFlags2&)*base::readBytes(sizeof(ALTTPProgressFlags2)));
quest->setLightDarkWorldIndicator((ALTTPLightDarkWorldIndicator&)*base::readBytes(1));
base::seek(1);
quest->setTagAlong((ALTTPTagAlong)base::readByte());
j = 6;
while((j--) > 0)
{
oldmanFlags.push_back(this->readByte());
oldmanFlags.push_back(base::readByte());
}
quest->setOldManFlags(oldmanFlags);
quest->setBombFlag(this->readByte());
quest->setBombFlag(base::readByte());
j = 5;
while((j--) > 0)
{
unknown1.push_back(this->readByte());
unknown1.push_back(base::readByte());
}
quest->setUnknown1(unknown1);
@ -140,26 +142,26 @@ ALTTPFile* ALTTPFileReader::readFile()
j = 6;
while((j--) > 0)
{
playerName.push_back(this->readUInt16());
playerName.push_back(base::readUInt16());
}
quest->setPlayerName(playerName);
quest->setValid((this->readUInt16() == 0x55AA));
quest->setValid((base::readUInt16() == 0x55AA));
j = 0x0D;
while((j--) > 0)
{
dungeonDeaths.push_back(this->readUInt16());
dungeonDeaths.push_back(base::readUInt16());
}
quest->setDungeonDeathTotals(dungeonDeaths);
quest->setUnknown2(this->readUInt16());
quest->setDeathSaveCount(this->readUInt16());
quest->setPostGameDeathCounter(this->readInt16());
quest->setUnknown2(base::readUInt16());
quest->setDeathSaveCount(base::readUInt16());
quest->setPostGameDeathCounter(base::readInt16());
this->seek(0xF7);
base::seek(0xF7);
quest->setChecksum(this->readUInt16());
quest->setChecksum(base::readUInt16());
if (i < 3)
quests.push_back(quest);
@ -173,22 +175,22 @@ ALTTPFile* ALTTPFileReader::readFile()
ALTTPRoomFlags* ALTTPFileReader::readRoomFlags()
{
ALTTPRoomFlags* flags = new ALTTPRoomFlags;
flags->Chest1 = readBit();
flags->Chest2 = readBit();
flags->Chest3 = readBit();
flags->Chest4 = readBit();
flags->Quadrant1 = readBit();
flags->Quadrant2 = readBit();
flags->Quadrant3 = readBit();
flags->Quadrant4 = readBit();
flags->Door1 = readBit();
flags->Door2 = readBit();
flags->Door3 = readBit();
flags->Door4 = readBit();
flags->BossBattleWon = readBit();
flags->Key = readBit();
flags->KeyOrChest = readBit();
flags->ChestOrTile = readBit();
flags->Chest1 = base::readBit();
flags->Chest2 = base::readBit();
flags->Chest3 = base::readBit();
flags->Chest4 = base::readBit();
flags->Quadrant1 = base::readBit();
flags->Quadrant2 = base::readBit();
flags->Quadrant3 = base::readBit();
flags->Quadrant4 = base::readBit();
flags->Door1 = base::readBit();
flags->Door2 = base::readBit();
flags->Door3 = base::readBit();
flags->Door4 = base::readBit();
flags->BossBattleWon = base::readBit();
flags->Key = base::readBit();
flags->KeyOrChest = base::readBit();
flags->ChestOrTile = base::readBit();
return flags;
}
@ -196,37 +198,38 @@ ALTTPRoomFlags* ALTTPFileReader::readRoomFlags()
ALTTPOverworldEvent* ALTTPFileReader::readOverworldEvent()
{
ALTTPOverworldEvent* event = new ALTTPOverworldEvent;
event->Unused1 = readBit();
event->HeartPiece = readBit();
event->Overlay = readBit();
event->Unused2 = readBit();
event->Unused3 = readBit();
event->Unused4 = readBit();
event->Set = readBit();
event->Unused5 = readBit();
event->Unused1 = base::readBit();
event->HeartPiece = base::readBit();
event->Overlay = base::readBit();
event->Unused2 = base::readBit();
event->Unused3 = base::readBit();
event->Unused4 = base::readBit();
event->Set = base::readBit();
event->Unused5 = base::readBit();
return event;
}
ALTTPDungeonItemFlags ALTTPFileReader::readDungeonFlags()
{
ALTTPDungeonItemFlags flags;
flags.Unused1 = readBit();
flags.GanonsTower = readBit();
flags.TurtleRock = readBit();
flags.GargoylesDomain = readBit();
flags.TowerOfHera = readBit();
flags.IcePalace = readBit();
flags.SkullWoods = readBit();
flags.MiseryMire = readBit();
flags.DarkPalace = readBit();
flags.SwampPalace = readBit();
flags.HyruleCastle2 = readBit();
flags.DesertPalace = readBit();
flags.EasternPalace = readBit();
flags.HyruleCastle = readBit();
flags.SewerPassage = readBit();
flags.Unused1 = base::readBit();
flags.GanonsTower = base::readBit();
flags.TurtleRock = base::readBit();
flags.GargoylesDomain = base::readBit();
flags.TowerOfHera = base::readBit();
flags.IcePalace = base::readBit();
flags.SkullWoods = base::readBit();
flags.MiseryMire = base::readBit();
flags.DarkPalace = base::readBit();
flags.SwampPalace = base::readBit();
flags.HyruleCastle2 = base::readBit();
flags.DesertPalace = base::readBit();
flags.EasternPalace = base::readBit();
flags.HyruleCastle = base::readBit();
flags.SewerPassage = base::readBit();
return flags;
}
} // io
} // zelda

View File

@ -21,13 +21,16 @@
namespace zelda
{
namespace io
{
ALTTPFileWriter::ALTTPFileWriter(Uint8* data, Uint64 length)
: BinaryWriter(data, length)
: base(data, length)
{
}
ALTTPFileWriter::ALTTPFileWriter(const std::string& filename)
: BinaryWriter(filename)
: base(filename)
{
}
@ -43,142 +46,142 @@ void ALTTPFileWriter::writeFile(ALTTPFile* file)
for (int j = 0; j < 0x140; j++)
{
this->writeRoomFlags(quest->roomFlags(j));
writeRoomFlags(quest->roomFlags(j));
}
for (int j = 0; j < 0x0C0; j++)
{
this->writeOverworldEvent(quest->overworldEvent(j));
writeOverworldEvent(quest->overworldEvent(j));
}
this->writeBytes((Int8*)quest->inventory(), sizeof(ALTTPInventory));
this->writeUInt16(quest->rupeeMax());
this->writeUInt16(quest->rupeeCurrent());
this->writeDungeonItems(quest->compasses());
this->writeDungeonItems(quest->bigKeys());
this->writeDungeonItems(quest->dungeonMaps());
this->writeUInt16(quest->wishingPond());
this->writeByte(quest->healthMax());
this->writeByte(quest->health());
this->writeByte(quest->magicPower());
this->writeByte(quest->keys());
this->writeByte(quest->bombUpgrades());
this->writeByte(quest->arrowUpgrades());
this->writeByte(quest->healthFiller());
this->writeByte(quest->magicFiller());
base::writeBytes((Int8*)quest->inventory(), sizeof(ALTTPInventory));
base::writeUInt16(quest->rupeeMax());
base::writeUInt16(quest->rupeeCurrent());
writeDungeonItems(quest->compasses());
writeDungeonItems(quest->bigKeys());
writeDungeonItems(quest->dungeonMaps());
base::writeUInt16(quest->wishingPond());
base::writeByte(quest->healthMax());
base::writeByte(quest->health());
base::writeByte(quest->magicPower());
base::writeByte(quest->keys());
base::writeByte(quest->bombUpgrades());
base::writeByte(quest->arrowUpgrades());
base::writeByte(quest->healthFiller());
base::writeByte(quest->magicFiller());
ALTTPPendants pendants = quest->pendants();
this->writeBit(pendants.Courage);
this->writeBit(pendants.Wisdom);
this->writeBit(pendants.Power);
this->writeByte(quest->bombFiller());
this->writeByte(quest->arrowFiller());
this->writeByte(quest->arrows());
this->seek(1);
base::writeBit(pendants.Courage);
base::writeBit(pendants.Wisdom);
base::writeBit(pendants.Power);
base::writeByte(quest->bombFiller());
base::writeByte(quest->arrowFiller());
base::writeByte(quest->arrows());
base::seek(1);
ALTTPAbilities abilities = quest->abilityFlags();
this->writeBit(abilities.Nothing);
this->writeBit(abilities.Swim);
this->writeBit(abilities.Dash);
this->writeBit(abilities.Pull);
this->writeBit(abilities.Unknown1);
this->writeBit(abilities.Talk);
this->writeBit(abilities.Read);
this->writeBit(abilities.Unknown2);
base::writeBit(abilities.Nothing);
base::writeBit(abilities.Swim);
base::writeBit(abilities.Dash);
base::writeBit(abilities.Pull);
base::writeBit(abilities.Unknown1);
base::writeBit(abilities.Talk);
base::writeBit(abilities.Read);
base::writeBit(abilities.Unknown2);
ALTTPCrystals crystals = quest->crystals();
this->writeBytes((Int8*)&crystals, sizeof(ALTTPCrystals));
base::writeBytes((Int8*)&crystals, sizeof(ALTTPCrystals));
ALTTPMagicUsage magicUsage = quest->magicUsage();
this->writeBytes((Int8*)&magicUsage, sizeof(ALTTPMagicUsage));
base::writeBytes((Int8*)&magicUsage, sizeof(ALTTPMagicUsage));
for (int j = 0; j < 0x010; j++)
this->writeByte(quest->dungeonKeys(j));
base::writeByte(quest->dungeonKeys(j));
seek(0x039);
this->writeByte((Int8)quest->progressIndicator());
base::seek(0x039);
base::writeByte((Int8)quest->progressIndicator());
ALTTPProgressFlags1 progress1 = quest->progressFlags1();
this->writeBytes((Int8*)&progress1, sizeof(ALTTPProgressFlags1));
this->writeByte(quest->mapIcon());
this->writeByte(quest->startLocation());
base::writeBytes((Int8*)&progress1, sizeof(ALTTPProgressFlags1));
base::writeByte(quest->mapIcon());
base::writeByte(quest->startLocation());
ALTTPProgressFlags2 progress2 = quest->progressFlags2();
this->writeBytes((Int8*)&progress2, sizeof(ALTTPProgressFlags2));
base::writeBytes((Int8*)&progress2, sizeof(ALTTPProgressFlags2));
ALTTPLightDarkWorldIndicator indicator = quest->lightDarkWorldIndicator();
this->writeBytes((Int8*)&indicator, 1);
this->seek(1);
this->writeByte(quest->tagAlong());
base::writeBytes((Int8*)&indicator, 1);
base::seek(1);
base::writeByte(quest->tagAlong());
for(int j = 0; j < 6; j++)
this->writeByte(quest->oldManFlag(j));
base::writeByte(quest->oldManFlag(j));
this->writeByte(quest->bombFlag());
base::writeByte(quest->bombFlag());
for (int j = 0; j < 5; j++)
this->writeByte(quest->unknown1(j));
base::writeByte(quest->unknown1(j));
for (int j = 0; j < 6; j++)
this->writeUInt16(quest->playerName()[j]);
base::writeUInt16(quest->playerName()[j]);
this->writeUInt16((quest->valid() == true ? 0x55AA : 0));
base::writeUInt16((quest->valid() == true ? 0x55AA : 0));
for (int j = 0; j < 0x0D; j++)
this->writeUInt16(quest->dungeonDeathTotal(j));
base::writeUInt16(quest->dungeonDeathTotal(j));
this->writeUInt16(quest->unknown2());
this->writeUInt16(quest->deathSaveCount());
this->writeUInt16(quest->postGameDeathCounter());
base::writeUInt16(quest->unknown2());
base::writeUInt16(quest->deathSaveCount());
base::writeUInt16(quest->postGameDeathCounter());
this->seek(0xF7);
this->writeUInt16(calculateChecksum(i));
base::seek(0xF7);
base::writeUInt16(calculateChecksum(i));
}
}
void ALTTPFileWriter::writeRoomFlags(ALTTPRoomFlags* flags)
{
writeBit(flags->Chest1);
writeBit(flags->Chest2);
writeBit(flags->Chest3);
writeBit(flags->Chest4);
writeBit(flags->Quadrant1);
writeBit(flags->Quadrant2);
writeBit(flags->Quadrant3);
writeBit(flags->Quadrant4);
writeBit(flags->Door1);
writeBit(flags->Door2);
writeBit(flags->Door3);
writeBit(flags->Door4);
writeBit(flags->BossBattleWon);
writeBit(flags->Key);
writeBit(flags->KeyOrChest);
writeBit(flags->ChestOrTile);
base::writeBit(flags->Chest1);
base::writeBit(flags->Chest2);
base::writeBit(flags->Chest3);
base::writeBit(flags->Chest4);
base::writeBit(flags->Quadrant1);
base::writeBit(flags->Quadrant2);
base::writeBit(flags->Quadrant3);
base::writeBit(flags->Quadrant4);
base::writeBit(flags->Door1);
base::writeBit(flags->Door2);
base::writeBit(flags->Door3);
base::writeBit(flags->Door4);
base::writeBit(flags->BossBattleWon);
base::writeBit(flags->Key);
base::writeBit(flags->KeyOrChest);
base::writeBit(flags->ChestOrTile);
}
void ALTTPFileWriter::writeOverworldEvent(ALTTPOverworldEvent* event)
{
writeBit(event->Unused1);
writeBit(event->HeartPiece);
writeBit(event->Overlay);
writeBit(event->Unused2);
writeBit(event->Unused3);
writeBit(event->Unused4);
writeBit(event->Set);
writeBit(event->Unused5);
base::writeBit(event->Unused1);
base::writeBit(event->HeartPiece);
base::writeBit(event->Overlay);
base::writeBit(event->Unused2);
base::writeBit(event->Unused3);
base::writeBit(event->Unused4);
base::writeBit(event->Set);
base::writeBit(event->Unused5);
}
void ALTTPFileWriter::writeDungeonItems(ALTTPDungeonItemFlags flags)
{
writeBit(flags.Unused1);
writeBit(flags.Unused2);
writeBit(flags.GanonsTower);
writeBit(flags.TurtleRock);
writeBit(flags.TowerOfHera);
writeBit(flags.IcePalace);
writeBit(flags.SkullWoods);
writeBit(flags.MiseryMire);
writeBit(flags.DarkPalace);
writeBit(flags.SwampPalace);
writeBit(flags.HyruleCastle2);
writeBit(flags.DesertPalace);
writeBit(flags.EasternPalace);
writeBit(flags.HyruleCastle);
writeBit(flags.SewerPassage);
base::writeBit(flags.Unused1);
base::writeBit(flags.Unused2);
base::writeBit(flags.GanonsTower);
base::writeBit(flags.TurtleRock);
base::writeBit(flags.TowerOfHera);
base::writeBit(flags.IcePalace);
base::writeBit(flags.SkullWoods);
base::writeBit(flags.MiseryMire);
base::writeBit(flags.DarkPalace);
base::writeBit(flags.SwampPalace);
base::writeBit(flags.HyruleCastle2);
base::writeBit(flags.DesertPalace);
base::writeBit(flags.EasternPalace);
base::writeBit(flags.HyruleCastle);
base::writeBit(flags.SewerPassage);
}
Uint16 ALTTPFileWriter::calculateChecksum(Uint32 game)
@ -215,4 +218,5 @@ Uint16 ALTTPFileWriter::calculateChecksum(Uint32 game)
*/
}
} // io
} // zelda

View File

@ -71,7 +71,7 @@ std::vector<ALTTPOverworldEvent*> ALTTPQuest::overworldEvents() const
ALTTPOverworldEvent* ALTTPQuest::overworldEvent(Uint32 id) const
{
if (id > m_overworldEvents.size() - 1)
throw InvalidOperationException("ALTTPQuest::overworldEvents(Uint32) -> index out of range");
throw error::InvalidOperationException("ALTTPQuest::overworldEvents -> index out of range");
return m_overworldEvents[id];
}
@ -301,7 +301,7 @@ void ALTTPQuest::setDungeonKeys(std::vector<Uint8> val)
void ALTTPQuest::setDungeonKeys(Uint32 id, Uint8 val)
{
if (id > m_dungeonKeys.size() - 1)
throw InvalidOperationException("ALTTPQuest::setDungeonKeys(Uint32, Uint8) -> index out of range");
throw error::InvalidOperationException("ALTTPQuest::setDungeonKeys -> index out of range");
m_dungeonKeys[id] = val;
}
@ -309,7 +309,7 @@ void ALTTPQuest::setDungeonKeys(Uint32 id, Uint8 val)
Uint8 ALTTPQuest::dungeonKeys(Uint32 id) const
{
if (id > m_dungeonKeys.size() - 1)
throw InvalidOperationException("ALTTPQuest::dungeonKeys() -> index out of range");
throw error::InvalidOperationException("ALTTPQuest::dungeonKeys -> index out of range");
return m_dungeonKeys[id];
}
@ -398,7 +398,7 @@ void ALTTPQuest::setOldManFlags(std::vector<Uint8> flags)
void ALTTPQuest::setOldManFlag(Uint32 id, Uint8 val)
{
if (id > m_oldManFlags.size() - 1)
throw InvalidOperationException("ALTTPQuest::setOldManFlag(Uint32, Uint8) -> index out of range");
throw error::InvalidOperationException("ALTTPQuest::setOldManFlag -> index out of range");
m_oldManFlags[id] = val;
}
@ -406,7 +406,7 @@ void ALTTPQuest::setOldManFlag(Uint32 id, Uint8 val)
Uint8 ALTTPQuest::oldManFlag(Uint32 id)
{
if (id > m_oldManFlags.size() - 1)
throw InvalidOperationException("ALTTPQuest::oldManFlag(Uint32) -> index out of range");
throw error::InvalidOperationException("ALTTPQuest::oldManFlag -> index out of range");
return m_oldManFlags[id];
}
@ -434,7 +434,7 @@ void ALTTPQuest::setUnknown1(std::vector<Uint8> flags)
void ALTTPQuest::setUnknown1(Uint32 id, Uint8 val)
{
if (id > m_unknown1.size())
throw InvalidOperationException("ALTTPQuest::setUnknown1(Uint32, Uint8) -> index out of range");
throw error::InvalidOperationException("ALTTPQuest::setUnknown1) -> index out of range");
m_unknown1[id] = val;
}
@ -442,7 +442,7 @@ void ALTTPQuest::setUnknown1(Uint32 id, Uint8 val)
Uint8 ALTTPQuest::unknown1(Uint32 id)
{
if (id > m_unknown1.size())
throw InvalidOperationException("ALTTPQuest::unknown1(Uint32) -> index out of range");
throw error::InvalidOperationException("ALTTPQuest::unknown1 -> index out of range");
return m_unknown1[id];
}
@ -460,7 +460,7 @@ void ALTTPQuest::setPlayerName(std::vector<Uint16> playerName)
void ALTTPQuest::setPlayerName(const std::string& playerName)
{
if (playerName == std::string() || playerName.size() > 6)
throw InvalidOperationException("ALTTPQuest::setPlayerName(const std::string&) -> playerName invalid");
throw error::InvalidOperationException("ALTTPQuest::setPlayerName -> playerName invalid");
m_playerName.clear();
@ -623,7 +623,7 @@ void ALTTPQuest::setDungeonDeathTotals(std::vector<Uint16> val)
void ALTTPQuest::setDungeonDeathTotal(Uint32 id, Uint16 val)
{
if (id > m_dungeonDeathTotals.size())
throw InvalidOperationException("ALTTPQuest::setDungeonDeathTotal(Uint32, Uint16) -> index out of range");
throw error::InvalidOperationException("ALTTPQuest::setDungeonDeathTotal -> index out of range");
m_dungeonDeathTotals[id] = val;
}
@ -631,7 +631,7 @@ void ALTTPQuest::setDungeonDeathTotal(Uint32 id, Uint16 val)
Uint16 ALTTPQuest::dungeonDeathTotal(Uint32 id) const
{
if (id > m_dungeonDeathTotals.size())
throw InvalidOperationException("ALTTPQuest::setDungeonDeathTotal(Uint32) -> index out of range");
throw error::InvalidOperationException("ALTTPQuest::setDungeonDeathTotal -> index out of range");
return m_dungeonDeathTotals[id];
}

View File

@ -50,7 +50,7 @@ BinaryReader::BinaryReader(const std::string& filename)
in = fopen(filename.c_str(), "rb");
if (!in)
throw FileNotFoundException(filename);
throw error::FileNotFoundException(filename);
fseek(in, 0, SEEK_END);
length = ftell(in);
@ -67,7 +67,7 @@ BinaryReader::BinaryReader(const std::string& filename)
Int32 ret = fread(m_data + done, 1, blocksize, in);
if (ret < 0)
throw IOException("Error readin data from disk");
throw error::IOException("BinaryReader::BinaryReader -> reading data from disk");
else if (ret == 0)
break;
@ -82,12 +82,12 @@ BinaryReader::BinaryReader(const std::string& filename)
void BinaryReader::writeByte(Int8)
{
throw IOException("BinaryReader::writeByte() -> Stream not open for writing");
throw error::IOException("BinaryReader::writeByte -> Stream not open for writing");
}
void BinaryReader::writeBytes(Int8*, Int64)
{
throw IOException("BinaryReader::writeBytes() -> Stream not open for writing");
throw error::IOException("BinaryReader::writeBytes -> Stream not open for writing");
}
Int16 BinaryReader::readInt16()
@ -99,7 +99,7 @@ Int16 BinaryReader::readInt16()
}
if (m_position + sizeof(Int16) > m_length)
throw IOException("BinaryReader::readInt16() -> Position outside stream bounds");
throw error::IOException("BinaryReader::readInt16 -> Position outside stream bounds");
Int16 ret = *(Int16*)(m_data + m_position);
m_position += 2;
@ -116,7 +116,7 @@ Uint16 BinaryReader::readUInt16()
m_position += sizeof(Uint8);
}
if (m_position + sizeof(Uint16) > m_length)
throw IOException("BinaryReader::readUint16() -> Position outside stream bounds");
throw error::IOException("BinaryReader::readUint16 -> Position outside stream bounds");
Uint16 ret = *(Uint16*)(m_data + m_position);
m_position += 2;
@ -134,7 +134,7 @@ Int32 BinaryReader::readInt32()
m_position += sizeof(Uint8);
}
if (m_position + sizeof(Int32) > m_length)
throw IOException("BinaryReader::readUint32() -> Position outside stream bounds");
throw error::IOException("BinaryReader::readUint32 -> Position outside stream bounds");
Int32 ret = *(Int32*)(m_data + m_position);
m_position += 4;
@ -151,7 +151,7 @@ Uint32 BinaryReader::readUInt32()
m_position += sizeof(Uint8);
}
if (m_position + sizeof(Uint32) > m_length)
throw IOException("BinaryReader::readUint32() -> Position outside stream bounds");
throw error::IOException("BinaryReader::readUint32 -> Position outside stream bounds");
Uint32 ret = *(Uint32*)(m_data + m_position);
m_position += 4;
@ -169,7 +169,7 @@ Int64 BinaryReader::readInt64()
m_position += sizeof(Uint8);
}
if (m_position + sizeof(Int64) > m_length)
throw IOException("BinaryReader::readInt64() -> Position outside stream bounds");
throw error::IOException("BinaryReader::readInt64 -> Position outside stream bounds");
Int64 ret = *(Int64*)(m_data + m_position);
m_position += 8;
@ -187,7 +187,7 @@ Uint64 BinaryReader::readUInt64()
m_position += sizeof(Uint8);
}
if (m_position + sizeof(Uint64) > m_length)
throw IOException("BinaryReader::readUInt64() -> Position outside stream bounds");
throw error::IOException("BinaryReader::readUInt64 -> Position outside stream bounds");
Uint64 ret = *(Uint64*)(m_data + m_position);
m_position += 8;
@ -204,7 +204,7 @@ float BinaryReader::readFloat()
m_position += sizeof(Uint8);
}
if (m_position + sizeof(float) > m_length)
throw IOException("BinaryReader::readFloat() -> Position outside stream bounds");
throw error::IOException("BinaryReader::readFloat -> Position outside stream bounds");
float ret = *(float*)(m_data + m_position);
m_position += 4;
@ -222,7 +222,7 @@ double BinaryReader::readDouble()
m_position += sizeof(Uint8);
}
if (m_position + sizeof(double) > m_length)
throw IOException("BinaryReader::readDouble() -> Position outside stream bounds");
throw error::IOException("BinaryReader::readDouble -> Position outside stream bounds");
double ret = *(double*)(m_data + m_position);
m_position += 8;
@ -241,7 +241,7 @@ bool BinaryReader::readBool()
m_position += sizeof(Uint8);
}
if (m_position + sizeof(bool) > m_length)
throw IOException("BinaryReader::readBool() -> Position outside stream bounds");
throw error::IOException("BinaryReader::readBool -> Position outside stream bounds");
bool ret = *(bool*)(m_data + m_position);
m_position += 1;

View File

@ -15,6 +15,7 @@
#include "BinaryWriter.hpp"
#include "IOException.hpp"
#include "InvalidOperationException.hpp"
#include "FileNotFoundException.hpp"
#include "utility.hpp"
#include "utf8.h"
@ -45,21 +46,21 @@ BinaryWriter::BinaryWriter(const std::string& filename)
m_position = 0;
m_data = new Uint8[m_length];
if (!m_data)
throw IOException("Could not allocate memory!");
throw error::IOException("BinaryWriter::BinaryWriter -> Could not allocate memory!");
memset(m_data, 0, m_length);
}
void BinaryWriter::save(const std::string& filename)
{
if (filename.empty() && m_filepath.empty())
throw Exception("InvalidOperationException: BinaryWriter::Save() -> No file specified, cannot save.");
throw error::InvalidOperationException("BinaryWriter::save -> No file specified, cannot save.");
if (!filename.empty())
m_filepath = filename;
FILE* out = fopen(m_filepath.c_str(), "wb");
if (!out)
throw FileNotFoundException(m_filepath);
throw error::FileNotFoundException(m_filepath);
Uint32 done = 0;
Uint32 blocksize = BLOCKSZ;
@ -71,7 +72,7 @@ void BinaryWriter::save(const std::string& filename)
Int32 ret = fwrite(m_data + done, 1, blocksize, out);
if (ret < 0)
throw IOException("Error writing data to disk");
throw error::IOException("BinaryWriter::save Error writing data to disk");
else if (ret == 0)
break;
@ -83,12 +84,12 @@ void BinaryWriter::save(const std::string& filename)
Int8 BinaryWriter::readByte()
{
throw IOException("Stream not open for reading");
throw error::IOException("BinaryWriter::readByte -> Stream not open for reading");
}
Int8* BinaryWriter::readBytes(Int64)
{
throw IOException("Stream not open for reading");
throw error::IOException("BinaryWriter::readBytes -> Stream not open for reading");
}
void BinaryWriter::writeInt16(Int16 val)
@ -102,7 +103,7 @@ void BinaryWriter::writeInt16(Int16 val)
if (m_position + sizeof(Int16) > m_length && m_autoResize)
resize(m_position + sizeof(Int16));
else if (m_position > m_length)
throw IOException("BinaryWriter::WriteInt16() -> Position outside stream bounds");
throw error::IOException("BinaryWriter::WriteInt16 -> Position outside stream bounds");
if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian))
val = swap16(val);
@ -122,7 +123,7 @@ void BinaryWriter::writeUInt16(Uint16 val)
if (m_position + sizeof(Uint16) > m_length && m_autoResize)
resize(m_position + sizeof(Uint16));
else if (m_position > m_length)
throw IOException("BinaryWriter::WriteUInt16() -> Position outside stream bounds");
throw error::IOException("BinaryWriter::WriteUInt16 -> Position outside stream bounds");
if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian))
@ -143,7 +144,7 @@ void BinaryWriter::writeInt32(Int32 val)
if (m_position + sizeof(Int32) > m_length && m_autoResize)
resize(m_position + sizeof(Int32));
else if (m_position > m_length)
throw IOException("BinaryWriter::WriteInt32() -> Position outside stream bounds");
throw error::IOException("BinaryWriter::WriteInt32 -> Position outside stream bounds");
if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian))
val = swap32(val);
@ -163,7 +164,7 @@ void BinaryWriter::writeUInt32(Uint32 val)
if (m_position + sizeof(Uint32) > m_length && m_autoResize)
resize(m_position + sizeof(Uint32));
else if (m_position > m_length)
throw IOException("BinaryWriter::WriteUInt32() -> Position outside stream bounds");
throw error::IOException("BinaryWriter::WriteUInt32 -> Position outside stream bounds");
if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian))
val = swap32(val);
@ -183,7 +184,7 @@ void BinaryWriter::writeInt64(Int64 val)
if (m_position + sizeof(Int64) > m_length && m_autoResize)
resize(m_position + sizeof(Int64));
else if (m_position > m_length)
throw IOException("BinaryWriter::WriteInt64() -> Position outside stream bounds");
throw error::IOException("BinaryWriter::WriteInt64 -> Position outside stream bounds");
if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian))
@ -204,7 +205,7 @@ void BinaryWriter::writeUInt64(Uint64 val)
if (m_position + sizeof(Uint64) > m_length && m_autoResize)
resize(m_position + sizeof(Uint64));
else if (m_position > m_length)
throw IOException("BinaryWriter::WriteUInt64() -> Position outside stream bounds");
throw error::IOException("BinaryWriter::WriteUInt64 -> Position outside stream bounds");
if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian))
val = swap64(val);
@ -224,7 +225,7 @@ void BinaryWriter::writeFloat(float val)
if (m_position + sizeof(float) > m_length && m_autoResize)
resize(m_position + sizeof(float));
else if (m_position > m_length)
throw IOException("BinaryWriter::WriteFloat() -> Position outside stream bounds");
throw error::IOException("BinaryWriter::WriteFloat -> Position outside stream bounds");
if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian))
val = swapFloat(val);
@ -244,7 +245,7 @@ void BinaryWriter::writeDouble(double val)
if (m_position + sizeof(double) > m_length && m_autoResize)
resize(m_position + sizeof(double));
else if (m_position > m_length)
throw IOException("BinaryWriter::WriteDouble() -> Position outside stream bounds");
throw error::IOException("BinaryWriter::WriteDouble -> Position outside stream bounds");
if ((!isSystemBigEndian() && m_endian == BigEndian) || (isSystemBigEndian() && m_endian == LittleEndian))
val = swapDouble(val);
@ -264,7 +265,7 @@ void BinaryWriter::writeBool(bool val)
if (m_position + sizeof(bool) > m_length && m_autoResize)
resize(m_position + sizeof(bool));
else if (m_position > m_length)
throw IOException("BinaryWriter::WriteBool() -> Position outside stream bounds");
throw error::IOException("BinaryWriter::WriteBool -> Position outside stream bounds");
*(bool*)(m_data + m_position) = val;

View File

@ -1,3 +1,18 @@
// This file is part of libZelda.
//
// libZelda is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// libZelda is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with libZelda. If not, see <http://www.gnu.org/licenses/>
#include "Compression.hpp"
#include <zlib.h>

View File

@ -18,14 +18,18 @@
namespace zelda
{
namespace io
{
MCFileReader::MCFileReader(Uint8* data, Uint64 length)
: BinaryReader(data, length)
: base(data, length)
{
}
MCFileReader::MCFileReader(const std::string& filename)
: BinaryReader(filename)
: base(filename)
{
}
} // io
} // zelda

View File

@ -19,12 +19,12 @@ namespace zelda
{
MCFileWriter::MCFileWriter(Uint8* data, Uint64 length)
: io::BinaryWriter(data, length)
: base(data, length)
{
}
MCFileWriter::MCFileWriter(const std::string& filename)
: io::BinaryWriter(filename)
: base(filename)
{
}

View File

@ -42,7 +42,7 @@ Stream::Stream(const Uint8* data, Uint64 length) :
m_autoResize(true)
{
if (length <= 0)
throw InvalidOperationException("Length cannot be <= to 0");
throw error::InvalidOperationException("Stream::Stream -> Length cannot be <= to 0");
m_length = length;
if (data)
@ -90,7 +90,7 @@ void Stream::writeBit(bool val)
if (m_position + sizeof(Uint8) > m_length && m_autoResize)
resize(m_position + sizeof(Uint8));
else if (m_position > m_length)
throw IOException("Stream::writeBit() -> Position outside stream bounds");
throw error::IOException("Stream::writeBit() -> Position outside stream bounds");
*(Uint8*)(m_data + m_position) |= ((Uint32)val << m_bitPosition);
m_bitPosition++;
@ -116,7 +116,7 @@ void Stream::writeByte(Int8 byte)
if (m_position + 1 > m_length && m_autoResize)
resize(m_position + 1);
else if (m_position > m_length)
throw IOException("Stream::writeByte() -> Position outside stream bounds");
throw error::IOException("Stream::writeByte() -> Position outside stream bounds");
*(Int8*)(m_data + m_position) = byte;
m_position++;
@ -136,11 +136,11 @@ void Stream::writeBytes(Int8* data, Int64 length)
}
if (!data)
throw InvalidOperationException("BinaryWriter::writeBytes() -> data cannnot be NULL");
throw error::InvalidOperationException("Stream::writeBytes -> data cannnot be NULL");
if (m_position + length > m_length && m_autoResize)
resize(m_position + length);
else if (m_position > m_length)
throw IOException("BinaryWriter::writeBytes() -> Position outside stream bounds");
throw error::IOException("Stream::writeBytes -> Position outside stream bounds");
memcpy((Int8*)(m_data + m_position), data, length);
@ -153,7 +153,7 @@ bool Stream::readBit()
if (m_position + sizeof(Uint8) > m_length && m_autoResize)
resize(m_position + sizeof(Uint8));
else if (m_position > m_length)
throw IOException("BinaryWriter::WriteInt16() -> Position outside stream bounds");
throw error::IOException("Stream::writeInt16 -> Position outside stream bounds");
bool ret = (*(Uint8*)(m_data + m_position) & (1 << m_bitPosition));
@ -175,7 +175,7 @@ Int8 Stream::readByte()
m_position += sizeof(Uint8);
}
if (m_position + 1 > m_length)
throw IOException("Position passed stream bounds");
throw error::IOException("Stream::readByte -> Position passed stream bounds");
return *(Int8*)(m_data + m_position++);
}
@ -189,7 +189,7 @@ Int8* Stream::readBytes(Int64 length)
}
if (m_position + length > m_length)
throw IOException("Position passed stream bounds: " + m_position);
throw error::IOException("Stream::readBytes -> Position passed stream bounds: " + m_position);
Int8* ret = new Int8[length];
memcpy(ret, (const Int8*)(m_data + m_position), length);
@ -206,7 +206,7 @@ void Stream::seek(Int64 position, SeekOrigin origin)
{
std::stringstream ss;
ss << position;
throw IOException("Stream::seek() Beginnning -> Position outside stream bounds: " + ss.str());
throw error::IOException("Stream::seek() Beginnning -> Position outside stream bounds: " + ss.str());
}
if ((Uint64)position > m_length)
this->resize(position);
@ -217,7 +217,7 @@ void Stream::seek(Int64 position, SeekOrigin origin)
{
std::stringstream ss;
ss << (m_position + position);
throw IOException("Stream::seek() Current -> Position outside stream bounds: " + ss.str());
throw error::IOException("Stream::seek() Current -> Position outside stream bounds: " + ss.str());
}
else if ((m_position + position) > m_length)
this->resize(m_position + position);
@ -229,7 +229,7 @@ void Stream::seek(Int64 position, SeekOrigin origin)
{
std::stringstream ss;
ss << std::hex << "0x" << (m_length - position);
throw IOException("Stream::seek() End -> Position outside stream bounds " + ss.str());
throw error::IOException("Stream::seek() End -> Position outside stream bounds " + ss.str());
}
else if ((m_length - position) > m_length)
this->resize(m_length - position);
@ -242,7 +242,7 @@ void Stream::seek(Int64 position, SeekOrigin origin)
void Stream::resize(Uint64 newSize)
{
if (newSize < m_length)
throw InvalidOperationException("Stream::Resize() -> New size cannot be less to the old size.");
throw error::InvalidOperationException("Stream::resize() -> New size cannot be less to the old size.");
// Allocate and copy new buffer
Uint8* newArray = new Uint8[newSize];

View File

@ -38,7 +38,7 @@ TextStream::TextStream(const std::string& filename, TextMode fileMode, AccessMod
if (!in)
{
if((fileMode & Create) != Create)
throw FileNotFoundException(filename.c_str());
throw error::FileNotFoundException(filename.c_str());
in = fopen(filename.c_str(), "w+b");
}
@ -72,7 +72,7 @@ TextStream::TextStream(const std::string& filename, TextMode fileMode, AccessMod
void TextStream::save(const std::string& filename)
{
if (m_accessmode != WriteOnly && m_accessmode != ReadWrite)
throw InvalidOperationException("Stream not open for writing");
throw error::InvalidOperationException("TextStream::save -> Stream not open for writing");
if (filename != std::string())
m_filename = filename;
@ -98,16 +98,16 @@ void TextStream::save(const std::string& filename)
fclose(out);
}
else
throw FileNotFoundException(m_filename);
throw error::FileNotFoundException(m_filename);
}
std::string TextStream::readLine()
{
if (m_accessmode != ReadOnly && m_accessmode != ReadWrite)
throw InvalidOperationException("Stream not open for reading");
throw error::InvalidOperationException("TextStream::readLine -> Stream not open for reading");
if (m_currentLine > m_lines.size())
throw IOException("Position past stream bounds");
throw error::IOException("TextStream::readLine -> Position past stream bounds");
return m_lines[m_currentLine++];
}
@ -116,7 +116,7 @@ std::string TextStream::readLine()
void TextStream::writeLine(const std::string& str)
{
if (m_accessmode != WriteOnly && m_accessmode != ReadWrite)
throw InvalidOperationException("Stream not open for writing");
throw error::InvalidOperationException("TextStream::writeLine -> Stream not open for writing");
else if (m_currentLine > m_lines.size())
{
m_lines.push_back(str);
@ -130,7 +130,7 @@ void TextStream::writeLine(const std::string& str)
void TextStream::writeLines(std::vector<std::string> strings)
{
if (m_accessmode != WriteOnly && m_accessmode != ReadWrite)
throw InvalidOperationException("Stream not open for writing");
throw error::InvalidOperationException("TextStream::writeLines -> Stream not open for writing");
for (std::string s: strings)
writeLine(s);
@ -139,10 +139,10 @@ void TextStream::writeLines(std::vector<std::string> strings)
std::vector<std::string> TextStream::readLines(Uint32 numLines)
{
if (m_accessmode != ReadOnly && m_accessmode != ReadWrite)
throw InvalidOperationException("Stream not open for reading");
throw error::InvalidOperationException("TextStream::readLines -> Stream not open for reading");
if (numLines > m_lines.size())
throw InvalidOperationException("numLines exceeds the number of stored strings.");
throw error::InvalidOperationException("TextStream::readLines -> numLines exceeds the number of stored strings.");
Uint32 currentLine = m_currentLine;
std::vector<std::string> ret;
@ -156,21 +156,21 @@ std::vector<std::string> TextStream::readLines(Uint32 numLines)
std::string TextStream::readLineAt(Uint32 line)
{
if (m_accessmode != ReadOnly && m_accessmode != ReadWrite)
throw InvalidOperationException("Stream not open for reading");
throw error::InvalidOperationException("Stream not open for reading");
if (line <= 0)
throw InvalidOperationException("A line cannot be zero indexed");
throw error::InvalidOperationException("A line cannot be zero indexed");
if ((line - 1) >= m_lines.size())
throw IOException("Line index out of range");
throw error::IOException("TextStream::readLineAt -> Line index out of range");
return m_lines[line - 1];
}
void TextStream::writeLineAt(Uint32 line, const std::string& str)
{
if (m_accessmode != WriteOnly && m_accessmode != ReadWrite)
throw InvalidOperationException("Stream not open for reading");
throw error::InvalidOperationException("TextStream::writeLineAt -> Stream not open for reading");
if (line <= 0)
throw InvalidOperationException("A line cannot be zero indexed");
throw error::InvalidOperationException("TextStream::writeLineAt -> A line cannot be zero indexed");
m_currentLine = line;
writeLine(str);
@ -179,7 +179,7 @@ void TextStream::writeLineAt(Uint32 line, const std::string& str)
std::vector<std::string> TextStream::readAllLines()
{
if (m_accessmode != ReadOnly && m_accessmode != ReadWrite)
throw InvalidOperationException("Stream not open for reading");
throw error::InvalidOperationException("TextWriter::readAllLines -> Stream not open for reading");
return m_lines;
}
@ -187,7 +187,7 @@ std::vector<std::string> TextStream::readAllLines()
void TextStream::setCurrentLine(Uint32 line)
{
if (line <= 0)
throw InvalidOperationException("A line cannot be zero indexed");
throw error::InvalidOperationException("TextWriter::setCurrentLine -> A line cannot be zero indexed");
m_currentLine = line - 1;
}

View File

@ -14,40 +14,14 @@
// along with libZelda. If not, see <http://www.gnu.org/licenses/>
#include "WiiBanner.hpp"
#include "WiiImage.hpp"
#include <utility.hpp>
#include <string.h>
namespace zelda
{
WiiImage::WiiImage(Uint32 width, Uint32 height, Uint8* data) :
m_width(width),
m_height(height),
m_data(data)
{
}
WiiImage::~WiiImage()
{
if (m_data)
delete[] m_data;
m_data = NULL;
}
Uint8* WiiImage::data()
{
return m_data;
}
Uint32 WiiImage::width() const
{
return m_width;
}
Uint32 WiiImage::height() const
{
return m_height;
}
WiiBanner::WiiBanner() :
m_gameId(0),
m_banner(NULL),

View File

@ -14,10 +14,13 @@
// along with libZelda. If not, see <http://www.gnu.org/licenses/>
#include "WiiImage.hpp"
#include <utility.hpp>
#include "utility.hpp"
#include <string.h>
#include <stdlib.h>
namespace zelda
{
WiiImage::WiiImage(Uint32 width, Uint32 height, Uint8* data) :
m_width(width),
m_height(height),
@ -96,3 +99,5 @@ Uint8 *WiiImage::toRGBA()
}
return bitmapdata;
}
} // zelda

View File

@ -16,6 +16,7 @@
#include "WiiSaveReader.hpp"
#include "WiiSave.hpp"
#include "WiiFile.hpp"
#include "WiiImage.hpp"
#include "WiiBanner.hpp"
#include "md5.h"
#include "aes.h"
@ -25,23 +26,27 @@
#include <iomanip>
#include <utility.hpp>
#include <IOException.hpp>
#include <InvalidOperationException.hpp>
#include <string.h>
namespace zelda
{
namespace io
{
const Uint8 SD_KEY[16] = {0xab, 0x01, 0xb9, 0xd8, 0xe1, 0x62, 0x2b, 0x08, 0xaf, 0xba, 0xd8, 0x4d, 0xbf, 0xc2, 0xa5, 0x5d};
const Uint8 SD_IV[16] = {0x21, 0x67, 0x12, 0xe6, 0xaa, 0x1f, 0x68, 0x9f, 0x95, 0xc5, 0xa2, 0x23, 0x24, 0xdc, 0x6a, 0x98};
const Uint8 MD5_BLANKER[16] = {0x0e, 0x65, 0x37, 0x81, 0x99, 0xbe, 0x45, 0x17, 0xab, 0x06, 0xec, 0x22, 0x45, 0x1a, 0x57, 0x93};
WiiSaveReader::WiiSaveReader(const Uint8* data, Uint64 length)
: BinaryReader(data, length)
: base(data, length)
{
setEndianess(BigEndian);
}
WiiSaveReader::WiiSaveReader(const std::string& filename)
: BinaryReader(filename)
: base(filename)
{
setEndianess(BigEndian);
}
@ -50,37 +55,37 @@ WiiSave* WiiSaveReader::readSave()
{
WiiSave* ret = new WiiSave;
if (length() < 0xF0C0)
throw IOException("Not a valid WiiSave");
throw error::InvalidOperationException("WiiSaveReader::readSave -> Not a valid WiiSave");
WiiBanner* banner = this->readBanner();
if (!banner)
throw IOException("Invalid banner");
throw error::InvalidOperationException("WiiSaveReader::readSave -> Invalid banner");
ret->setBanner(banner);
Uint32 bkVer = this->readUInt32();
Uint32 bkVer = base::readUInt32();
if (bkVer != 0x00000070)
throw IOException("Invalid BacKup header size");
throw error::InvalidOperationException("WiiSaveReader::readSave -> Invalid BacKup header size");
Uint32 bkMagic = this->readUInt32();
Uint32 bkMagic = base::readUInt32();
bkMagic = bkMagic;
if (bkMagic != 0x426B0001)
throw IOException("Invalid BacKup header magic");
throw error::InvalidOperationException("WiiSaveReader::readSave -> Invalid BacKup header magic");
Uint32 ngId = this->readUInt32();
Uint32 ngId = base::readUInt32();
ngId = ngId;
Uint32 numFiles = this->readUInt32();
Uint32 numFiles = base::readUInt32();
/*int fileSize =*/ this->readUInt32();
seek(8); // skip unknown data;
/*int fileSize =*/ base::readUInt32();
base::seek(8); // skip unknown data;
Uint32 totalSize = this->readUInt32();
this->seek(64); // Unknown (Most likely padding)
this->seek(8);
this->seek(6);
this->seek(2);
this->seek(0x10);
Uint32 totalSize = base::readUInt32();
base::seek(64); // Unknown (Most likely padding)
base::seek(8);
base::seek(6);
base::seek(2);
base::seek(0x10);
WiiFile* file;
for (Uint32 i = 0; i < numFiles; ++i)
@ -98,10 +103,10 @@ WiiBanner* WiiSaveReader::readBanner()
{
Uint8* dec = new Uint8[0xf0c0];
memset(dec, 0, 0xF0C0);
Uint8* data = (Uint8*)this->readBytes(0xF0C0);
Uint8* oldData = this->data();
Uint64 oldPos = this->position();
Uint64 oldLen = this->length();
Uint8* data = (Uint8*)base::readBytes(0xF0C0);
Uint8* oldData = base::data();
Uint64 oldPos = base::position();
Uint64 oldLen = base::length();
Uint64 gameId;
Uint32 bannerSize;
Uint8 permissions;
@ -135,20 +140,20 @@ WiiBanner* WiiSaveReader::readBanner()
for (int i = 0; i < 16; ++i)
std::cerr << std::hex << (int)(md5Calc[i]);
std::cerr << std::endl;
this->setData(oldData, oldLen);
this->seek(oldPos, Stream::Beginning);
throw IOException("MD5 Mismatch");
base::setData(oldData, oldLen);
base::seek(oldPos, Stream::Beginning);
throw error::InvalidOperationException("WiiSaveReader::readBanner -> MD5 Mismatch");
}
// Set the binary reader buffer;
this->setData(dec, 0xF0C0);
base::setData(dec, 0xF0C0);
// Start reading the header
gameId = this->readUInt64();
bannerSize = this->readUInt32();
permissions = this->readByte();
/* unk =*/ this->readByte();
this->seek(0x10);
gameId = base::readUInt64();
bannerSize = base::readUInt32();
permissions = base::readByte();
/* unk =*/ base::readByte();
base::seek(0x10);
// skip padding
this->seek(2);
base::seek(2);
int magic;
int flags;
@ -156,28 +161,28 @@ WiiBanner* WiiSaveReader::readBanner()
std::string gameTitle;
std::string subTitle;
magic = this->readUInt32();
magic = base::readUInt32();
// Ensure that the header magic is valid.
if (magic != 0x5749424E)
{
// Make sure to reset m_reader values back to the old ones.
this->setData(oldData, oldLen);
this->seek(oldPos, Stream::Beginning);
throw IOException("Invalid Header Magic");
base::setData(oldData, oldLen);
base::seek(oldPos, Stream::Beginning);
throw error::InvalidOperationException("WiiSaveReader::readBanner -> Invalid Header Magic");
}
flags = this->readUInt32();
animSpeed = this->readUInt16();
this->seek(22);
flags = base::readUInt32();
animSpeed = base::readUInt16();
base::seek(22);
gameTitle = this->readUnicode();
if (this->position() != 0x0080)
this->seek(0x0080, Stream::Beginning);
gameTitle = base::readUnicode();
if (base::position() != 0x0080)
base::seek(0x0080, Stream::Beginning);
subTitle = this->readUnicode();
if (this->position() != 0x00C0)
this->seek(0x00C0, Stream::Beginning);
subTitle = base::readUnicode();
if (base::position() != 0x00C0)
base::seek(0x00C0, Stream::Beginning);
WiiBanner* banner = new WiiBanner;
banner->setGameID(gameId);
@ -211,14 +216,14 @@ WiiBanner* WiiSaveReader::readBanner()
}
}
this->setData(oldData, oldLen);
this->seek(oldPos, Stream::Beginning);
base::setData(oldData, oldLen);
base::seek(oldPos, Stream::Beginning);
return banner;
}
WiiImage* WiiSaveReader::readImage(Uint32 width, Uint32 height)
{
Uint8* image = (Uint8*)this->readBytes(width*height*2);
Uint8* image = (Uint8*)base::readBytes(width*height*2);
if (!isEmpty((Int8*)image, width*height*2))
return new WiiImage(width, height, image);
@ -237,30 +242,30 @@ WiiFile* WiiSaveReader::readFile()
Uint8* filedata;
WiiFile* ret;
Uint32 magic = this->readUInt32();
Uint32 magic = base::readUInt32();
if (magic != 0x03adf17e)
{
std::cerr << "Not a valid File entry header: 0x" << std::hex << magic << std::endl;
return NULL;
}
fileLen = this->readUInt32();
permissions = this->readByte();
attributes = this->readByte();
type = (WiiFile::Type)this->readByte();
name = std::string((const char*)this->readBytes(0x45));
fileLen = base::readUInt32();
permissions = base::readByte();
attributes = base::readByte();
type = (WiiFile::Type)base::readByte();
name = std::string((const char*)base::readBytes(0x45));
ret = new WiiFile(std::string(name));
ret->setPermissions(permissions);
ret->setAttributes(attributes);
ret->setType((WiiFile::Type)type);
Uint8* iv = (Uint8*)this->readBytes(0x10);
this->seek(0x20);
Uint8* iv = (Uint8*)base::readBytes(0x10);
base::seek(0x20);
if (type == WiiFile::File)
{
// Read file data
int roundedLen = (fileLen + 63) & ~63;
filedata = (Uint8*)this->readBytes(roundedLen);
filedata = (Uint8*)base::readBytes(roundedLen);
// Decrypt file
Uint8* decData = new Uint8[roundedLen];
@ -278,11 +283,11 @@ WiiFile* WiiSaveReader::readFile()
void WiiSaveReader::readCerts(Uint32 totalSize)
{
Uint32 dataSize = totalSize - 0x340;
Uint8* sig = (Uint8*)this->readBytes(0x40);
Uint8* ngCert = (Uint8*)this->readBytes(0x180);
Uint8* apCert = (Uint8*)this->readBytes(0x180);
this->seek(0xF0C0, Stream::Beginning);
Uint8* data = (Uint8*)this->readBytes(dataSize);
Uint8* sig = (Uint8*)base::readBytes(0x40);
Uint8* ngCert = (Uint8*)base::readBytes(0x180);
Uint8* apCert = (Uint8*)base::readBytes(0x180);
base::seek(0xF0C0, Stream::Beginning);
Uint8* data = (Uint8*)base::readBytes(dataSize);
Uint8* hash;
hash = getSha1(data, dataSize);
@ -291,4 +296,5 @@ void WiiSaveReader::readCerts(Uint32 totalSize)
check_ec(ngCert, apCert, sig, hash2);
}
} // io
} // zelda

View File

@ -17,11 +17,11 @@
#include "WiiSave.hpp"
#include "WiiFile.hpp"
#include "WiiBanner.hpp"
#include "WiiImage.hpp"
#include "WiiSave.hpp"
#include "WiiFile.hpp"
#include "WiiBanner.hpp"
#include "BinaryWriter.hpp"
#include "IOException.hpp"
#include "aes.h"
#include "ec.h"
#include "utility.hpp"
@ -39,15 +39,18 @@
namespace zelda
{
namespace io
{
const Uint8 SD_KEY[16] = {0xab, 0x01, 0xb9, 0xd8, 0xe1, 0x62, 0x2b, 0x08, 0xaf, 0xba, 0xd8, 0x4d, 0xbf, 0xc2, 0xa5, 0x5d};
const Uint8 SD_IV[16] = {0x21, 0x67, 0x12, 0xe6, 0xaa, 0x1f, 0x68, 0x9f, 0x95, 0xc5, 0xa2, 0x23, 0x24, 0xdc, 0x6a, 0x98};
const Uint8 MD5_BLANKER[16] = {0x0e, 0x65, 0x37, 0x81, 0x99, 0xbe, 0x45, 0x17, 0xab, 0x06, 0xec, 0x22, 0x45, 0x1a, 0x57, 0x93};
WiiSaveWriter::WiiSaveWriter(const std::string &filename)
: BinaryWriter(filename)
: base(filename)
{
this->setAutoResizing(true);
this->setEndianess(BigEndian);
base::setAutoResizing(true);
base::setEndianess(BigEndian);
}
@ -58,65 +61,65 @@ bool WiiSaveWriter::writeSave(WiiSave *save, Uint8 *macAddress, Uint32 ngId, Uin
writeBanner(save->banner());
this->writeUInt32(0x70);
this->writeUInt32(0x426B0001);
this->writeUInt32(ngId); // NG-ID
this->writeUInt32(save->fileList().size());
this->writeUInt32(0); // Size of files;
this->seek(8);
this->writeUInt32(0); // totalSize
this->seek(64);
this->writeUInt64(save->banner()->gameID());
this->writeBytes((Int8*)macAddress, 6);
this->seek(2); // unknown;
this->seek(0x10); // padding;
base::writeUInt32(0x70);
base::writeUInt32(0x426B0001);
base::writeUInt32(ngId); // NG-ID
base::writeUInt32(save->fileList().size());
base::writeUInt32(0); // Size of files;
base::seek(8);
base::writeUInt32(0); // totalSize
base::seek(64);
base::writeUInt64(save->banner()->gameID());
base::writeBytes((Int8*)macAddress, 6);
base::seek(2); // unknown;
base::seek(0x10); // padding;
Uint32 totalSize = 0;
for (std::unordered_map<std::string, WiiFile*>::const_iterator iter = save->fileList().begin(); iter != save->fileList().end(); ++iter)
{
totalSize += writeFile(iter->second);
}
int pos = this->position();
int pos = base::position();
// Write size data
this->seek(0xF0C0 + 0x10, Stream::Beginning);
this->writeUInt32(totalSize);
this->seek(0xF0C0 + 0x1C, Stream::Beginning);
this->writeUInt32(totalSize + 0x3c0);
this->seek(pos, Stream::Beginning);
base::seek(0xF0C0 + 0x10, Stream::Beginning);
base::writeUInt32(totalSize);
base::seek(0xF0C0 + 0x1C, Stream::Beginning);
base::writeUInt32(totalSize + 0x3c0);
base::seek(pos, Stream::Beginning);
writeCerts(totalSize, ngId, ngPriv, ngSig, ngKeyId);
this->save();
base::save();
return true;
}
void WiiSaveWriter::writeBanner(WiiBanner *banner)
{
this->setEndianess(BigEndian);
this->setAutoResizing(true);
this->writeInt64(banner->gameID());
this->writeInt32((0x60a0+0x1200)*banner->icons().size());
this->writeByte((Int8)banner->permissions());
this->seek(1);
this->writeBytes((Int8*)MD5_BLANKER, 16);
this->seek(2);
this->writeInt32(0x5749424E); // WIBN
this->writeInt32(banner->flags());
this->writeInt16(banner->animationSpeed());
this->seek(22);
base::setEndianess(BigEndian);
base::setAutoResizing(true);
base::writeInt64(banner->gameID());
base::writeInt32((0x60a0+0x1200)*banner->icons().size());
base::writeByte((Int8)banner->permissions());
base::seek(1);
base::writeBytes((Int8*)MD5_BLANKER, 16);
base::seek(2);
base::writeInt32(0x5749424E); // WIBN
base::writeInt32(banner->flags());
base::writeInt16(banner->animationSpeed());
base::seek(22);
this->writeUnicode(banner->title());
base::writeUnicode(banner->title());
if (this->position() != 0x0080)
this->seek(0x0080, Stream::Beginning);
if (base::position() != 0x0080)
base::seek(0x0080, Stream::Beginning);
this->writeUnicode(banner->subtitle());
base::writeUnicode(banner->subtitle());
if (this->position() != 0x00C0)
this->seek(0x00C0, Stream::Beginning);
if (base::position() != 0x00C0)
base::seek(0x00C0, Stream::Beginning);
WiiImage* bannerImage = banner->bannerImage();
this->writeBytes((Int8*)bannerImage->data(), bannerImage->width()*bannerImage->height()*2);
base::writeBytes((Int8*)bannerImage->data(), bannerImage->width()*bannerImage->height()*2);
// For empty icons
Uint8* tmpIcon = new Uint8[48*48*2];
@ -129,27 +132,27 @@ void WiiSaveWriter::writeBanner(WiiBanner *banner)
}
else
{
this->writeBytes((Int8*)tmpIcon, 48*48*2);
base::writeBytes((Int8*)tmpIcon, 48*48*2);
}
}
delete[] tmpIcon; // delete tmp buffer;
Uint8* hash = new Uint8[0x10];
MD5(hash, (Uint8*)this->data(), 0xF0C0);
this->seek(0x0E, Stream::Beginning);
this->writeBytes((Int8*)hash, 0x10);
MD5(hash, (Uint8*)base::data(), 0xF0C0);
base::seek(0x0E, Stream::Beginning);
base::writeBytes((Int8*)hash, 0x10);
aes_set_key(SD_KEY);
Uint8 data[0xF0C0];
memcpy(data, this->data(), 0xF0C0);
memcpy(data, base::data(), 0xF0C0);
Uint8 tmpIV[26];
memcpy(tmpIV, SD_IV, 16);
aes_encrypt(tmpIV, data, data, 0xF0C0);
this->seek(0, Stream::Beginning);
this->writeBytes((Int8*)data, 0xF0C0);
this->seek(0xF0C0, Stream::Beginning);
base::seek(0, Stream::Beginning);
base::writeBytes((Int8*)data, 0xF0C0);
base::seek(0xF0C0, Stream::Beginning);
}
Uint32 WiiSaveWriter::writeFile(WiiFile *file)
@ -157,23 +160,23 @@ Uint32 WiiSaveWriter::writeFile(WiiFile *file)
Uint32 ret = 0x80;
// Write the File magic
this->writeUInt32(0x03ADF17E);
this->writeUInt32(file->length());
this->writeByte(file->permissions());
this->writeByte(file->attributes());
this->writeByte(file->type());
base::writeUInt32(0x03ADF17E);
base::writeUInt32(file->length());
base::writeByte(file->permissions());
base::writeByte(file->attributes());
base::writeByte(file->type());
Uint8 name[0x45];
fillRandom(name, 0x45);
memcpy(name, file->filename().c_str(), file->filename().size());
name[file->filename().size()] = '\0';
this->writeBytes((Int8*)name, 0x45);
base::writeBytes((Int8*)name, 0x45);
Uint8 iv[16];
fillRandom(iv, 0x10);
this->writeBytes((Int8*)iv, 0x10);
base::writeBytes((Int8*)iv, 0x10);
Uint8 crap[0x20];
fillRandom(crap, 0x20);
this->writeBytes((Int8*)crap, 0x20);
base::writeBytes((Int8*)crap, 0x20);
if (file->type() == WiiFile::File)
{
@ -184,7 +187,7 @@ Uint32 WiiSaveWriter::writeFile(WiiFile *file)
aes_set_key(SD_KEY);
aes_encrypt(iv, file->data(), data, roundedSize);
this->writeBytes((Int8*)data, roundedSize);
base::writeBytes((Int8*)data, roundedSize);
ret += roundedSize;
delete[] data;
}
@ -196,7 +199,7 @@ Uint32 WiiSaveWriter::writeFile(WiiFile *file)
void WiiSaveWriter::writeImage(WiiImage* image)
{
Int8* data = (Int8*)image->data();
this->writeBytes(data, image->width() * image->height() * 2);
base::writeBytes(data, image->width() * image->height() * 2);
}
void WiiSaveWriter::writeCerts(Uint32 filesSize, Uint32 ngId, Uint8 *ngPriv, Uint8 *ngSig, Uint32 ngKeyId)
@ -232,7 +235,7 @@ void WiiSaveWriter::writeCerts(Uint32 filesSize, Uint32 ngId, Uint8 *ngPriv, Uin
dataSize = filesSize + 0x80;
data = new Uint8[dataSize];
Uint8* rawData = this->data();
Uint8* rawData = base::data();
memcpy(data, rawData + 0xF0C0, dataSize);
hash = getSha1(data, dataSize);
@ -248,9 +251,10 @@ void WiiSaveWriter::writeCerts(Uint32 filesSize, Uint32 ngId, Uint8 *ngPriv, Uin
*(Uint32*)(sig+60) = stuff;
delete[] hash2;
this->writeBytes((Int8*)sig, 0x40);
this->writeBytes((Int8*)ngCert, 0x180);
this->writeBytes((Int8*)apCert, 0x180);
base::writeBytes((Int8*)sig, 0x40);
base::writeBytes((Int8*)ngCert, 0x180);
base::writeBytes((Int8*)apCert, 0x180);
}
} // io
} // zelda

View File

@ -1,3 +1,18 @@
// This file is part of libZelda.
//
// libZelda is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// libZelda is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with libZelda. If not, see <http://www.gnu.org/licenses/>
#include "ZQuest.hpp"
namespace zelda

View File

@ -1,10 +1,27 @@
// This file is part of libZelda.
//
// libZelda is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// libZelda is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with libZelda. If not, see <http://www.gnu.org/licenses/>
#include "ZQuestFileReader.hpp"
#include "ZQuest.hpp"
#include "IOException.hpp"
#include "InvalidOperationException.hpp"
#include "Compression.hpp"
namespace zelda
{
namespace io
{
ZQuestFileReader::ZQuestFileReader(Uint8 *data, Uint64 length)
: base(data, length)
@ -26,12 +43,12 @@ ZQuest *ZQuestFileReader::read()
magic = base::readUInt32();
if (magic != ZQuest::Magic)
throw IOException("ZQuestFileReader::read -> Not a valid ZQuest file");
throw error::InvalidOperationException("ZQuestFileReader::read -> Not a valid ZQuest file");
version = base::readUInt32();
if (version != ZQuest::Version)
throw IOException("ZQuestFileReader::read -> Unsupported ZQuest version");
throw error::InvalidOperationException("ZQuestFileReader::read -> Unsupported ZQuest version");
compressedLen = base::readUInt32();
uncompressedLen = base::readUInt32();
@ -49,7 +66,7 @@ ZQuest *ZQuestFileReader::read()
{
delete[] dst;
delete[] data;
throw IOException("ZQuestFileReader::read -> Error decompressing data");
throw error::InvalidOperationException("ZQuestFileReader::read -> Error decompressing data");
}
delete[] data;
@ -59,4 +76,5 @@ ZQuest *ZQuestFileReader::read()
return new ZQuest(game, BOM == 0xFEFF ? BigEndian : LittleEndian, data, uncompressedLen);
}
} // io
} // zelda

View File

@ -1,3 +1,18 @@
// This file is part of libZelda.
//
// libZelda is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// libZelda is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with libZelda. If not, see <http://www.gnu.org/licenses/>
#include "ZQuestFileWriter.hpp"
#include "InvalidOperationException.hpp"
#include "ZQuest.hpp"
@ -5,6 +20,8 @@
namespace zelda
{
namespace io
{
ZQuestFileWriter::ZQuestFileWriter(Uint8* data, Uint64 length)
: base(data, length)
@ -19,7 +36,7 @@ ZQuestFileWriter::ZQuestFileWriter(const std::string& filename)
void ZQuestFileWriter::write(ZQuest* quest, bool compress)
{
if (!quest)
throw InvalidOperationException("ZQuestFileWriter::writer -> quest cannot be NULL");
throw error::InvalidOperationException("ZQuestFileWriter::writer -> quest cannot be NULL");
base::writeUInt32(ZQuest::Magic);
base::writeUInt32(ZQuest::Version);
@ -54,6 +71,9 @@ void ZQuestFileWriter::write(ZQuest* quest, bool compress)
base::writeUInt16(quest->endian() == BigEndian ? 0xFEFF : 0xFFFE);
base::seek(0x0A);
base::writeUBytes(questData, compLen);
base::save();
}
} // io
} // zelda