예제 #1
0
파일: engine.cpp 프로젝트: jcaesar/openage
void save_screenshot(const char* filename) {

	log::msg("saving screenshot to %s...", filename);

	int32_t rmask, gmask, bmask, amask;
	rmask = 0x000000FF;
	gmask = 0x0000FF00;
	bmask = 0x00FF0000;
	amask = 0xFF000000;
	SDL_Surface *screen = SDL_CreateRGBSurface(SDL_SWSURFACE, window_size.x, window_size.y, 32, rmask, gmask, bmask, amask);

	size_t pxcount = screen->w * screen->h;
	uint32_t *pxdata = new uint32_t[pxcount];

	glReadPixels(0, 0, window_size.x, window_size.y, GL_RGBA, GL_UNSIGNED_BYTE, pxdata);

	uint32_t *surface_pxls = (uint32_t *)screen->pixels;

	//we need to invert all rows, but leave column order the same.
	for (ssize_t row = 0; row < screen->h; row++) {
		ssize_t irow = screen->h - 1 - row;
		for (ssize_t col = 0; col < screen->w; col++) {
			uint32_t pxl = pxdata[irow * screen->w + col];

			//TODO: store the alpha channels in the screenshot, is buggy at the moment..
			surface_pxls[row * screen->w + col] = pxl | 0xFF000000;
		}
	}

	delete[] pxdata;

	IMG_SavePNG(screen, filename);
	SDL_FreeSurface(screen);
}
예제 #2
0
int IMG_SaveFrameBuffer(const char* file, int compression)
{
	const int w = preferences::actual_screen_width();
	const int h = preferences::actual_screen_height();

#if SDL_VERSION_ATLEAST(2, 0, 0)
	graphics::surface s(SDL_CreateRGBSurface(0, w, h, 24, SURFACE_MASK_RGB));
#else
	graphics::surface s(SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 24, SURFACE_MASK_RGB));
#endif
	glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, s->pixels); 

	unsigned char* pixels = (unsigned char*)s->pixels;

	for(int n = 0; n != h/2; ++n) {
		unsigned char* s1 = pixels + n*w*3;
		unsigned char* s2 = pixels + (h-n-1)*w*3;
		for(int m = 0; m != w*3; ++m) {
			std::swap(s1[m], s2[m]);
		}
	}

	const int result = IMG_SavePNG(file, s.get(), compression);
	if(result == -1) {
		fprintf(stderr, "FAILED TO SAVE SCREENSHOT\n");
		return result;
	}
	fprintf(stderr, "SAVED SCREENSHOT TO %s.\n", file);
	
	return result;
}
예제 #3
0
파일: eel_image.c 프로젝트: olofson/eel
static EEL_xno img_SavePNG(EEL_vm *vm)
{
	EEL_value *arg = vm->heap + vm->argv;
	int res;
	SDL_Surface *from;
	int comp = -1;

	/* Filename */
	const char *fn = eel_v2s(arg);
	if(!fn)
		return EEL_XNEEDSTRING;

	/* Surface */
	if(EEL_CLASS(arg + 1) != esdl_md.surface_cid)
			return EEL_XWRONGTYPE;
	from = o2ESDL_surface(arg[1].objref.v)->surface;

	/* Compression level */
	if(vm->argc >= 3)
	{
		comp = eel_v2l(arg + 2);
#if 0
		if(comp < -1)
			return EEL_XLOWVALUE;
		if(comp > 9)
			return EEL_XHIGHVALUE;
#endif
	}

	res = IMG_SavePNG(fn, from, comp);
	if(res)
		return EEL_XCANTWRITE;
	return 0;
}
예제 #4
0
    bool screenshot_( const std::string& filename ) noexcept
    {
        int err = 0;
        int w, h;
        SDL_Surface * sshot_surface;

        SDL_GetWindowSize( window, &w, &h );
        sshot_surface = SDL_CreateRGBSurface( 0, w, h, ARGB_DEPTH,
                                              RMASK, GMASK,
                                              BMASK, AMASK );

        if ( sshot_surface == nullptr )
            return false;

        err = SDL_RenderReadPixels( renderer, nullptr, SDL_PIXELFORMAT_RGBA8888,
                                    sshot_surface->pixels, sshot_surface->pitch );

        if ( err == -1 )
        {
            // Cannot read the pixels from the renderer
            SDL_FreeSurface( sshot_surface );
            return false;
        }

        err = IMG_SavePNG( sshot_surface, filename.c_str() );
        SDL_FreeSurface( sshot_surface );

        return err == 0;
    }
예제 #5
0
bool Surface::Save(const char *fn) const
{
#ifdef WITH_IMAGE
    return !surface || !fn || IMG_SavePNG(fn, surface, -1) ? false : true;
#else
    return !surface || !fn || SDL_SaveBMP(surface, fn) ? false : true;
#endif
}
예제 #6
0
파일: graphic.cpp 프로젝트: pyrun/py_engine
void Graphic::SaveImageBMP( std::string File) {
    // Save Image
    File = File + ".png";
    /*SDL_RWops *file = SDL_RWFromFile( File.c_str(), "wb");
    SDL_SaveBMP_RW( m_display->GetSurface(), file, 0);
    file->close(file);*/
    if( IMG_SavePNG( m_display->GetSurface(), File.c_str())) {
        printf("Unable to save png -- %s\n", SDL_GetError());
    }
}
예제 #7
0
CAMLprim value sdlimagestub_savepng(value surf, value file)
{
	CAMLparam2(surf, file);
	int ret = IMG_SavePNG(
		String_val(file),
		SDL_Surface_val(surf),
		IMG_COMPRESS_MAX);
	if(ret != 0) raise_failure();
	CAMLreturn(Val_unit);
}
예제 #8
0
void Texture2dData::store(const util::Path& file) const {
	log::log(MSG(info) << "Saving texture data to " << file);

	if (this->info.get_format() != pixel_format::rgba8) {
		throw Error(MSG(err) << "Storing 2D textures into files is unimplemented. PRs welcome :D");
	}

	auto size = this->info.get_size();

// If an older SDL2 is used, we have to specify the format manually.
#ifndef SDL_PIXELFORMAT_RGBA32
	uint32_t rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
	rmask = 0xff000000;
	gmask = 0x00ff0000;
	bmask = 0x0000ff00;
	amask = 0x000000ff;
#else // little endian, like x86
	rmask = 0x000000ff;
	gmask = 0x0000ff00;
	bmask = 0x00ff0000;
	amask = 0xff000000;
#endif

	std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> surf(
		SDL_CreateRGBSurfaceFrom(
			// const_cast is okay, because the surface doesn't modify data
			const_cast<void*>(static_cast<void const*>(this->data.data())),
			size.first,
			size.second,
			32,
			this->info.get_row_size(),
			rmask, gmask, bmask, amask
		),
		&SDL_FreeSurface
	);
#else
	std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> surf(
		SDL_CreateRGBSurfaceWithFormatFrom(
			// const_cast is okay, because the surface doesn't modify data
			const_cast<void*>(static_cast<void const*>(this->data.data())),
			size.first,
			size.second,
			32,
			this->info.get_row_size(),
			SDL_PIXELFORMAT_RGBA32
		),
		&SDL_FreeSurface
	);
#endif

	// Call sdl_image for saving the screenshot to PNG
	std::string path = file.resolve_native_path_w();
	IMG_SavePNG(surf.get(), path.c_str());
}
예제 #9
0
bool Surface::Save(const std::string & fn) const
{
    int res = 0;

#ifdef WITH_IMAGE
#if SDL_VERSION_ATLEAST(2, 0, 0)
    res = IMG_SavePNG(surface, fn.c_str());
#else
    res = IMG_SavePNG(fn.c_str(), surface, -1);
#endif
#else
    res = SDL_SaveBMP(surface, fn.c_str());
#endif

    if(0 != res)
    {
	ERROR(SDL_GetError());
	return false;
    }

    return true;
}
예제 #10
0
bool save_png ( SDL_SURFACE::RawPtr buffer, const std::string& filename )
{
  if ( buffer == nullptr )
  {
    NOM_LOG_ERR( NOM, "Video surface memory is not valid for saving output");
    return false;
  }

  // Undocumented method for writing out a PNG file with SDL2_image
  if ( IMG_SavePNG ( buffer, filename.c_str() ) != 0 )
  {
    NOM_LOG_ERR(NOM,SDL_GetError());
    return false;
  }

  return true;
}
예제 #11
0
파일: Image.cpp 프로젝트: i8degrees/nomlib
bool Image::save_png ( const std::string& filename ) const
{
  if ( this->valid() == false )
  {
    NOM_LOG_ERR(NOM, "Image is not valid for saving output" );
    return false;
  }

  // Undocumented method for writing out a PNG file with SDL2_image
  if ( IMG_SavePNG ( this->image(), filename.c_str() ) != 0 )
  {
    NOM_LOG_ERR ( NOM, SDL_GetError() );
    return false;
  }

  return true;
}
예제 #12
0
void LectorTerreno::guardarMatrizEnPNG(string nombreArchivo){

	Uint32* vectorPixeles = new Uint32[altoMatriz*anchoMatriz];
	SDL_Surface* surNueva = IMG_Load(propiedadesPNG);

	for(unsigned y = 0; y < altoMatriz; y++)
		for(unsigned x = 0; x < anchoMatriz; x++){
			vectorPixeles[x + (y*anchoMatriz)] = pixelToUint32(matrizTerreno[x][y], surNueva->format);
		}

	surNueva->h = altoMatriz;
	surNueva->w = anchoMatriz;
	surNueva->pitch = anchoMatriz*4;	//pitch: tamaño en bits de cada linea (ancho x bytes por pixel)
	surNueva->pixels = vectorPixeles;
	IMG_SavePNG(surNueva, nombreArchivo.c_str());

	delete[] vectorPixeles;
}
예제 #13
0
void convert(const std::string &fileName) {
    if (fileName.rfind(".bmp") == std::string::npos) return;
    std::string out = fileName;
    size_t extPos = out.rfind('.');
    if (extPos != std::string::npos) out = out.substr(0, extPos);
    out += ".png";
    if (!g_dryrun) {
        SDL_Surface *surf = IMG_Load(fileName.c_str());
        if (!surf) {
            std::cerr << std::string("Couldn't open ") << fileName << ": " << IMG_GetError() << std::endl;
            return;
        }
        uint8_t r, g, b, a;
        if (surf->format->palette) {
            SDL_GetRGBA(0, surf->format, &r, &g, &b, &a);
            std::cout << fileName << ": converting [" << uint16_t(r) << ", " << uint16_t(g) << ", " <<
                uint16_t(b) << ", " << uint16_t(a) << "] to alpha" << std::endl;
            SDL_SetColorKey(surf, SDL_TRUE, 0);
        }
        else {
            std::cout << fileName << ": no palette" << std::endl;
        }
        SDL_Surface *other = SDL_ConvertSurfaceFormat(surf, SDL_PIXELFORMAT_RGBA8888, 0);
        SDL_FreeSurface(surf);
        if (!other) {
            std::cerr << "Couldn't convert " << fileName << ": " << SDL_GetError() << std::endl;
            return;
        }
        uint32_t *pixels = (uint32_t *)other->pixels;
        for (int i = 0; i < other->w * other->h; i++, pixels++) {
            SDL_GetRGBA(*pixels, other->format, &r, &g, &b, &a);
            float aFloat = a / 255;
            r *= aFloat; g *= aFloat; b *= aFloat;
            *pixels = SDL_MapRGBA(other->format, r, g, b, a);
        }
        if (IMG_SavePNG(other, out.c_str()) == -1)
            std::cerr << "Couldn't save " << out << ":" << IMG_GetError() << std::endl;
        SDL_FreeSurface(other);
    }
    else
    {
        std::cout << "converting " << fileName << " to " << out << std::endl;
    }
}
예제 #14
0
파일: image_sdl.c 프로젝트: IvwsIgeMq/libsg
int image_sdl_save(SDL_Surface *src, const char *path,
				   enum img_fmt fmt)
{
	int ret = -1;

	assert(src);
	assert(path);
	assert(strlen(path) > 0);
	assert(fmt != IMGFMT_NONE);

	if(fmt == IMGFMT_PNG) {
		ret = IMG_SavePNG(src, path);
		if(ret != 0)
			sg_log_err("Image save error, %s.", SDL_GetError());
	} else
		sg_log_err("Only png is supportted for now.");

	return ret;
}
예제 #15
0
void ScreenshotManager::save_screenshot() {
	std::string filename = this->gen_next_filename();

	log::log(MSG(info) << "Saving screenshot to " << filename);

	int32_t rmask, gmask, bmask, amask;
	rmask = 0x000000FF;
	gmask = 0x0000FF00;
	bmask = 0x00FF0000;
	amask = 0xFF000000;

	SDL_Surface *screen = SDL_CreateRGBSurface(
	SDL_SWSURFACE,
	this->window_size.x,
	this->window_size.y,
	32,
	rmask, gmask, bmask, amask);

	size_t pxcount = screen->w * screen->h;

	auto pxdata = std::make_unique<uint32_t[]>(pxcount);

	glReadPixels(0, 0,
	             this->window_size.x, this->window_size.y,
	             GL_RGBA, GL_UNSIGNED_BYTE, pxdata.get());

	uint32_t *surface_pxls = (uint32_t *)screen->pixels;

	// we need to invert all pixel rows, but leave column order the same.
	for (ssize_t row = 0; row < screen->h; row++) {
		ssize_t irow = screen->h - 1 - row;
		for (ssize_t col = 0; col < screen->w; col++) {
			uint32_t pxl = pxdata[irow * screen->w + col];

			// TODO: store the alpha channels in the screenshot, is buggy at the moment..
			surface_pxls[row * screen->w + col] = pxl | 0xFF000000;
		}
	}

	// call sdl_image for saving the screenshot to png
	IMG_SavePNG(screen, filename.c_str());
	SDL_FreeSurface(screen);
}
예제 #16
0
void SDLFrontend::makeScreenshot (const std::string& filename)
{
	assert(_renderer);

	SDL_Rect viewport;
	int bpp;
	Uint32 rmask, gmask, bmask, amask;

	SDL_RenderGetViewport(_renderer, &viewport);

	SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_RGBA8888, &bpp, &rmask, &gmask, &bmask, &amask);
	ScopedPtr<SDL_Surface> surface(SDL_CreateRGBSurface(0, viewport.w, viewport.h, bpp, rmask, gmask, bmask, amask));
	if (!surface)
		return;

	if (SDL_RenderReadPixels(_renderer, nullptr, surface->format->format, surface->pixels, surface->pitch) < 0)
		return;

	const std::string fullFilename = FS.getAbsoluteWritePath() + filename + "-" + dateutil::getDateString() + ".png";
	IMG_SavePNG(surface, fullFilename.c_str());
}
예제 #17
0
int write_image( const Image& image, const char *filename )
{
    if(std::string(filename).rfind(".png") == std::string::npos && std::string(filename).rfind(".PNG") == std::string::npos )
    {
        printf("writing color image '%s'... failed, not a PNG image.\n", filename);
        return -1;
    }
    
    // flip de l'image : Y inverse entre GL et BMP
    Image flip= create_image(image.width, image.height, 4, make_color(0, 0, 0));
    for(int y= 0; y < image.height; y++)
    for(int x= 0; x < image.width; x++)
        image_set_pixel(flip, x, image.height - y -1, image_pixel(image, x, y));

    SDL_Surface *bmp= SDL_CreateRGBSurfaceFrom((void *) &flip.data.front(),
        image.width, image.height,
        32, image.width * 4,
#if 0
        0xFF000000,
        0x00FF0000,
        0x0000FF00,
        0x000000FF
#else
        0x000000FF,
        0x0000FF00,
        0x00FF0000,
        0xFF000000
#endif
    );

    int code= IMG_SavePNG(bmp, filename);
    SDL_FreeSurface(bmp);
    release_image(flip);
    
    if(code < 0)
        printf("writing color image '%s'... failed\n%s\n", filename, SDL_GetError());
    else
        printf("writing color image '%s'...\n", filename);
    return code;
}
예제 #18
0
std::string WadImageCache::image_to_new_name(SDL_Surface *image, int32 *filesize) const
{
	// create name
	boost::uuids::random_generator gen;
	boost::uuids::uuid u = gen();
	std::string ustr = boost::uuids::to_string(u);
	
	FileSpecifier File;
	File.SetToImageCacheDir();
	File.AddPart(ustr);
	
	FileSpecifier TempFile;
	TempFile.SetTempName(File);
	
	int ret;
//#if defined(HAVE_PNG) && defined(HAVE_SDL_IMAGE)
//	ret = aoIMG_SavePNG(TempFile.GetPath(), image, IMG_COMPRESS_DEFAULT, NULL, 0);
#ifdef HAVE_SDL_IMAGE
	ret = IMG_SavePNG(image, TempFile.GetPath());
#else
	ret = SDL_SaveBMP(image, TempFile.GetPath());
#endif
	if (ret == 0 && TempFile.Rename(File))
	{
		if (filesize)
		{
			OpenedFile of;
			if (File.Open(of))
				of.GetLength(*filesize);
		}
		return ustr;
	}
	
	if (filesize)
		*filesize = 0;
	return "";
}
예제 #19
0
void ProcessFile(char* fileName)
{
    SDL_Surface* font = IMG_Load(fileName);

    if (font == NULL)
    {
        fprintf(stderr, "File not found or not correct image format.\n");
        return;
    }

    if (font->format->BitsPerPixel != 32)
    {
        fprintf(stderr, "Pixel format is not 32bit.\n");
        return;
    }

    Uint32* pix = (Uint32*)font->pixels;

    FRectangle* charRectangle;
    int currentCharIndex = 0;

    State = SEEKING;

    int i = 0, j = 0;

    int iters = 0;

    while (true)
    {
        if (i >= font->w)
        {
            return;
        }

        Uint32 px = pix[i + (j * font->w)];

        switch (State)
        {
            case SEEKING:
            {
                if (j >= font->h)
                {
                    i++;
                    j = 0;
                }
                else
                {
                    if (px != BLANK)
                    {
                        State = BEGIN_CHAR;
                    }
                    else
                    {
                        j++;
                    }
                }

                break;
            }
            case BEGIN_CHAR:
            {
                charRectangle = new FRectangle();
                charRectangle->Left = i;
                charRectangle->Top = j;
                charRectangle->Right = i;
                charRectangle->Bottom = j;

                State = PIXEL_FOUND;

                break;
            }
            case LINE_SEEK:
            {
                if (j >= font->h)
                {
                    if (charRectangle->Right != i)
                    {
                        State = END_CHAR;
                    }

                    i++;
                    j = 0;
                }
                else
                {
                    if (px != BLANK)
                    {
                        State = PIXEL_FOUND;
                        break;
                    }

                    j++;
                }

                break;
            }
            case PIXEL_FOUND:
            {
                if (j >= font->h)
                {
                    State = LINE_SEEK;
                    break;
                }

                if (px != BLANK)
                {
                    if (j < charRectangle->Top)
                    {
                        charRectangle->Top = j;
                    }
                    if (j > charRectangle->Bottom)
                    {
                        charRectangle->Bottom = j;
                    }
                    if (i > charRectangle->Right)
                    {
                        charRectangle->Right = i;
                    }
                }

                j++;

                break;
            }
            case END_CHAR:
            {
                SDL_Rect rec = FRectToSDL_Rect(*charRectangle);
                rec.w += 1; // Have to add +1 to w and h to compensate the comversion from my rec to sdl rec. TODO : Problem in FRect impl ?
                rec.h += 1;

                SDL_Surface* subSurf = SDL_CreateRGBSurface(0, rec.w, rec.h, 32, font->format->Rmask, font->format->Gmask, font->format->Bmask, font->format->Amask);

                SDL_BlitSurface(font, &rec, subSurf, NULL);

                char fileName[260];
                if (islower(CharacterSet[currentCharIndex]))
                {
                    sprintf(fileName, "letters/%c_.png", CharacterSet[currentCharIndex]);
                }
                else
                {
                    sprintf(fileName, "letters/%c.png", CharacterSet[currentCharIndex]);
                }

                IMG_SavePNG(subSurf, fileName);

                currentCharIndex++;

                State = SEEKING;

                break;
            }
        }

        iters++;
    }
}
예제 #20
0
파일: misc.c 프로젝트: csiga/Eternal-Lands
void makeScreenShot ()
{
	char fname[256];
	int ret;
	int align;
	int dlen, ishot, iline, w = window_width, h = window_height;
	unsigned char *pixels;
	SDL_Surface *surf;
	
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
	int rmask = 0x00ff0000;
	int gmask = 0x0000ff00;
	int bmask = 0x000000ff;
#else
	int rmask = 0x000000ff;
	int gmask = 0x0000ff00;
	int bmask = 0x00ff0000;
#endif
	int amask = 0x00000000;

	/* see if the screenshots directory exists */
	safe_snprintf (fname, sizeof (fname), "%sscreenshots", configdir);

	ret = file_exists(fname);
	if(ret == 0)
	{
		if(MKDIR(fname) < 0)
		{
			LOG_ERROR ("Unable to create directory \"%s\"\n", fname);
			return;
		}
	}
	else if (ret == -1)
	{
		return;
	}

	dlen = strlen (fname);

	/* try to find a file name which isn't taken yet */
	for (ishot = 1; ishot < 1000; ishot++)
	{
		safe_snprintf (fname+dlen, sizeof(fname)-dlen, "/elscreen%03d.png", ishot);
		ret = file_exists(fname);
		if(ret == 0)
		{
			break;
		}
		else if(ret == -1)
		{
			return; //we hit an error, it's already reported
		}
	}

	/* if all numbered file names have been taken, use the default */
	if (ishot >= 1000)
	{
		LOG_TO_CONSOLE(c_red2, max_screenshots_warning_str);
		safe_snprintf (fname+dlen, sizeof(fname)-dlen, "/elscreen.png");
	}
	LOG_TO_CONSOLE(c_green1, fname);

	/* read the pixels from the GL scene */
	glGetIntegerv(GL_PACK_ALIGNMENT, &align);
	pixels = malloc(h * align * ((3 * w - 1) / align + 1));
	glReadPixels (0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, pixels);
	/* Let SDL worry about creating a BMP from it: create a surface */
	surf = SDL_CreateRGBSurface (SDL_SWSURFACE, w, h, 24, rmask, gmask, bmask, amask);

	/* simply memcpy'ing the pixels results in an upside-down image,
	 * so copy the lines in reverse order */
	if (SDL_MUSTLOCK(surf)) SDL_LockSurface(surf);
	for (iline = 0; iline < h; iline++)
		memcpy ((char *)surf->pixels + surf->pitch*iline, pixels + surf->pitch*(h-iline-1), 3*w);
	if (SDL_MUSTLOCK(surf)) SDL_UnlockSurface(surf);
	//SDL_SaveBMP (surf, fname);
	IMG_SavePNG (surf, fname);
	free (pixels);
	SDL_FreeSurface (surf);
}
예제 #21
0
    // =========================================================================
    int main(int argc, char** argv)
    {
        const char * usage = "Usage: lmu2png map.lmu chipset.png output.png\n";

        if(argc < 4 || argc > 5)
        {
            std::cout<<usage;
            exit(EXIT_FAILURE);
        }

        const char* map_path = argv[1];
        const char* chipset_path = argv[2];
        const char* output_path = argv[3];

        std::unique_ptr<RPG::Map> map = LMU_Reader::Load(map_path, "");
        if (map.get() == NULL)
        {
            std::cerr<<LcfReader::GetError()<<std::endl;
            exit(EXIT_FAILURE);
        }

        SDL_Surface* chipset = IMG_Load(chipset_path);
        if (chipset == NULL)
        {
            std::cerr<<IMG_GetError()<<std::endl;
            exit(EXIT_FAILURE);
        }

        if (IMG_isBMP(SDL_RWFromFile(chipset_path, "rb")))
        {
            // Set as color key the first color in the palette
            SDL_Color ckey = chipset->format->palette->colors[0];
            SDL_SetColorKey(chipset, SDL_TRUE, SDL_MapRGB(chipset->format, ckey.r, ckey.g, ckey.b));
        }

        SDL_Surface* output = SDL_CreateRGBSurface(0, map->width * 16, map->height * 16, 8, 0, 0, 0, 0);
        output->format->palette = chipset->format->palette;
        stChipset gen;
        gen.GenerateFromSurface(chipset);

        for (int y = 0; y < map->height; ++y)
            for (int x = 0; x < map->width; ++x)
            {
                gen.RenderTile(output, x*16, y*16, map->lower_layer[x+y*map->width], 0);
                gen.RenderTile(output, x*16, y*16, map->upper_layer[x+y*map->width], 0);
            }

        std::vector<RPG::Event>::iterator ev;
        for (ev = map->events.begin(); ev != map->events.end(); ++ev)
        {
            RPG::EventPage evp = ev->pages[0];
            if (evp.character_name.empty())
                gen.RenderTile(output, (ev->x)*16, (ev->y)*16, 0x2710 + evp.character_index, 0);
        }

        if(IMG_SavePNG(output, output_path) < 0)
        {
	    std::cerr<<IMG_GetError()<<std::endl;
	    exit(EXIT_FAILURE);
        }

        exit(EXIT_SUCCESS);
}
예제 #22
0
SDL_Surface *LoadSvg(char *fname, int hor_width, int hor_height, bool rot, bool cache)
{
    SDL_Surface *res = NULL;
    bool skip = false;

    rsvg_init();

    GError *error = NULL;
    RsvgHandle *rsvg_handle = rsvg_handle_new_from_file(fname, &error);
    if (!rsvg_handle)
    {
        log_error("can't load vector image `%s'", fname);
        LoadImgErrors++;
        skip = true;
    }

    if (!skip)
    {
        RsvgDimensionData dimensions;
        rsvg_handle_get_dimensions(rsvg_handle, &dimensions);
        int svg_width = dimensions.width;
        int svg_height = dimensions.height;

        float svg_koef = (float)svg_width / svg_height;
        float hor_koef = (float)hor_width / hor_height;
        float scale = (svg_koef > hor_koef ? (float)hor_height / svg_height : (float)hor_width / svg_width);

        int scaled_width = (int)(svg_width * scale);
        int scaled_height = (int)(svg_height * scale);

        int res_width = (rot ? hor_height : hor_width);
        int res_height = (rot ? hor_width : hor_height);

        bool loaded_from_cache = false;
        char *cached_file_full = NULL;
        char *file = NULL;
        char *file_hash = NULL;
        if (cache && can_cache)
        {
            int mod_time = 0;
            struct stat st;
            if (stat(fname, &st) == 0)
                mod_time = st.st_mtime;

            char *last_slash_ptr = strrchr(fname, '/');
            file = (last_slash_ptr ? last_slash_ptr + 1 : fname);
            int max_overhead = 64;
            cached_file_full = (char*)malloc(strlen(cache_dir_full) + strlen("/") + strlen(file) + max_overhead + 1);
            file_hash = (char*)malloc(strlen(file) + max_overhead + 1);

            char *state = (rot ? "rotated" : "normal");
            sprintf(cached_file_full, "%s/%s_%x-%dx%d-%s.png", cache_dir_full, file, mod_time, res_width, res_height, state);
            sprintf(file_hash, "%s_%x", file, mod_time);

            res = LoadImg(cached_file_full, false);
            if (res)
            {
                log_info("vector image `%s' was loaded from cache `%s'", fname, cached_file_full);
                loaded_from_cache = true;
            }
        }

        if (!loaded_from_cache)
        {
            int stride = res_width * 4; /* 4 bytes/pixel (32bpp RGBA) */
            void *image = calloc(stride * res_height, 1);
            cairo_surface_t *cairo_surf = cairo_image_surface_create_for_data(
                                              image, CAIRO_FORMAT_ARGB32,
                                              res_width, res_height, stride);
            cairo_t *cr = cairo_create(cairo_surf);

            if (rot)
            {
                cairo_translate(cr, -(scaled_height-res_width)/2, res_height+(scaled_width-res_height)/2);
                cairo_scale(cr, scale, scale);
                cairo_rotate(cr, -M_PI/2);
            }
            else
            {
                cairo_translate(cr, -(scaled_width-res_width)/2, -(scaled_height-res_height)/2);
                cairo_scale(cr, scale, scale);
            }

            rsvg_handle_render_cairo(rsvg_handle, cr);

            cairo_surface_finish(cairo_surf);
            cairo_destroy(cr);

            uint32_t rmask = 0x00ff0000;
            uint32_t gmask = 0x0000ff00;
            uint32_t bmask = 0x000000ff;
            uint32_t amask = 0xff000000;
            //Notice that it matches CAIRO_FORMAT_ARGB32
            res = SDL_CreateRGBSurfaceFrom(
                      (void*) image,
                      res_width, res_height,
                      32, //4 bytes/pixel = 32bpp
                      stride,
                      rmask, gmask, bmask, amask);
        }

        if (cache && can_cache)
        {
            if (!loaded_from_cache && res)
            {
                if (TouchDir(save_dir_full) && TouchDir(cache_dir_full))
                {
                    ClearCache(file, file_hash);
                    if (IMG_SavePNG(res, cached_file_full) == 0)
                        log_info("vector image `%s' was cached to `%s'", fname, cached_file_full);
                    else
                        log_error("can't cache vector image `%s' to `%s'", fname, cached_file_full);
                }
                else
                    can_cache = false;
            }
            free(cached_file_full);
            free(file_hash);
        }
    }

    rsvg_term();

    return res;
}
예제 #23
0
void dump_screen(void)
{
	// Find suitable file name
	FileSpecifier file;
	int i = 0;
	do {
		char name[256];
		const char* suffix;
#ifdef HAVE_PNG
		suffix = "png";
#else
		suffix = "bmp";
#endif
		if (get_game_state() == _game_in_progress)
		{
			sprintf(name, "%s_%04d.%s", to_alnum(static_world->level_name).c_str(), i, suffix);
		}
		else
		{
			sprintf(name, "Screenshot_%04d.%s", i, suffix);
		}

		file = screenshots_dir + name;
		i++;
	} while (file.Exists());

#ifdef HAVE_PNG
	// build some nice metadata
	std::vector<IMG_PNG_text> texts;
	std::map<std::string, std::string> metadata;

	metadata["Source"] = expand_app_variables("$appName$ $appVersion$ ($appPlatform$)");

	time_t rawtime;
	time(&rawtime);
	
	char time_string[32];
	strftime(time_string, 32,"%d %b %Y %H:%M:%S +0000", gmtime(&rawtime));
	metadata["Creation Time"] = time_string;

	if (get_game_state() == _game_in_progress)
	{
		const float FLOAT_WORLD_ONE = float(WORLD_ONE);
		const float AngleConvert = 360/float(FULL_CIRCLE);

		metadata["Level"] = static_world->level_name;

		char map_file_name[256];
		FileSpecifier fs = environment_preferences->map_file;
		fs.GetName(map_file_name);
		metadata["Map File"] = map_file_name;

		if (Scenario::instance()->GetName().size())
		{
			metadata["Scenario"] = Scenario::instance()->GetName();
		}

		metadata["Polygon"] = boost::lexical_cast<std::string>(world_view->origin_polygon_index);
		metadata["X"] = boost::lexical_cast<std::string>(world_view->origin.x / FLOAT_WORLD_ONE);
		metadata["Y"] = boost::lexical_cast<std::string>(world_view->origin.y / FLOAT_WORLD_ONE);
		metadata["Z"] = boost::lexical_cast<std::string>(world_view->origin.z / FLOAT_WORLD_ONE);
		metadata["Yaw"] = boost::lexical_cast<std::string>(world_view->yaw * AngleConvert);


		short pitch = world_view->pitch;
		if (pitch > HALF_CIRCLE) pitch -= HALF_CIRCLE;
		metadata["Pitch"] = boost::lexical_cast<std::string>(pitch * AngleConvert);
	}

	for (std::map<std::string, std::string>::const_iterator it = metadata.begin(); it != metadata.end(); ++it)
	{
		IMG_PNG_text text;
		text.key = const_cast<char*>(it->first.c_str());
		text.value = const_cast<char*>(it->second.c_str());
		texts.push_back(text);
	}

	IMG_PNG_text* textp = texts.size() ? &texts[0] : 0;
#endif

	// Without OpenGL, dumping the screen is easy
	if (!MainScreenIsOpenGL()) {
//#ifdef HAVE_PNG
//		aoIMG_SavePNG(file.GetPath(), MainScreenSurface(), IMG_COMPRESS_DEFAULT, textp, texts.size());
#ifdef HAVE_SDL_IMAGE
		IMG_SavePNG(MainScreenSurface(), file.GetPath());
#else
		SDL_SaveBMP(MainScreenSurface(), file.GetPath());
#endif
		return;
	}
	
	int video_w = MainScreenPixelWidth();
	int video_h = MainScreenPixelHeight();

#ifdef HAVE_OPENGL
	// Otherwise, allocate temporary surface...
	SDL_Surface *t = SDL_CreateRGBSurface(SDL_SWSURFACE, video_w, video_h, 24,
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
	  0x000000ff, 0x0000ff00, 0x00ff0000, 0);
#else
	  0x00ff0000, 0x0000ff00, 0x000000ff, 0);
#endif
	if (t == NULL)
		return;

	// ...and pixel buffer
	void *pixels = malloc(video_w * video_h * 3);
	if (pixels == NULL) {
		SDL_FreeSurface(t);
		return;
	}

	// Read OpenGL frame buffer
	glPixelStorei(GL_PACK_ALIGNMENT, 1);
	glReadPixels(0, 0, video_w, video_h, GL_RGB, GL_UNSIGNED_BYTE, pixels);
	glPixelStorei(GL_PACK_ALIGNMENT, 4);  // return to default

	// Copy pixel buffer (which is upside-down) to surface
	for (int y = 0; y < video_h; y++)
		memcpy((uint8 *)t->pixels + t->pitch * y, (uint8 *)pixels + video_w * 3 * (video_h - y - 1), video_w * 3);
	free(pixels);

	// Save surface
//#ifdef HAVE_PNG
//        aoIMG_SavePNG(file.GetPath(), t, IMG_COMPRESS_DEFAULT, textp, texts.size());
#ifdef HAVE_SDL_IMAGE
	IMG_SavePNG(t, file.GetPath());
#else
	SDL_SaveBMP(t, file.GetPath());
#endif
	SDL_FreeSurface(t);
#endif
}