Sprite2DView::Sprite2DView() : sc(), directory(), shuffle_directory(), mode(), zoom(), pos(), width(), height(), aspect(), index(), sprite(), new_sprite(), fadein(), scale(), offset(), display_time(), show_thumbnail(), ignore_delta(), shuffle(), auto_scroll() { auto_scroll = false; index = 0; for(std::vector<std::string>::iterator i = arg_files.begin(); i != arg_files.end(); ++i) { if (boost::filesystem::is_directory(i->c_str())) { adddir(Pathname(*i, Pathname::kSysPath)); } else { directory.push_back(Pathname(*i, Pathname::kSysPath)); } } shuffle_directory = directory; shuffle = false; //std::sort(shuffle_directory.begin(), shuffle_directory.end()); //std::random_shuffle(shuffle_directory.begin(), shuffle_directory.end()); offset = 0.0f; if (directory.size() > 1) mode = SLIDESHOW; else mode = SLIDESHOW; zoom = 1.0f; pos = Vector2f(0,0); display_time = 0.0f; show_thumbnail = false; ignore_delta = false; next_image(0); sprite = new_sprite; new_sprite = Sprite(); }
Bomb::Bomb(int x, int y) : sprite(Pathname("images/bomb.sprite")), explo(Pathname("images/explo.sprite")), light(Pathname("images/bomblight.sprite")), highlight(Pathname("images/bombhighlight.sprite")), explolight(Pathname("images/explolight.sprite")), pos(static_cast<float>(x), static_cast<float>((y / TILE_SIZE + 1) * TILE_SIZE)), count(2.0f), state(COUNTDOWN), exploded(false) { }
Pathname Pathname::get_dirname() const { std::string::size_type i = m_path.rfind('/'); if (i == std::string::npos) { return Pathname("", m_type); } else { return Pathname(m_path.substr(0, i+1), m_type); } }
Inventory::Inventory() : impl(new InventoryImpl()) { impl->slot = Sprite(Pathname("images/inventory/slot.sprite")); impl->slothighlight = Sprite(Pathname("images/inventory/slothighlight.sprite")); impl->moving = false; impl->add_angle = 0.0f; impl->current_item = 0; impl->items.push_back(InventoryItem("Flashlight", "images/inventory/flashlight.sprite")); impl->items.push_back(InventoryItem("Stone", "images/inventory/stone.sprite")); impl->items.push_back(InventoryItem("PDA", "images/inventory/pda.sprite")); impl->items.push_back(InventoryItem("5x Granates", "images/inventory/granate.sprite")); impl->items.push_back(InventoryItem("Lv1 Keycard", "images/inventory/keycard.sprite")); }
int main() { try { SDLSystem sdl_system; Input::Manager manager; Input::ControllerPtr controller = manager.create_controller(Pathname("../data/controller/default.scm", Pathname::SYSTEM_PATH)); while(true) { std::vector<Input::Event> events; controller->poll_events(events); for(std::vector<Input::Event>::iterator i = events.begin(); i != events.end(); ++i) { // insert code here } manager.update(0.033f); } } catch (std::exception& err) { std::cout << "Exception: " << err.what() << std::endl; } return 0; }
SpriteDescriptionPtr SpriteDescription::from_file(const Pathname& path) { ReaderObject reader_object = FileReader::parse(path); ReaderMapping reader = reader_object.get_mapping(); SpriteDescriptionPtr desc(new SpriteDescription); reader.read_int("speed", desc->speed); reader.read_bool("loop", desc->loop); reader.read_vector2i("offset", desc->offset); reader.read_enum("origin", desc->origin, string2origin); if (!reader.read_path("image", desc->filename)) { log_error("'image' missing for %1%", reader_object.get_name()); } desc->filename = Pathname(desc->filename.get_raw_path(), Pathname::DATA_PATH); // FIXME: Hack reader.read_size("array", desc->array); reader.read_vector2i("position", desc->frame_pos); reader.read_size("size", desc->frame_size); return desc; }
/** Load a level and create the World for each given level, this allows to track missing resources and other problems in level creation */ int main(int argc, char** argv) { g_path_manager.set_path("data"); Resource::init(); Display::create_window(NULL_FRAMEBUFFER, Size(640, 480), false, false); Fonts::init(); Sound::PingusSound::init(); for(int i = 1; i < argc; ++i) { try { std::cout << "Processing: " << argv[i] << " " << i << "/" << (argc-1) << std::endl; PingusLevel plf(Pathname(argv[i], Pathname::SYSTEM_PATH)); World world(plf); } catch(const std::exception& err) { log_error("%1%: exception catched: %2%", argv[i], err.what()); } } Sound::PingusSound::deinit(); Fonts::deinit(); Resource::deinit(); return 0; }
void PingusMain::read_rc_file (void) { if (!cmd_options.no_config_file.is_set() || !cmd_options.no_config_file.get()) { std::string filename = System::get_userdir() + "config"; if (!System::exist(filename)) { log_info(filename << ": config file not found"); } else { try { CommandLineOptions options; options.merge(Options::from_file(Pathname(filename, Pathname::SYSTEM_PATH))); options.merge(cmd_options); cmd_options = options; } catch(const std::exception& err) { log_error(err.what()); } } } }
void EditorScreen::level_new_without_confirm() { // FIXME: dialogs don't update level_pathname = Pathname(); set_level(std::unique_ptr<EditorLevel>(new EditorLevel)); }
Font Resource::load_font(const std::string& res_name) { FontDescription desc(Pathname("images/" + res_name + ".font", Pathname::DATA_PATH)); //("data/images/fonts/chalk_large-iso-8859-1.font"); return Font(desc); }
DemoSession::DemoSession(const Pathname& pathname_) : pathname(pathname_), server(), demo(), events(), fastforward_button(), pause_button(), restart_button(), pause(false), fast_forward(false) { // Load Demo file demo = std::unique_ptr<PingusDemo>(new PingusDemo(pathname)); events = demo->get_events(); // Reverse the vector so that we can use pop_back() std::reverse(events.begin(), events.end()); // Create server plf = PingusLevel(Pathname("levels/" + demo->get_levelname() + ".pingus", Pathname::DATA_PATH)); if (plf.get_checksum() != demo->get_checksum()) { log_warn("checksum missmatch between demo (%1%) and level (%2%)", demo->get_checksum(), plf.get_checksum()); } // Create GUI DemoSession* self = this; ceu_out_go(&CEUapp, CEU_IN_NEW_DEMO_SESSION, &self); }
CSString CreateSrStringFilename (const char* pFilename, const char* pExtension) { CSString BaseFilename(pFilename); CSString Pathname(pFilename); CSString Extension(pExtension); CSString Filename; int Index; Index = Pathname.FindCharR('\\'); if (Index > 0) { Pathname.Truncate(Index); Pathname += "\\"; BaseFilename.Delete(0, Index+1); } else { Pathname.Empty(); } Pathname += "Strings\\"; Index = BaseFilename.FindCharR('.'); if (Index > 0) BaseFilename.Truncate(Index); Filename = Pathname + BaseFilename; Filename += "_" + g_SrLanguage + "." + Extension; return Filename; }
VRDummy::VRDummy(const FileReader& props) : sprite(), highlight(), rotation(), jump_time() { props.get("name", name); props.get("pos", pos); sprite = Sprite3D(Pathname("models/characters/vrdummy/vrdummy.wsprite")); rotation = 0; highlight = Sprite(Pathname("images/hedgehog_highlight.sprite")); highlight.set_blend_func(GL_SRC_ALPHA, GL_ONE); jump_time = 0; }
DeformDrawer::DeformDrawer(FileReader& /*props*/) : framebuffer(Framebuffer::create_with_texture(GL_TEXTURE_2D, 800, 600)), surface(Surface::create(Pathname("images/particles/deform2.png"))), shader_program(ShaderProgram::create()) { shader_program->attach(ShaderObject::create_from_file(GL_FRAGMENT_SHADER, "data/shader/particledeform.frag")); shader_program->link(); }
void PingusMenu::do_start(const std::string &filename) { // Start the story or worldmap mode Sound::PingusSound::play_sound ("letsgo"); std::shared_ptr<WorldmapNS::WorldmapScreen> worldmap_screen = std::make_shared<WorldmapNS::WorldmapScreen>(); worldmap_screen->load(Pathname(filename, Pathname::DATA_PATH)); ScreenManager::instance()->push_screen(worldmap_screen); bool story_seen = false; StatManager::instance()->get_bool("tutorial-startstory-seen", story_seen); // FIXME: Hardcoding tutorial is evil if (!story_seen) { ReaderObject reader = Reader::parse(Pathname("stories/tutorial_intro.story", Pathname::DATA_PATH)); ScreenManager::instance()->push_screen(std::make_shared<StoryScreen>(reader.get_mapping())); StatManager::instance()->set_bool("tutorial-startstory-seen", true); } }
KAI_BEGIN Pathname GetFullname(const Object &Q) { if (!Q.Valid()) return Pathname(); return GetFullname(GetStorageBase(Q)); }
int Lensflare::run() { SDL sdl; OpenGLWindow window("Shader Test", m_window_size, // window size m_aspect_ratio, // aspect ratio m_fullscreen, // fullscreen 4); // anti-alias TextureManager texture_manager; SurfaceManager surface_manager; if (!GLEW_ARB_occlusion_query) { throw std::runtime_error("GL_ARB_occlusion_query not supported"); } m_light = Surface::create(Pathname("light.png", Pathname::kSysPath)); m_lightquery = Surface::create(Pathname("lightquery.png", Pathname::kSysPath)); m_superlight = Surface::create(Pathname("superlight.png", Pathname::kSysPath)); m_flair1 = Surface::create(Pathname("flair1.png", Pathname::kSysPath)); m_flair2 = Surface::create(Pathname("flair2.png", Pathname::kSysPath)); m_cover = Surface::create(Pathname("cover.png", Pathname::kSysPath)); m_halo = Surface::create(Pathname("halo.png", Pathname::kSysPath)); float pos[] = { 0.1f, 0.2f, 0.4f, 0.8f, 1.6f, 3.2f }; for(size_t i = 0; i < sizeof(pos)/sizeof(float); ++i) { m_flairs.push_back(Flair(m_flair2, pos[i], 1.0f * pos[i], Color(1,1,1,1))); m_flairs.push_back(Flair(m_flair2, -pos[i] * 0.7f, 1.0f * pos[i] * 0.7f, Color(1,1,1,1))); } for(size_t i = 0; i < sizeof(pos)/sizeof(float); ++i) { m_flairs.push_back(Flair(m_flair1, pos[i]* 0.2f, 1.0f * pos[i] * 0.2f, Color(1,1,1,0.1f))); m_flairs.push_back(Flair(m_flair1, -pos[i] * 0.1f, 1.0f * pos[i] * 0.1f, Color(1,1,1,0.1f))); } GLint query_counter_bits = 0; glGetQueryiv(GL_SAMPLES_PASSED, GL_QUERY_COUNTER_BITS, &query_counter_bits); if (query_counter_bits == 0) { std::cout << "Occlusion query not supported" << std::endl; } m_loop = true; while(m_loop) { glClearColor(0,0,0,1); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); process_input(); draw(); window.swap_buffers(); } return 0; }
std::shared_ptr<SpriteDescription> ResourceManager::get_sprite_description_from_file(const std::string& resname) { // try to load a .sprite file std::string filename = "images/" + resname + ".sprite"; Pathname path(filename, Pathname::DATA_PATH); if (path.exist()) { SpriteDescriptionPtr desc = SpriteDescription::from_file(path); // resolve relative filenames if (!desc->filename.absolute()) { desc->filename = Pathname(System::dirname(filename) + "/" + desc->filename.get_raw_path(), Pathname::DATA_PATH); } return desc; } // try to load a .png file filename = "images/" + resname + ".png"; path = Pathname(filename, Pathname::DATA_PATH); if (path.exist()) { SpriteDescriptionPtr desc(new SpriteDescription); desc->filename = path; return desc; } // try to load a .jpg file filename = "images/" + resname + ".jpg"; path = Pathname(filename, Pathname::DATA_PATH); if (path.exist()) { SpriteDescriptionPtr desc(new SpriteDescription); desc->filename = path; return desc; } // give up return SpriteDescriptionPtr(); }
void StoryDot::on_click() { try { ReaderObject reader = Reader::parse(Pathname(m_story, Pathname::DATA_PATH)); ScreenManager::instance()->push_screen(std::make_shared<StoryScreen>(reader.get_mapping(), m_credits)); } catch(const std::exception& err) { log_error("%1%", err.what()); } }
Pathname Pathname::get_basename() const { std::string::size_type i = m_path.rfind('/'); if (i == std::string::npos) { return *this; } else { return Pathname(m_path.substr(i+1), m_type); } }
///////////////////////////////////////////////////////////////////////////////////////// // //创建/打开文件 // //特性:文件不存在--创建,文件存在--打开文件并把属性设为NORMAL,即可以写只读文件。关闭 // 文件时恢复文件原属性。根据参数dwCreate: // = RF_NEW -- 清除文件,截断为0 // = RF_APPEND -- 文件指针移到文件尾 // = RF_EDIT -- 打开文件 // //返回:文件不存在--FALSE,成功--TRUE // BOOL ringFile::Create(DWORD dwCreate,DWORD dwAttr/*=FILE_ATTRIBUTE_NORMAL*/) { DWORD dwMode = RF_EDIT; if(m_hFile) { if(dwCreate == RF_APPEND) Seek(0,FILE_END); else if(dwCreate == RF_NEW) Seek(0); return TRUE; } switch(m_aAttrib) { case RFA_FILE: //临时文件无须设置属性 if((m_dwFileAttr & FILE_ATTRIBUTE_TEMPORARY) != FILE_ATTRIBUTE_TEMPORARY) SetFileAttributes(m_szFilename,FILE_ATTRIBUTE_NORMAL); if(dwCreate == RF_NEW) dwMode = TRUNCATE_EXISTING; break; case RFA_NOTEXIST: MkDir(Pathname()); m_dwFileAttr = dwAttr; break; default: return FALSE; } m_hFile = CreateFile(m_szFilename,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,dwMode,FILE_ATTRIBUTE_NORMAL,NULL); if(m_hFile==INVALID_HANDLE_VALUE) { m_hFile = NULL; m_dwFileAttr = 0xffffffff; m_aAttrib = RFA_NOTEXIST; return FALSE; } else { if(dwCreate == RF_APPEND) SeekToEnd(); m_dwFileSize = ::GetFileSize(m_hFile,NULL); return TRUE; } }
BOOL ringFile::reName(LPCTSTR lpNewName) { if(m_bExtern || lpNewName == NULL || *lpNewName == '\0') return FALSE; char dbuf[MAX_PATH]; char szTemp[MAX_PATH]; strcpy(szTemp,Pathname()); if(szTemp[strlen(szTemp)-1] == '\\') szTemp[strlen(szTemp)-1] = 0; wsprintf(dbuf,"%s\\%s\0\0",szTemp,lpNewName); return moveTo((LPSTR)dbuf,FALSE); }
CSString CreateSrStringPathname (const char* pFilename) { CSString Pathname(pFilename); int Index; Index = Pathname.FindCharR('\\'); if (Index > 0) { Pathname.Truncate(Index); Pathname += "\\"; } else { Pathname.Empty(); } Pathname += "Strings\\"; return Pathname; }
FramebufferSurface load_framebuffer_surface(const Pathname& filename, ResourceModifier::Enum modifier) { // FIXME: Implement proper cache try { Surface surface(filename); if (modifier != ResourceModifier::ROT0) { surface = surface.mod(modifier); } return Display::get_framebuffer()->create_surface(surface); } catch(const std::exception& err) { // return a dummy surface for cases where the image file can't be found log_error("%1%", err.what()); Surface surface(Pathname("images/core/misc/404.png", Pathname::DATA_PATH)); return Display::get_framebuffer()->create_surface(surface); } }
Surface Resource::load_surface(const ResDescriptor& desc_) { SpriteDescription* desc = resmgr.get_sprite_description(desc_.res_name); if (desc) { if (desc->array != Size(1, 1) || desc->frame_pos != Vector2i(0, 0) || desc->frame_size != Size(-1, -1)) { Surface surface(desc->filename); surface = surface.subsection(Rect(desc->frame_pos, desc->frame_size)); if (desc_.modifier == ResourceModifier::ROT0) { return surface; } else { return surface.mod(desc_.modifier); } } else { if (desc_.modifier == ResourceModifier::ROT0) { return Surface(desc->filename); } else { return Surface(desc->filename).mod(desc_.modifier); } } } else { log_error("failed to load surface: %1%", desc_.res_name); return Surface(Pathname("images/core/misc/404.png", Pathname::DATA_PATH)); } }
bool ReaderMapping::read_path(const char* key, Pathname& value) const { if (m_impl) { std::string filename; if (m_impl->read_string(key, filename)) { value = Pathname(filename, Pathname::DATA_PATH); return true; } else { return false; } } else { return false; } }
ParticleSystems::ParticleSystems(const FileReader& reader) : m_systems(), m_drawables() { std::string filename; Vector2f pos; reader.get("name", filename); reader.get("pos", pos); { // Load the ParticleSystems FileReader root_reader = FileReader::parse(Pathname(filename)); if(root_reader.get_name() != "particle-systems") { std::ostringstream msg; msg << "'" << filename << "' is not a particle-system file"; throw std::runtime_error(msg.str()); } std::vector<FileReader> sections = root_reader.get_sections(); for(std::vector<FileReader>::iterator i = sections.begin(); i != sections.end(); ++i) { if (i->get_name() == "particle-system") { boost::shared_ptr<ParticleSystem> particle_system(new ParticleSystem(*i)); particle_system->set_pos(pos); m_systems.push_back(particle_system); } } } for(Systems::iterator i = m_systems.begin(); i != m_systems.end(); ++i) { boost::shared_ptr<ParticleSystemDrawable> drawable(new ParticleSystemDrawable(**i)); m_drawables.push_back(drawable); Sector::current()->get_scene_graph().add_drawable(drawable); } }
int main(int argc, char** argv) { std::vector<Pathname> files; enum { kTitle = (1<<0), kDescription = (1<<1), kLevels = (1<<2), kFilename = (1<<3) }; unsigned int mode = 0; CommandLine argp; argp.add_usage("[OPTIONS]... [FILE]..."); argp.add_option('h', "help", "", "Displays this help"); argp.add_option('t', "title", "", "Display title of the levelset"); argp.add_option('d', "description", "", "Display description of the levelset"); argp.add_option('l', "levels", "", "Display levels in this levelset"); argp.add_option('f', "filename", "", "Display filename of the level"); argp.parse_args(argc, argv); argp.set_help_indent(20); while (argp.next()) { switch (argp.get_key()) { case 'h': argp.print_help(); exit(EXIT_SUCCESS); break; case 't': mode |= kTitle; break; case 'd': mode |= kDescription; break; case 'l': mode |= kLevels; break; case 'f': mode |= kFilename; break; case CommandLine::REST_ARG: files.push_back(Pathname(argp.get_argument(), Pathname::SYSTEM_PATH)); break; } } if (files.empty()) { argp.print_help(); exit(EXIT_SUCCESS); } else { // FIXME: a little ugly that levelset loads sprites and savegames System::init_directories(); g_path_manager.set_path("data/"); SavegameManager savegame_manager("savegames/savegames.scm"); StatManager stat_manager("savegames/variables.scm"); Resource::init(); Display::create_window(NULL_FRAMEBUFFER, Size(), false, false); for(auto it = files.begin(); it != files.end(); ++it) { const Pathname& path = *it; std::unique_ptr<Levelset> levelset = Levelset::from_file(path); if (mode == 0) { std::cout << "filename : " << path << std::endl; std::cout << "title : " << levelset->get_title() << std::endl; std::cout << "description : " << levelset->get_description() << std::endl; std::cout << "levels : " << std::endl; for(int i = 0; i < levelset->get_level_count(); ++i) { std::cout << " " << levelset->get_level(i)->resname << std::endl; } std::cout << std::endl; } else { if (mode & kFilename) { std::cout << path << ": "; } if (mode & kTitle) { std::cout << levelset->get_title() << std::endl; } if (mode & kDescription) { std::cout << levelset->get_description() << std::endl; } if (mode & kLevels) { for(int i = 0; i < levelset->get_level_count(); ++i) { std::cout << " " << levelset->get_level(i)->resname << std::endl; } std::cout << std::endl; } } } Resource::deinit(); } return 0; }
OpenGLWindow::OpenGLWindow(const std::string& title, const Size& size, const Size& aspect, bool fullscreen, int anti_aliasing) : m_impl(new OpenGLWindowImpl) { m_impl->m_size = size; //SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); // vsync SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // FIXME: Should make this configurable, as Matrox G450 can't do it, // but works 'fine' without it SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); if (anti_aliasing) { SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 ); // boolean value, either it's enabled or not SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, anti_aliasing ); // 0, 2, or 4 for number of samples } SDL_WM_SetCaption(title.c_str(), title.c_str()); SDL_WM_SetIcon(IMG_Load(Pathname("icon.png").get_sys_path().c_str()), NULL); m_impl->m_window = SDL_SetVideoMode(size.width, size.height, 0, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0)); if (!m_impl->m_window) { throw std::runtime_error("Display:: Couldn't create window"); } else { GLenum err = glewInit(); if (err != GLEW_OK) { std::ostringstream msg; msg << "Display:: Couldn't initialize glew: " << glewGetString(err); throw std::runtime_error(msg.str()); } else { std::cout << "glewInit() successfull: " << glewGetString(GLEW_VERSION) << std::endl; std::cout << "OpenGL " << glGetString(GL_VERSION) << " detected" << std::endl; std::cout << "OpenGL 3.2: " << GL_VERSION_3_2 << std::endl; std::cout << "GL_VERSION_3_0: " << GL_VERSION_3_0 << std::endl; glViewport(0, 0, m_impl->m_window->w, m_impl->m_window->h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); Display::aspect_size = aspect; glOrtho(0.0, Display::get_width(), Display::get_height(), 0.0, 1000.0, -1000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (0) // disabled for the moment, as it seems to do more harm then good { // Magic pixel center constant, without that textures drawn in // pixel coordinates might end up blurry glTranslated(0.375f, 0.375f, 0.0); } if (anti_aliasing) glEnable(GL_MULTISAMPLE); assert_gl("setup projection"); OpenGLState::init(); } } }
int main(int argc, char** argv) { std::vector<Pathname> files; bool crop = false; CommandLine argp; argp.add_usage("[OPTIONS]... LEVELFILE OUTPUTFILE"); argp.add_option('h', "help", "", "Displays this help"); argp.add_option('b', "background", "RRGGBBAA", "Set background color"); argp.add_option('c', "crop", "", "crop output to the actual objects rendered, not levelsize "); argp.parse_args(argc, argv); while (argp.next()) { switch (argp.get_key()) { case 'h': argp.print_help(); exit(EXIT_SUCCESS); break; case 'c': crop = true; break; case 'b': // FIXME: not implemented break; case CommandLine::REST_ARG: files.push_back(Pathname(argp.get_argument(), Pathname::SYSTEM_PATH)); break; } } if (files.size() != 2) { argp.print_help(); exit(EXIT_SUCCESS); } else { g_path_manager.set_path("data/"); Resource::init(); // render all the objects WorldObjRenderer renderer; Size size; if (System::get_file_extension(files[0].get_raw_path()) == "prefab") { PrefabFile prefab = PrefabFile::from_path(files[0]); renderer.process(prefab.get_objects()); crop = true; } else { PingusLevel plf(files[0]); renderer.process(plf.get_objects()); size = plf.get_size(); } Surface out_surface; if (crop) { Rect rect = renderer.get_clip_rect(); out_surface = Surface(rect.get_width(), rect.get_height()); // FIXME: alpha doesn't work, as the PNG saver can't handle that out_surface.fill(Color(255, 255, 255, 255)); renderer.blit(out_surface, -rect.left, -rect.top); // create a .sprite file to handle the offset std::string outfile = System::cut_file_extension(files[1].get_sys_path()) + ".sprite"; Vector2i offset(rect.left, rect.top); std::ostringstream out; SExprFileWriter writer(out); writer.begin_section("pingus-sprite"); writer.write_string("image", System::cut_file_extension(System::basename(files[0].get_raw_path())) + ".png"); writer.write_vector2i("offset", offset); writer.end_section(); out << std::endl; log_info("writing: %1%", outfile); System::write_file(outfile, out.str()); } else { out_surface = Surface(size.width, size.height); // FIXME: alpha doesn't work, as the PNG saver can't handle that out_surface.fill(Color(255, 255, 255, 255)); renderer.blit(out_surface); } Screenshot::save(out_surface.get_surface(), files[1].get_sys_path()); Resource::deinit(); } return 0; }