/** * lädt die Bilddaten aus einer Datei. * * @param[in] file Dateihandle der Datei * @param[in] palette Grundpalette * * @return liefert Null bei Erfolg, ungleich Null bei Fehler * * @author FloSoft */ int libsiedler2::baseArchivItem_Bitmap_Shadow::load(FILE *file, const ArchivItem_Palette *palette) { unsigned char *data = NULL; if(file == NULL) return 1; if(palette == NULL) palette = this->palette; if(palette == NULL) return 2; tex_clear(); // Nullpunkt X einlesen if(libendian::le_read_s(&nx, file) != 0) return 2; // Nullpunkt Y einlesen if(libendian::le_read_s(&ny, file) != 0) return 3; // Unbekannte Daten überspringen fseek(file, 4, SEEK_CUR); // Breite einlesen if(libendian::le_read_us(&width, file) != 0) return 4; // Höhe einlesen if(libendian::le_read_us(&height, file) != 0) return 5; // Unbekannte Daten überspringen fseek(file, 2, SEEK_CUR); // Länge einlesen if(libendian::le_read_ui(&length, file) != 0) return 6; // Daten einlesen if(length != 0) { data = new unsigned char[length]; if(libendian::le_read_uc(data, length, file) != (int)length) return 7; } // Speicher anlegen tex_alloc(); unsigned char gray = palette->lookup(255,255,255); if(length != 0 && data) { unsigned char *image = &data[height*2]; unsigned int position = 0; // Einlesen for(unsigned short y = 0; y < height; ++y) { unsigned short x = 0; // Solange Zeile einlesen, bis x voll ist while(x < width) { // graue Pixel setzen unsigned char count = image[position++]; for(unsigned char i = 0; i < count; ++i, ++x) tex_setPixel(x, y, gray, palette); // transparente Pixel setzen count = image[position++]; for(unsigned char i = 0; i < count; ++i, ++x) tex_setPixel(x, y, TRANSPARENT_INDEX, palette); } // FF überspringen ++position; } // FF überspringen ++position; if(position != length-(height*2) ) return 8; delete[] data; } return 0; }
/** * erzeugt ein Bitmap aus einem Puffer. * * "überstehende" Ränder werden mit Transparenz aufgefüllt. * * @param[in] width Breite des neuen Bildes * @param[in] height Höhe des neuen Bildes * @param[in] buffer Quellpuffer * @param[in] buffer_width Breite des Puffers * @param[in] buffer_height Höhe des Puffers * @param[in] buffer_format Texturformat des Puffers * @param[in] palette Grundpalette * * @return Null falls Bitmap erfolgreich erstellt worden ist, ungleich Null bei Fehler * * @author FloSoft */ int libsiedler2::baseArchivItem_Bitmap::create(unsigned short width, unsigned short height, const unsigned char* buffer, unsigned short buffer_width, unsigned short buffer_height, TEXTURFORMAT buffer_format, const ArchivItem_Palette* palette) { if(width == 0 || height == 0 || buffer == NULL || buffer_width == 0 || buffer_height == 0) return 1; if(palette == NULL) palette = this->palette; if(palette == NULL) return 2; this->width = width; this->height = height; this->length = width * height; this->format = buffer_format; // Texturspeicher anfordern tex_alloc(); unsigned short bpp; switch(buffer_format) { case FORMAT_RGBA: bpp = 4; break; case FORMAT_PALETTED: bpp = 1; break; default: bpp = 0; break; } for(unsigned int y = 0, y2 = 0; y2 < buffer_height && y < height; ++y, ++y2) { for(unsigned int x = 0, x2 = 0; x2 < buffer_width && x < width; ++x, ++x2) { unsigned int position = (y2 * buffer_width + x2) * bpp; // und Pixel setzen switch(buffer_format) { case FORMAT_RGBA: if(buffer[position + 3] != 0x00) tex_setPixel(x, y, buffer[position + 2], buffer[position + 1], buffer[position], buffer[position + 3]); else tex_setPixel(x, y, TRANSPARENT_INDEX, palette); break; case FORMAT_PALETTED: tex_setPixel(x, y, buffer[position], palette); break; default: break; // Do nothing } } } // Alles ok return 0; }
/** * lädt die Bilddaten aus einer Datei. * * @param[in] file Dateihandle der Datei * @param[in] palette Grundpalette * * @return liefert Null bei Erfolg, ungleich Null bei Fehler */ int libsiedler2::baseArchivItem_Bitmap_RLE::load(std::istream& file, const ArchivItem_Palette* palette) { if(!file) return 1; if(palette == NULL) palette = this->palette_; if(palette == NULL) return 2; tex_clear(); libendian::LittleEndianIStreamRef fs(file); // Nullpunkt X einlesen fs >> nx_; // Nullpunkt Y einlesen fs >> ny_; // Unbekannte Daten überspringen fs.ignore(4); // Breite einlesen fs >> width_; // Höhe einlesen fs >> height_; // Unbekannte Daten überspringen fs.ignore(2); // Länge einlesen unsigned length; fs >> length; std::vector<unsigned char> data(length); // Daten einlesen fs >> data; // Speicher anlegen tex_alloc(); if(length != 0) { size_t position = height_ * 2; // Einlesen for(unsigned short y = 0; y < height_; ++y) { unsigned short x = 0; // Solange Zeile einlesen, bis x voll ist while(x < width_) { // farbige Pixel setzen unsigned char count = data[position++]; for(unsigned char i = 0; i < count; ++i, ++x) tex_setPixel(x, y, data[position++], palette); // transparente Pixel setzen count = data[position++]; for(unsigned char i = 0; i < count; ++i, ++x) tex_setPixel(x, y, TRANSPARENT_INDEX, palette); } // FF überspringen ++position; } // FF überspringen ++position; if(position != length) return 8; } return 0; }