void CLoadFile::openNextFile(const boost::filesystem::path & fname, int minimalVersion) { assert(!serializer.reverseEndianess); assert(minimalVersion <= SERIALIZATION_VERSION); try { fName = fname.string(); sfile = make_unique<FileStream>(fname, std::ios::in | std::ios::binary); sfile->exceptions(std::ifstream::failbit | std::ifstream::badbit); //we throw a lot anyway if(!(*sfile)) THROW_FORMAT("Error: cannot open to read %s!", fName); //we can read char buffer[4]; sfile->read(buffer, 4); if(std::memcmp(buffer,"VCMI",4)) THROW_FORMAT("Error: not a VCMI file(%s)!", fName); serializer & serializer.fileVersion; if(serializer.fileVersion < minimalVersion) THROW_FORMAT("Error: too old file format (%s)!", fName); if(serializer.fileVersion > SERIALIZATION_VERSION) { logGlobal->warnStream() << boost::format("Warning format version mismatch: found %d when current is %d! (file %s)\n") % serializer.fileVersion % SERIALIZATION_VERSION % fName; auto versionptr = (char*)&serializer.fileVersion; std::reverse(versionptr, versionptr + 4); logGlobal->warnStream() << "Version number reversed is " << serializer.fileVersion << ", checking..."; if(serializer.fileVersion == SERIALIZATION_VERSION) { logGlobal->warnStream() << fname << " seems to have different endianness! Entering reversing mode."; serializer.reverseEndianess = true; } else THROW_FORMAT("Error: too new file format (%s)!", fName); } } catch(...) { clear(); //if anything went wrong, we delete file and rethrow throw; } }
CTypeList::TypeInfoPtr CTypeList::getTypeDescriptor(const std::type_info *type, bool throws) const { auto i = typeInfos.find(type); if(i != typeInfos.end()) return i->second; //type found, return ptr to structure if(!throws) return nullptr; THROW_FORMAT("Cannot find type descriptor for type %s. Was it registered?", type->name()); }
std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(TypeInfoPtr from, TypeInfoPtr to) const { if(!strcmp(from->name, to->name)) return std::vector<CTypeList::TypeInfoPtr>(); // Perform a simple BFS in the class hierarchy. auto BFS = [&](bool upcast) { std::map<TypeInfoPtr, TypeInfoPtr> previous; std::queue<TypeInfoPtr> q; q.push(to); while(q.size()) { auto typeNode = q.front(); q.pop(); for(auto & weakNode : (upcast ? typeNode->parents : typeNode->children) ) { auto nodeBase = weakNode.lock(); if(!previous.count(nodeBase)) { previous[nodeBase] = typeNode; q.push(nodeBase); } } } std::vector<TypeInfoPtr> ret; if(!previous.count(from)) return ret; ret.push_back(from); TypeInfoPtr ptr = from; do { ptr = previous.at(ptr); ret.push_back(ptr); } while(ptr != to); return ret; }; // Try looking both up and down. auto ret = BFS(true); if(ret.empty()) ret = BFS(false); if(ret.empty()) THROW_FORMAT("Cannot find relation between types %s and %s. Were they (and all classes between them) properly registered?", from->name % to->name); return ret; }
FontRenderer::FontRenderer() { u64 languageCode = 0; ASSERT_OK(setGetSystemLanguage(&languageCode), "Failed to get system language code\n"); ASSERT_OK(plGetSharedFont(languageCode, m_sharedFontData.data(), PlSharedFontType_Total, &m_totalSharedFonts), "Failed to get shared fonts"); if (m_totalSharedFonts == 0) THROW_FORMAT("No shared fonts found!\n"); ASSERT_OK(FT_Init_FreeType(&m_ftLibrary), "Failed to init freetype"); PlFontData standardFontData = m_sharedFontData[PlSharedFontType_Standard]; ASSERT_OK(FT_New_Memory_Face(m_ftLibrary, (const FT_Byte*)standardFontData.address, standardFontData.size, 0, &m_ftFaces[FontFaceType::STANDARD]), "Failed to create standard font face"); PlFontData extendedFontData = m_sharedFontData[PlSharedFontType_NintendoExt]; ASSERT_OK(FT_New_Memory_Face(m_ftLibrary, (const FT_Byte*)extendedFontData.address, extendedFontData.size, 0, &m_ftFaces[FontFaceType::NINTY_EXT]), "Failed to create extended font face"); }