/**
 *  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;
}
Example #2
0
/**
 *  lädt eine spezifizierten Bobtype aus einer Datei in ein ArchivItem.
 *
 *  @param[in]  bobtype Typ des Items
 *  @param[in]  file    Filehandle auf die auszulesende Datei
 *  @param[in]  palette Grundpalette
 *  @param[out] item    ArchivItem-Struktur, welche gefüllt wird
 *
 *  @return Null bei Erfolg, ein Wert ungleich Null bei Fehler
 */
int libsiedler2::loader::LoadType(BOBTYPES bobtype, std::istream& file, const ArchivItem_Palette* palette, ArchivItem*& item)
{
    if(!file)
        return 1;

    try{
        switch(bobtype)
        {
            case BOBTYPE_SOUND: // WAVs, MIDIs
            {
                libendian::LittleEndianIStreamRef fs(file);
                unsigned int length;
                fs >> length;

                baseArchivItem_Sound* nitem = baseArchivItem_Sound::findSubType(file);
                if(!nitem || nitem->load(file, length) != 0){
                    delete nitem;
                    return 5;
                }
                item = nitem;
            } break;
            case BOBTYPE_BITMAP_RLE: // RLE komprimiertes Bitmap
            {
                baseArchivItem_Bitmap_RLE* nitem = dynamic_cast<baseArchivItem_Bitmap_RLE*>(getAllocator().create(BOBTYPE_BITMAP_RLE));
                if(nitem->load(file, palette) != 0){
                    delete nitem;
                    return 6;
                }
                item = nitem;
            } break;
            case BOBTYPE_FONT: // Font
            {
                ArchivItem_Font* nitem = dynamic_cast<ArchivItem_Font*>(getAllocator().create(BOBTYPE_FONT));
                if(nitem->load(file, palette) != 0){
                    delete nitem;
                    return 7;
                }
                item = nitem;
            } break;
            case BOBTYPE_BITMAP_PLAYER: // Bitmap mit spezifischer Spielerfarbe
            {
                ArchivItem_Bitmap_Player* nitem = dynamic_cast<ArchivItem_Bitmap_Player*>(getAllocator().create(BOBTYPE_BITMAP_PLAYER));
                if(nitem->load(file, palette) != 0){
                    delete nitem;
                    return 8;
                }
                item = nitem;
            } break;
            case BOBTYPE_PALETTE: // Palette
            {
                ArchivItem_Palette* nitem =  dynamic_cast<ArchivItem_Palette*>(getAllocator().create(BOBTYPE_PALETTE));
                if(nitem->load(file) != 0){
                    delete nitem;
                    return 9;
                }
                item = nitem;
            } break;
            case BOBTYPE_BOB: // Bobfile
            {
                ArchivItem_Bob* nitem = dynamic_cast<ArchivItem_Bob*>(getAllocator().create(BOBTYPE_BOB));
                if(nitem->load(file, palette) != 0){
                    delete nitem;
                    return 10;
                }
                item = nitem;
            } break;
            case BOBTYPE_BITMAP_SHADOW: // Schatten
            {
                baseArchivItem_Bitmap_Shadow* nitem = dynamic_cast<baseArchivItem_Bitmap_Shadow*>(getAllocator().create(BOBTYPE_BITMAP_SHADOW));
                if(nitem->load(file, palette) != 0){
                    delete nitem;
                    return 11;
                }
                item = nitem;
            } break;
            case BOBTYPE_MAP: // Mapfile
            {
                ArchivItem_Map* nitem = dynamic_cast<ArchivItem_Map*>(getAllocator().create(BOBTYPE_MAP));
                if(nitem->load(file, false) != 0){
                    delete nitem;
                    return 12;
                }
                item = nitem;
            } break;
            case BOBTYPE_TEXT: // Textfile
            {
                ArchivItem_Text* nitem =  dynamic_cast<ArchivItem_Text*>(getAllocator().create(BOBTYPE_TEXT));
                if(nitem->load(file) != 0){
                    delete nitem;
                    return 13;
                }
                item = nitem;
            } break;
            case BOBTYPE_BITMAP_RAW: // unkomprimiertes Bitmap
            {
                baseArchivItem_Bitmap_Raw* nitem = dynamic_cast<baseArchivItem_Bitmap_Raw*>(getAllocator().create(BOBTYPE_BITMAP_RAW));
                if(nitem->load(file, palette) != 0){
                    delete nitem;
                    return 14;
                }
                item = nitem;
            } break;
            case BOBTYPE_NONE:
                item = NULL;
                break;
            default:
                item = NULL;
                return 42;
        }

        if(item != NULL)
            item->setBobType(bobtype);
    }catch(std::runtime_error&){
        // Mostly error on reading (e.g. unexpected end of file)
        return 999;
    }

    return 0;
}