Files @ r9583:b6e25a00b908
Branch filter:

Location: cpp/openttd-patchpack/source/src/blitter/factory.hpp - annotation

rubidium
(svn r13621) -Fix: building roadbits in the wrong direction on bridges or building roadbits from underneath the bridge to the bridgehead is impossible, so don't silently ignore that error when building over houses and industries is not ignored.
r6937:bea726150bf3
r6937:bea726150bf3
r9111:983de9c5a848
r9111:983de9c5a848
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r7568:fc1eeb32558c
r8214:9a3935f9ef4e
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r9582:cb7711765a81
r9582:cb7711765a81
r9582:cb7711765a81
r9582:cb7711765a81
r9582:cb7711765a81
r9582:cb7711765a81
r9582:cb7711765a81
r9582:cb7711765a81
r9582:cb7711765a81
r9582:cb7711765a81
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r9436:8c85322a3b2a
r9436:8c85322a3b2a
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r9294:d468ad712ebe
r9294:d468ad712ebe
r9294:d468ad712ebe
r9294:d468ad712ebe
r9294:d468ad712ebe
r9582:cb7711765a81
r9294:d468ad712ebe
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r7567:345990e41454
r7567:345990e41454
r9561:373f1b581232
r9561:373f1b581232
r9561:373f1b581232
r9561:373f1b581232
r9561:373f1b581232
r9561:373f1b581232
r9561:373f1b581232
r6937:bea726150bf3
r7567:345990e41454
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r7567:345990e41454
r6937:bea726150bf3
r7091:5e43bed16283
r6937:bea726150bf3
r7568:fc1eeb32558c
r7568:fc1eeb32558c
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r6937:bea726150bf3
r8275:5932486ddd21
r8275:5932486ddd21
r6937:bea726150bf3
/* $Id$ */

/** @file factory.hpp Factory to 'query' all available blitters. */

#ifndef BLITTER_FACTORY_HPP
#define BLITTER_FACTORY_HPP

#include "base.hpp"
#include "../debug.h"
#include "../string_func.h"
#include <map>

/**
 * The base factory, keeping track of all blitters.
 */
class BlitterFactoryBase {
private:
	const char *name;

	struct StringCompare {
		bool operator () (const char *a, const char *b) const
		{
			return strcmp(a, b) < 0;
		}
	};

	typedef std::map<const char *, BlitterFactoryBase *, StringCompare> Blitters;

	static Blitters &GetBlitters()
	{
		static Blitters &s_blitters = *new Blitters();
		return s_blitters;
	}

	static Blitter **GetActiveBlitter()
	{
		static Blitter *s_blitter = NULL;
		return &s_blitter;
	}

protected:
	/**
	 * Register a blitter internally, based on his name.
	 * @param name the name of the blitter.
	 * @note an assert() will be trigger if 2 blitters with the same name try to register.
	 */
	void RegisterBlitter(const char *name)
	{
		/* Don't register nameless Blitters */
		if (name == NULL) return;

		this->name = strdup(name);

		std::pair<Blitters::iterator, bool> P = GetBlitters().insert(Blitters::value_type(name, this));
		assert(P.second);
	}

public:
	BlitterFactoryBase() :
		name(NULL)
	{}

	virtual ~BlitterFactoryBase()
	{
		if (this->name == NULL) return;
		GetBlitters().erase(this->name);
		if (GetBlitters().empty()) delete &GetBlitters();
		free((void *)this->name);
	}

	/**
	 * Find the requested blitter and return his class.
	 * @param name the blitter to select.
	 * @post Sets the blitter so GetCurrentBlitter() returns it too.
	 */
	static Blitter *SelectBlitter(const char *name)
	{
		const char *default_blitter = "8bpp-optimized";

#if defined(__APPLE__)
		/* MacOS X 10.5 removed 8bpp fullscreen support.
		 * Because of this we will pick 32bpp by default */
		if (MacOSVersionIsAtLeast(10, 5, 0)) {
			default_blitter = "32bpp-anim";
		}
#endif /* defined(__APPLE__) */
		if (GetBlitters().size() == 0) return NULL;
		const char *bname = (StrEmpty(name)) ? default_blitter : name;

		Blitters::iterator it = GetBlitters().begin();
		for (; it != GetBlitters().end(); it++) {
			BlitterFactoryBase *b = (*it).second;
			if (strcasecmp(bname, b->name) == 0) {
				Blitter *newb = b->CreateInstance();
				delete *GetActiveBlitter();
				*GetActiveBlitter() = newb;

				DEBUG(driver, 1, "Successfully %s blitter '%s'",StrEmpty(name) ? "probed" : "loaded", bname);
				return newb;
			}
		}
		return NULL;
	}

	/**
	 * Get the current active blitter (always set by calling SelectBlitter).
	 */
	static Blitter *GetCurrentBlitter()
	{
		return *GetActiveBlitter();
	}


	static char *GetBlittersInfo(char *p, const char *last)
	{
		p += snprintf(p, last - p, "List of blitters:\n");
		Blitters::iterator it = GetBlitters().begin();
		for (; it != GetBlitters().end(); it++) {
			BlitterFactoryBase *b = (*it).second;
			p += snprintf(p, last - p, "%18s: %s\n", b->name, b->GetDescription());
		}
		p += snprintf(p, last - p, "\n");

		return p;
	}

	/**
	 * Get a nice description of the blitter-class.
	 */
	virtual const char *GetDescription() = 0;

	/**
	 * Create an instance of this Blitter-class.
	 */
	virtual Blitter *CreateInstance() = 0;
};

/**
 * A template factory, so ->GetName() works correctly. This because else some compiler will complain.
 */
template <class T>
class BlitterFactory: public BlitterFactoryBase {
public:
	BlitterFactory() { this->RegisterBlitter(((T *)this)->GetName()); }

	/**
	 * Get the long, human readable, name for the Blitter-class.
	 */
	const char *GetName();
};

extern char _ini_blitter[32];

#endif /* BLITTER_FACTORY_HPP */