Picture PictureBank::makePicture(SDL_Surface *surface, const std::string& resource_name) const { Point offset( 0, 0 ); // decode the picture name => to set the offset manually // resource_name = "buildings/Govt_00005.png" int dot_pos = resource_name.find('.'); std::string filename = resource_name.substr(0, dot_pos); Point pic_info = PictureInfoBank::instance().getOffset(filename); if (pic_info.getX() == -1 && pic_info.getY() == -1) { // this is a tiled picture=> automatic offset correction offset.setY( surface->h-15*((surface->w+2)/60) ); // (w+2)/60 is the size of the tile: (1x1, 2x2, 3x3, ...) } else if (pic_info.getX() == -2 && pic_info.getY() == -2) { // this is a walker picture=> automatic offset correction offset = Point( -surface->w/2, int(surface->h*3./4.) ); } else { offset = pic_info; } Picture pic; pic.init( surface, offset ); pic.setName(filename); return pic; }
void SdlEngine::loadPicture(Picture& ioPicture, bool streaming) { if( !ioPicture.surface() ) { Size size = ioPicture.size(); Logger::warning( StringHelper::format( 0xff, "SdlEngine:: can't make surface, size=%dx%d", size.width(), size.height() ) ); } SDL_Texture* tx = 0; if( streaming ) { tx = SDL_CreateTexture(_d->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, ioPicture.width(), ioPicture.height() ); } else { tx = SDL_CreateTextureFromSurface(_d->renderer, ioPicture.surface()); } if( !tx ) { Logger::warning( "SdlEngine: cannot create texture from surface" + ioPicture.name() ); } ioPicture.init( tx, ioPicture.surface(), 0 ); if( streaming ) { ioPicture.update(); } SDL_SetTextureBlendMode( ioPicture.texture(), SDL_BLENDMODE_BLEND ); SDL_SetSurfaceBlendMode( ioPicture.surface(), SDL_BLENDMODE_BLEND ); }
Picture operator|(const Picture& p, const Picture& q) { Picture r; r.init(Picture::max(p.height,q.height),p.width + q.width); r.clear(p.height,0,r.height,q.width); r.clear(q.height,p.width,r.height,r.width); r.copyblock(0,0,p); r.copyblock(0,p.width,q); return r; }
Picture operator&(const Picture& p, const Picture& q) { Picture r; r.init(p.height + q.height, Picture::max(p.width ,q.width)); r.clear(0,p.width,p.height,r.width); r.clear(p.height,q.width,r.height,r.width); r.copyblock(0,0,p); r.copyblock(p.height,0,q); return r; }
void Font::draw(Picture& dstpic, const std::string &text, const int dx, const int dy, bool useAlpha ) { if( !_d->ttfFont || !dstpic.isValid() ) return; SDL_Surface* sText = TTF_RenderUTF8_Blended( _d->ttfFont, text.c_str(), _d->color ); if( sText && useAlpha ) { SDL_SetAlpha( sText, 0, 0 ); } if( sText ) { Picture pic; pic.init( sText, Point( 0, 0 ) ); dstpic.draw( pic, dx, dy); } SDL_FreeSurface( sText ); }
Picture frame(const Picture& p) { Picture r; r.init(p.height + 2, p.width + 2); for(int i = 1; i < r.height -1; ++i) { r.position(i,0) = '|'; r.position(i, r.width - 1) = '|'; } for(int j = 1; j < r.width - 1; ++j) { r.position(0, j) = '-'; r.position(r.height - 1, j) = '-'; } r.position(0, 0) = '+'; r.position(0, r.width-1) = '+'; r.position(r.height-1, 0)= '+'; r.position(r.height-1,r.width-1)='+'; r.copyblock(1,1,p); return r; }
Picture* Picture::createCopy() const { if( !_d->surface ) { _OC3_DEBUG_BREAK_IF( "No surface for duplicate" ); return GfxEngine::instance().createPicture( Size( 100 ) ); } int width = _d->surface->w; int height = _d->surface->h; SDL_Surface* img = SDL_ConvertSurface( _d->surface, _d->surface->format, SDL_SWSURFACE); if (img == NULL) { THROW("Cannot make surface, size=" << width << "x" << height); } Picture* newpic = GfxEngine::instance().createPicture( Size( width, height ) ); newpic->init(img, _d->offset ); return newpic; }
void PictureBank::loadArchive( const std::string &filename, GfxEngine& engine ) { std::cout << "reading image archive: " << filename << std::endl; struct archive *a; struct archive_entry *entry; int rc; a = archive_read_new(); archive_read_support_compression_all(a); archive_read_support_format_all(a); rc = archive_read_open_filename(a, filename.c_str(), 16384); // block size if (rc != ARCHIVE_OK) { THROW("Cannot open archive " << filename); } SDL_Surface *surface; SDL_RWops *rw; const Uint32 bufferSize = 10000000; // allocated buffer std::auto_ptr< Uint8 > buffer( new Uint8[ bufferSize ] ); if( buffer.get() == 0 ) THROW("Memory error, cannot allocate buffer size " << bufferSize); std::string entryname; Picture tmpPicture; while( archive_read_next_header(a, &entry) == ARCHIVE_OK ) { // for all entries in archive entryname = archive_entry_pathname(entry); if ((archive_entry_stat(entry)->st_mode & S_IFREG) == 0) { // not a regular file (maybe a directory). skip it. continue; } if (archive_entry_stat(entry)->st_size >= bufferSize) { THROW("Cannot load archive: file is too big " << entryname << " in archive " << filename); } int size = archive_read_data(a, buffer.get(), bufferSize); // read data into buffer rw = SDL_RWFromMem(buffer.get(), size); surface = IMG_Load_RW(rw, 0); SDL_SetAlpha( surface, 0, 0 ); tmpPicture.init( surface, Point() ); engine.loadPicture( tmpPicture ); setPicture( entryname, tmpPicture ); SDL_FreeRW(rw); } rc = archive_read_finish(a); if (rc != ARCHIVE_OK) { THROW("Error while reading archive " << filename); } }