/** * lädt eine ACT-File in ein ArchivInfo. * * @param[in] file Dateiname der ACT-File * @param[out] items ArchivInfo-Struktur, welche gefüllt wird * * @return Null bei Erfolg, ein Wert ungleich Null bei Fehler * * @author FloSoft * @author OLiver */ int libsiedler2::loader::LoadACT(const std::string& file, ArchivInfo& items) { long size; if(file.empty()) return 1; // Datei zum lesen öffnen boost::scoped_ptr<FILE> act(fopen(file.c_str(), "rb")); // hat das geklappt? if(!act) return 2; fseek(act.get(), 0, SEEK_END); size = ftell(act.get()); fseek(act.get(), 0, SEEK_SET); // sind es 256*3 Bytes, also somit 8bit-RGB? if(size != 256*3) return 3; ArchivItem_Palette* palette = (ArchivItem_Palette*)getAllocator().create(BOBTYPE_PALETTE); if(palette->load(act.get(), false) != 0){ delete palette; return 4; } // einlesen items.clear(); items.push(palette); // Alles OK return 0; }
/** * lädt eine Sounddatei in ein ArchivInfo. (midi, xmidi, wave) * * @param[in] file Dateiname der Sounddatei * @param[out] items ArchivInfo-Struktur, welche gefüllt wird * * @return Null bei Erfolg, ein Wert ungleich Null bei Fehler */ int libsiedler2::loader::LoadSND(const std::string& file, ArchivInfo& items) { if(file.empty()) return 1; // Datei zum lesen öffnen boost::iostreams::mapped_file_source mmapFile; try{ mmapFile.open(bfs::path(file)); } catch(std::exception& e){ std::cerr << "Could not open '" << file << "': " << e.what() << std::endl; return 2; } typedef boost::iostreams::stream<boost::iostreams::mapped_file_source> MMStream; MMStream snd(mmapFile); // hat das geklappt? if(!snd) return 2; baseArchivItem_Sound* sound = baseArchivItem_Sound::findSubType(snd); if(!sound) return 3; size_t size = getIStreamSize(snd); if(sound->load(snd, static_cast<unsigned>(size)) != 0) return 4; items.clear(); items.push(sound); return 0; }
/** * lädt eine BOB-File in ein ArchivInfo. * * @param[in] file Dateiname der BOB-File * @param[out] items ArchivInfo-Struktur, welche gefüllt wird * * @return Null bei Erfolg, ein Wert ungleich Null bei Fehler */ int libsiedler2::loader::LoadBOB(const std::string& file, const ArchivItem_Palette* palette, ArchivInfo& items) { unsigned int header; if(file.empty() || palette == NULL) return 1; // Datei zum lesen öffnen boost::iostreams::mapped_file_source mmapFile; try { mmapFile.open(bfs::path(file)); } catch(std::exception& e) { std::cerr << "Could not open '" << file << "': " << e.what() << std::endl; return 2; } typedef boost::iostreams::stream<boost::iostreams::mapped_file_source> MMStream; MMStream mmapStream(mmapFile); libendian::EndianIStream<false, MMStream& > bob(mmapStream); // hat das geklappt? if(!bob) return 2; // Header einlesen bob >> header; // ist es eine BOB-File? (Header 0xF601F501) if(header != 0x01F501F6) return 4; ArchivItem_Bob* item = dynamic_cast<ArchivItem_Bob*>(getAllocator().create(BOBTYPE_BOB)); boost::filesystem::path filePath(file); if(filePath.has_filename()) item->setName(filePath.filename().string()); if(item->load(bob.getStream(), palette) != 0) { delete item; return 5; } // Item alloziieren und zuweisen items.clear(); items.push(item); return 0; }
/** * lädt eine GER/ENG-File in ein ArchivInfo. * * @param[in] file Dateiname der GER/ENG-File * @param[out] items ArchivInfo-Struktur, welche gefüllt wird * @param[in] conversion Soll ggf. OEM-Charset in ANSI umgewandelt werden? * * @return Null bei Erfolg, ein Wert ungleich Null bei Fehler * * @bug Keine Erkennung ob Plain-Text oder "Irgendwas". */ int libsiedler2::loader::LoadTXT(const std::string& file, ArchivInfo& items, bool conversion) { short header; if(file.empty()) return 1; // Datei zum lesen öffnen boost::iostreams::mapped_file_source mmapFile; try{ mmapFile.open(bfs::path(file)); }catch(std::exception& e){ std::cerr << "Could not open '" << file << "': " << e.what() << std::endl; return 2; } typedef boost::iostreams::stream<boost::iostreams::mapped_file_source> MMStream; MMStream mmapStream(mmapFile); libendian::EndianIStream<false, MMStream& > fs(mmapStream); // hat das geklappt? if(!fs) return 2; size_t length = getIStreamSize(fs.getStream()); assert(length < std::numeric_limits<unsigned>::max()); // Header einlesen fs >> header; items.clear(); // ist es eine TXT-File? (Header 0xE7FD) if( header != (short)0xFDE7 ) { // den Header zurückspringen fs.setPositionRel(-2); ArchivItem_Text* item = (ArchivItem_Text*)getAllocator().create(BOBTYPE_TEXT); item->load(fs.getStream(), conversion); items.push(item); } else { // "archiviert" unsigned short count, unknown; unsigned int size; fs >> count; fs >> unknown; fs >> size; if(size == 0) size = static_cast<unsigned>(length); else size += 10; std::vector<unsigned> starts(count); // Starts einlesen for(unsigned short x = 0; x < count; ++x) { uint32_t s; fs >> s; if(s != 0) starts[x] = s + 10; } // Daten einlesen, zwecks Längenbestimmung size_t pos = fs.getPosition(); size_t rest = size - pos; std::vector<char> buffer(rest + 1); buffer.resize(rest); fs >> buffer; buffer.push_back(0); for(unsigned short x = 0; x < count; ++x) { unsigned i = starts[x]; if(i != 0) { // An Start springen fs.setPosition(i); // einlesen ArchivItem_Text* item = (ArchivItem_Text*)getAllocator().create(BOBTYPE_TEXT); assert(i >= pos); item->load(fs.getStream(), conversion, (unsigned int)strlen(&buffer[i - pos]) + 1); items.push(item); } else items.push(NULL); } } // alles ok return 0; }