Example #1
0
void WadImageCache::delete_storage_for_name(std::string& name) const
{
	FileSpecifier file;
	file.SetToImageCacheDir();
	file.AddPart(name);
	file.Delete();
}
Example #2
0
void WadImageCache::save_cache()
{
	if (!m_cache_dirty)
		return;
	
	InfoTree pt;
	
	for (cache_iter_t it = m_used.begin(); it != m_used.end(); ++it)
	{
		std::string name = it->second.first;
		WadImageDescriptor desc = boost::tuples::get<0>(it->first);
		
		pt.put(name + ".path", desc.file.GetPath());
		pt.put(name + ".checksum", desc.checksum);
		pt.put(name + ".index", desc.index);
		pt.put(name + ".tag", desc.tag);
		pt.put(name + ".width", boost::tuples::get<1>(it->first));
		pt.put(name + ".height", boost::tuples::get<2>(it->first));
		pt.put(name + ".filesize", it->second.second);
	}
	
	FileSpecifier info;
	info.SetToImageCacheDir();
	info.AddPart("Cache.ini");
	try {
		pt.save_ini(info);
		m_cache_dirty = false;
	} catch (InfoTree::ini_error e) {
		logError("Could not save image cache to %s (%s)", info.GetPath(), e.what());
		return;
	}
}
Example #3
0
SDL_Surface* QuickSaveImageCache::get(std::string image_name) {
    std::map<std::string, cache_iter_t>::iterator it = m_images.find(image_name);
    if (it != m_images.end()) {
        // found it: move to front of list
        m_used.splice(m_used.begin(), m_used, it->second);
        return it->second->second;
    }
    
    // didn't find: load image
    FileSpecifier f;
    f.SetToQuickSavesDir();
	f.AddPart(image_name + ".sgaA");
	
	WadImageDescriptor desc;
	desc.file = f;
	desc.checksum = 0;
	desc.index = SAVE_GAME_METADATA_INDEX;
	desc.tag = SAVE_IMG_TAG;
	
	SDL_Surface *img = WadImageCache::instance()->get_image(desc, PREVIEW_WIDTH, PREVIEW_HEIGHT);
	if (img) {
        m_used.push_front(cache_pair_t(image_name, img));
        m_images[image_name] = m_used.begin();
        
        // enforce maximum cache size
        if (m_used.size() > k_max_items) {
            cache_iter_t lru = m_used.end();
            --lru;
            m_images.erase(lru->first);
            SDL_FreeSurface(lru->second);
            m_used.pop_back();
        }
    }
    return img;
}
// This tries to find a filename (in the same directory as inBaseName) based on 'inBaseName' but that is not yet used.
// The current logic tries inBaseName first, then 'inBaseName 2', then 'inBaseName 3', and so on.
// The resulting name will have no more than inMaxNameLength actual characters.
// Returns whether it was successful (the current logic either returns true or loops forever; fortunately, the
// probability of looping forever is really, REALLY tiny; the directory would have to contain every possible variant).
static bool
make_nonconflicting_filename_variant(/*const*/ FileSpecifier& inBaseName, FileSpecifier& outNonconflictingName, size_t inMaxNameLength) {
	FileSpecifier theNameToTry;
	DirectorySpecifier theDirectory;
	inBaseName.ToDirectory(theDirectory);
        
        char	theBaseNameString[256]; // XXX I don't like this, but the SDL code already imposes this maxlen throughout.

        inBaseName.GetName(theBaseNameString);
        size_t	theBaseNameLength = strlen(theBaseNameString);

        char	theNameToTryString[256];
        char	theVariantSuffix[32]; // way more than enough

        unsigned int	theVariant = 0;
        size_t	theSuffixLength;
        size_t	theBaseNameLengthToUse;
        
        bool	theVariantIsAcceptable = false;
        
        while(!theVariantIsAcceptable) {
                theVariant++;
                if(theVariant == 1) {
                        theVariantSuffix[0] = '\0';
                        theSuffixLength = 0;
                }
                else {
                        theSuffixLength = sprintf(theVariantSuffix, " %d", theVariant);
                }
                
                assert(theSuffixLength <= inMaxNameLength);
                
                if(theSuffixLength + theBaseNameLength > inMaxNameLength)
                        theBaseNameLengthToUse = inMaxNameLength - theSuffixLength;
                else
                        theBaseNameLengthToUse = theBaseNameLength;
                
                sprintf(theNameToTryString, "%.*s%s", (int) theBaseNameLengthToUse, theBaseNameString, theVariantSuffix);
        
                theNameToTry.FromDirectory(theDirectory);
#if defined(mac) || defined(SDL_RFORK_HACK)
                // Note: SetName() currently ignores the 'type' argument, so I feel
                // little compulsion to try to figure it out.
                theNameToTry.SetName(theNameToTryString,NONE);
#else
                theNameToTry.AddPart(theNameToTryString);
#endif
                if(!theNameToTry.Exists())
                        theVariantIsAcceptable = true;
        }
        
        if(theVariantIsAcceptable) {
                outNonconflictingName = theNameToTry;
        }
        
        return theVariantIsAcceptable;
}
// Analogous to 'save_game()', but does not present any dialog to the user, and reports the results
// using screen_printf().  If inOverwriteRecent is set, it will save over the most recently saved
// or restored game (if possible).  If inOverwriteRecent is not set, or if there is no recent game
// to save over, it will pick a new, nonconflicting filename and save to it.
// Returns whether save was successful.
bool
save_game_full_auto(bool inOverwriteRecent) {
        bool createNewFile = !inOverwriteRecent;

        FileSpecifier theRecentSavedGame;
        get_current_saved_game_name(theRecentSavedGame);

        char theSavedGameName[256]; // XXX

        // If we're supposed to overwrite, change our minds if we seem to have no 'existing file'.
        if(!createNewFile) {
                theRecentSavedGame.GetName(theSavedGameName);
                if(strcmp(theSavedGameName, TS_GetCString(strFILENAMES, filenameDEFAULT_SAVE_GAME)) == 0)
                        createNewFile = true;
        }
        
        // Make up a filename (currently based on level name)
        if(createNewFile) {
                if(strncpy_filename_friendly(theSavedGameName, static_world->level_name, kMaxFilenameChars) <= 0)
                        strcpy(theSavedGameName, "Automatic Save");

                DirectorySpecifier theDirectory;
                theRecentSavedGame.ToDirectory(theDirectory);
                theRecentSavedGame.FromDirectory(theDirectory);
#if defined(mac) || defined(SDL_RFORK_HACK)
                // Note: SetName() currently ignores the 'type' argument, so I feel
                // little compulsion to try to figure it out.
                theRecentSavedGame.SetName(theSavedGameName,NONE);
#else
                theRecentSavedGame.AddPart(theSavedGameName);
#endif
        }
                
        
        FileSpecifier theOutputFile;
        
        if(createNewFile)
                make_nonconflicting_filename_variant(theRecentSavedGame, theOutputFile, kMaxFilenameChars);
        else
                theOutputFile = theRecentSavedGame;
        
        bool successfulSave = save_game_file(theOutputFile);

        theOutputFile.GetName(theSavedGameName);
        
        if(successfulSave) {
                screen_printf("%s saved game '%s'", createNewFile ? "Created new" : "Replaced existing", theSavedGameName);
                // play a sound?
        }
        else {
                screen_printf("Unable to save game as '%s'", theSavedGameName);
                // play a sound?
        }

        return successfulSave;
}
Example #6
0
SDL_Surface *WadImageCache::image_from_name(std::string& name) const
{
	FileSpecifier file;
	file.SetToImageCacheDir();
	file.AddPart(name);
	
	OpenedFile of;
	if (!file.Open(of))
		return NULL;
	
#ifdef HAVE_SDL_IMAGE
	SDL_Surface *img = IMG_Load_RW(of.GetRWops(), 0);
#else
	SDL_Surface *img = SDL_LoadBMP_RW(of.GetRWops(), 0);
#endif
	return img;
}
Example #7
0
// Exchange two files
bool FileSpecifier::Exchange(FileSpecifier &other)
{
	// Create temporary name (this is cheap, we should make sure that the
	// name is not already in use...)
	FileSpecifier tmp;
	ToDirectory(tmp);
	tmp.AddPart("exchange_tmp_file");

	err = 0;
	if (rename(GetPath(), tmp.GetPath()) < 0)
		err = errno;
	else
		rename(other.GetPath(), GetPath());
	if (rename(tmp.GetPath(), other.GetPath()) < 0)
		err = errno;
	return err == 0;
}
Example #8
0
void WadImageCache::initialize_cache()
{
	FileSpecifier info;
	info.SetToImageCacheDir();
	info.AddPart("Cache.ini");
	if (!info.Exists())
		return;
	
	InfoTree pt;
	try {
		pt = InfoTree::load_ini(info);
	} catch (InfoTree::ini_error e) {
		logError("Could not read image cache from %s (%s)", info.GetPath(), e.what());
	}
	
	for (InfoTree::iterator it = pt.begin(); it != pt.end(); ++it)
	{
		std::string name = it->first;
		InfoTree ptc = it->second;
		
		WadImageDescriptor desc;
		
		std::string path;
		ptc.read("path", path);
		desc.file = FileSpecifier(path);
		
		ptc.read("checksum", desc.checksum);
		ptc.read("index", desc.index);
		ptc.read("tag", desc.tag);
		
		int width = 0;
		ptc.read("width", width);
		int height = 0;
		ptc.read("height", height);
		size_t filesize = 0;
		ptc.read("filesize", filesize);
		
		cache_key_t key = cache_key_t(desc, width, height);
		cache_value_t val = cache_value_t(name, filesize);
		m_used.push_front(cache_pair_t(key, val));
		m_cacheinfo[key] = m_used.begin();
		m_cachesize += filesize;
	}
}
Example #9
0
	FileSpecifier GetPath() {
		FileSpecifier dir = m_list_w->get_file();
		std::string base;
		std::string part;
		dir.SplitPath(base, part);

		std::string filename = GetFilename();
		if (part == filename)
		{
			dir = base;
		}

		if (m_extension && !boost::algorithm::ends_with(filename, m_extension))
		{
			filename += m_extension;
		}
		dir.AddPart(filename);
		return dir;
	}
Example #10
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 "";
}