X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Floader%2FLoader.cpp;h=961ec7cff6d315dec5537338fe08ba8cfc0b9450;hb=0e7b9eca67383e45e04aa419cb783c92722f7801;hp=9c8739aabee00191584852973971f203fc8afa5e;hpb=45bb35881a10720ae26701ddf075f756419cd627;p=l2e.git diff --git a/src/loader/Loader.cpp b/src/loader/Loader.cpp index 9c8739a..961ec7c 100644 --- a/src/loader/Loader.cpp +++ b/src/loader/Loader.cpp @@ -5,6 +5,7 @@ #include #include #include +#include using std::make_pair; using std::map; @@ -57,6 +58,16 @@ void Loader::Load(const std::string &filePath) { LoadArrays(header->ident, header->ArraysBegin(), header->ArraysEnd()); + LoadImages(header->ident, + header->ImagesBegin(), + header->ImagesEnd()); + + InitObjects( + header->ObjectsBegin(), + header->ObjectsEnd()); + InitArrays( + header->ArraysBegin(), + header->ArraysEnd()); } catch (...) { delete[] block; throw; @@ -93,13 +104,27 @@ void Loader::LoadExternals(char *src, External *begin, External *end) { } } +void Loader::LoadImages(char *src, Image *begin, Image *end) { + for (Image *i = begin; i != end; ++i) { + const string path(src + i->pathOffset); + SDL_Surface **dest = reinterpret_cast(src + i->destOffset); + std::map::const_iterator + found(images.find(path)); + if (found != images.end()) { + *dest = found->second; + } else { + SDL_Surface *loaded = IMG_Load(path.c_str()); + images.insert(make_pair(path, loaded)); + *dest = loaded; + } + } +} + void Loader::LoadObjects(char *src, Object *begin, Object *end) { for (Object *i = begin; i < end; i = i->Next()) { const TypeDescription &td = TypeDescription::Get(i->typeId); - if (td.NeedsLinking()) { - LoadObject(src, i->RawObject(), td); - } + LoadObject(src, i->RawObject(), td); } } @@ -108,25 +133,73 @@ void Loader::LoadObject(char *src, char *object, const TypeDescription &td) { i(td.FieldsBegin()), end(td.FieldsEnd()); i != end; ++i) { const FieldDescription &field = i->second; - if (!field.IsReferenced() && !field.IsAggregate()) { - continue; - } - char **dest(reinterpret_cast(object + field.Offset())); - if (*dest) { - *dest = src + *reinterpret_cast(dest); + if (field.IsReferenced() || field.IsAggregate()) { + char **dest(reinterpret_cast(object + field.Offset())); + if (*dest) { + *dest = src + *reinterpret_cast(dest); + } + } else { + const TypeDescription &nestedType + = TypeDescription::Get(field.TypeId()); + LoadObject(src, object + field.Offset(), nestedType); } } } void Loader::LoadArrays(char *src, Array *begin, Array *end) { for (Array *i = begin; i < end; i = i->Next()) { - if (!i->ref) { + if (i->ref) { + for (char *j = i->Data(), *end = i->Data() + i->size; + j < end; j += sizeof(void *)) { + unsigned int offset = *reinterpret_cast(j); + if (offset) { + *reinterpret_cast(j) = src + offset; + } + } + } else { + const TypeDescription &td = TypeDescription::Get(i->typeId); + for (char *j = i->Data(), *end = i->Data() + i->size; + j < end; j += td.Size()) { + LoadObject(src, j, td); + } + } + } +} + + +void Loader::InitObjects(Object *begin, Object *end) { + for (Object *i = begin; i < end; i = i->Next()) { + const TypeDescription &td = + TypeDescription::Get(i->typeId); + InitObject(i->RawObject(), td); + } +} + +void Loader::InitObject(char *object, const TypeDescription &td) { + td.Init(object); + td.Load(object); + for (TypeDescription::FieldIterator + i(td.FieldsBegin()), end(td.FieldsEnd()); + i != end; ++i) { + const FieldDescription &field = i->second; + if (field.IsReferenced() || field.IsAggregate()) { + continue; + } + const TypeDescription &nestedType + = TypeDescription::Get(field.TypeId()); + InitObject(object + field.Offset(), nestedType); + } +} + +void Loader::InitArrays(Array *begin, Array *end) { + for (Array *i = begin; i < end; i = i->Next()) { + if (i->ref) { continue; } + const TypeDescription &td = TypeDescription::Get(i->typeId); for (char *j = i->Data(), *end = i->Data() + i->size; - j < end; j += sizeof(void *)) { - *reinterpret_cast(j) = - src + *reinterpret_cast(j); + j < end; j += td.Size()) { + InitObject(j, td); } } }