Exemple #1
0
/**
 *  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;
}
Exemple #2
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;
}
Exemple #4
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;
}
Exemple #5
0
/**
 *  lädt eine BBM-File in ein ArchivInfo.
 *
 *  @param[in]  file    Dateiname der BBM-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::LoadBBM(const std::string& file, ArchivInfo& items)
{
    char header[4], pbm[4];
    unsigned int chunk;
    unsigned int i = 0;

    if(file.empty())
        return 1;

    // Datei zum lesen öffnen
    boost::scoped_ptr<FILE> bbm(fopen(file.c_str(), "rb"));

    // hat das geklappt?
    if(!bbm)
        return 2;

    long size = getFileLength(bbm.get());

    // Header einlesen
    if(libendian::le_read_c(header, 4, bbm.get()) != 4)
        return 3;

    // ist es eine BBM-File? (Header "FORM")
    if(strncmp(header, "FORM", 4) != 0)
        return 4;

    // Länge einlesen
    unsigned length;
    if(libendian::le_read_ui(&length, bbm.get()) != 0)
        return 5;

    // Typ einlesen
    if(libendian::le_read_c(pbm, 4, bbm.get()) != 4)
        return 6;

    // ist es eine BBM-File? (Typ "PBM ")
    if(strncmp(pbm, "PBM ", 4) != 0)
        return 7;

    // Chunks einlesen
    while(!feof(bbm.get()) && ftell(bbm.get()) < size)
    {
        // Chunk-Typ einlesen
        if(libendian::be_read_ui(&chunk, bbm.get()) != 0)
            return 8;

        switch(chunk)
        {
            case 0x434D4150: // "CMAP"
            {
                // Länge einlesen
                if(libendian::be_read_ui(&length, bbm.get()) != 0)
                    return 9;

                // Bei ungerader Zahl aufrunden
                if(length & 1)
                    ++length;

                // Ist Länge wirklich so groß wie Farbtabelle?
                if(length != 256 * 3)
                    return 10;

                // Daten von Item auswerten
                ArchivItem_Palette* palette = (ArchivItem_Palette*)getAllocator().create(BOBTYPE_PALETTE);
                items.push(palette);

                size_t namePos = file.find_last_of('/');
                if(namePos != std::string::npos)
                {
                    std::stringstream rName;
                    rName << file.substr(namePos+1) << "(" << i << ")";
                    palette->setName(rName.str());
                }

                // Farbpalette lesen
                Color colors[256];
                if(libendian::le_read_uc(&colors[0].r, sizeof(colors), bbm.get()) != sizeof(colors))
                    return 10;

                // Farbpalette zuweisen
                for(unsigned int k = 0; k < 256; ++k)
                    palette->set(k, colors[k]);

                ++i;
            } break;
            default:
            {
                // Länge einlesen
                if(libendian::be_read_ui(&length, bbm.get()) != 0)
                    return 12;

                // Bei ungerader Zahl aufrunden
                if(length & 1)
                    ++length;

                if(length > 0)
                {
                    boost::scoped_array<unsigned char> buffer(new unsigned char[length]);

                    // überspringen
                    if(libendian::le_read_uc(buffer.get(), length, bbm.get()) != (int)length)
                        return 13;
                }
            } break;
        }
    }

    if(items.size() == 0)
        return 14;

    // alles ok
    return 0;
}