#include "Caster.h"
+#include "Interpreter.h"
+#include "Loader.h"
#include "TypeDescription.h"
#include "../battle/Resources.h"
#include "../battle/Monster.h"
namespace loader {
-Caster::Caster(Interpreter &intp)
-: intp(intp) {
+Caster::Caster(Loader &ld, Interpreter &intp)
+: ld(ld)
+, intp(intp) {
}
battle::Resources *Caster::GetBattleResources(const string &ident) {
return reinterpret_cast<battle::Resources *>(
- intp.GetObject(battle::Resources::TYPE_ID, ident));
+ GetObject(battle::Resources::TYPE_ID, ident));
}
Capsule *Caster::GetCapsule(const string &ident) {
- return reinterpret_cast<Capsule *>(intp.GetObject(Capsule::TYPE_ID, ident));
+ return reinterpret_cast<Capsule *>(
+ GetObject(Capsule::TYPE_ID, ident));
}
Hero *Caster::GetHero(const string &ident) {
- return reinterpret_cast<Hero *>(intp.GetObject(Hero::TYPE_ID, ident));
+ return reinterpret_cast<Hero *>(
+ GetObject(Hero::TYPE_ID, ident));
}
Item *Caster::GetItem(const string &ident) {
- return reinterpret_cast<Item *>(intp.GetObject(Item::TYPE_ID, ident));
+ return reinterpret_cast<Item *>(
+ GetObject(Item::TYPE_ID, ident));
}
Map *Caster::GetMap(const string &ident) {
- return reinterpret_cast<Map *>(intp.GetObject(Map::TYPE_ID, ident));
+ return reinterpret_cast<Map *>(
+ GetObject(Map::TYPE_ID, ident));
}
menu::Resources *Caster::GetMenuResources(const string &ident) {
return reinterpret_cast<menu::Resources *>(
- intp.GetObject(menu::Resources::TYPE_ID, ident));
+ GetObject(menu::Resources::TYPE_ID, ident));
}
Monster *Caster::GetMonster(const string &ident) {
- return reinterpret_cast<Monster *>(intp.GetObject(Monster::TYPE_ID, ident));
+ return reinterpret_cast<Monster *>(
+ GetObject(Monster::TYPE_ID, ident));
}
PartyLayout *Caster::GetPartyLayout(const string &ident) {
return reinterpret_cast<PartyLayout *>(
- intp.GetObject(PartyLayout::TYPE_ID, ident));
+ GetObject(PartyLayout::TYPE_ID, ident));
}
Spell *Caster::GetSpell(const string &ident) {
- return reinterpret_cast<Spell *>(intp.GetObject(Spell::TYPE_ID, ident));
+ return reinterpret_cast<Spell *>(
+ GetObject(Spell::TYPE_ID, ident));
+}
+
+
+void *Caster::GetObject(int typeId, const string &ident) {
+ std::map<string, LoadedExport>::const_iterator i(
+ ld.Exports().find(ident));
+ if (i != ld.Exports().end()) {
+ if (i->second.typeId != typeId) {
+ throw std::runtime_error("mismatched type for "
+ + ident);
+ } else {
+ return i->second.location;
+ }
+ }
+ return intp.GetObject(typeId, ident);
}
}
i(intp.ExportedIdentifiers().begin()),
end(intp.ExportedIdentifiers().end());
i != end; ++i) {
- addressMap.insert(make_pair(i->c_str(), cursor));
Object object;
object.typeId = Interpreter::STRING_ID;
object.size = i->size() + 1;
Write(out, &object, sizeof(Object));
+ addressMap.insert(make_pair(i->c_str(), cursor));
Write(out, i->c_str(), object.size);
}
for(vector<Interpreter::PostponedDefinition>::const_iterator
#include <cstring>
#include <fstream>
#include <stdexcept>
+#include <utility>
+using std::make_pair;
using std::map;
using std::string;
using std::vector;
LoadObjects(header->ident,
header->ObjectsBegin(),
header->ObjectsEnd());
+ LoadArrays(header->ident,
+ header->ArraysBegin(),
+ header->ArraysEnd());
} catch (...) {
delete[] block;
throw;
LoadedExport &exp(exports[identifier]);
exp.typeId = i->typeId;
exp.location = src + i->dataOffset;
+ exports.insert(make_pair(identifier, exp));
}
}
}
}
+void Loader::LoadArrays(char *src, Array *begin, Array *end) {
+ for (Array *i = begin; i < end; i = i->Next()) {
+ if (!i->ref) {
+ continue;
+ }
+ for (char *j = i->Data(), *end = i->Data() + i->size;
+ j < end; j += sizeof(void *)) {
+ *reinterpret_cast<char **>(j) =
+ src + *reinterpret_cast<unsigned int *>(j);
+ }
+ }
+}
+
}
public:
void Load(const std::string &file);
+ const std::map<std::string, LoadedExport> &Exports() const { return exports; }
+
private:
void LoadExports(char *src, Export *begin, Export *end);
void LoadExternals(char *src, External *begin, External *end);
void LoadObjects(char *src, Object *begin, Object *end);
void LoadObject(char *src, char *dest, const TypeDescription &);
+ void LoadArrays(char *src, Array *begin, Array *end);
private:
std::map<std::string, char *> objectFiles;