truelight@7348: /* $Id$ */ truelight@7348: truelight@7348: /** @file blitter.hpp */ truelight@7348: truelight@7348: #ifndef BLITTER_HPP truelight@7348: #define BLITTER_HPP truelight@7348: truelight@7348: #include "../spriteloader/spriteloader.hpp" truelight@7348: #include "../spritecache.h" truelight@7348: #include truelight@7348: #include truelight@7348: truelight@7348: enum BlitterMode { truelight@7348: BM_NORMAL, truelight@7348: BM_COLOUR_REMAP, truelight@7348: BM_TRANSPARENT, truelight@7348: }; truelight@7348: truelight@7348: /** truelight@7348: * How all blitters should look like. Extend this class to make your own. truelight@7348: */ truelight@7348: class Blitter { truelight@7348: public: truelight@7348: struct BlitterParams { truelight@7348: const void *sprite; ///< Pointer to the sprite how ever the encoder stored it truelight@7348: const byte *remap; ///< XXX -- Temporary storage for remap array truelight@7348: truelight@7348: int skip_left, skip_top; ///< How much pixels of the source to skip on the left and top (based on zoom of dst) truelight@7348: int width, height; ///< The width and height in pixels that needs to be drawn to dst truelight@7348: int sprite_width; ///< Real width of the sprite truelight@7348: int sprite_height; ///< Real height of the sprite truelight@7348: int left, top; ///< The offset in the 'dst' in pixels to start drawing truelight@7348: truelight@7348: void *dst; ///< Destination buffer truelight@7348: int pitch; ///< The pitch of the destination buffer truelight@7348: }; truelight@7348: truelight@7348: /** truelight@7348: * Get the screen depth this blitter works for. truelight@7348: * This is either: 8, 16, 24 or 32. truelight@7348: */ truelight@7348: virtual uint8 GetScreenDepth() = 0; truelight@7348: truelight@7348: /** truelight@7348: * Draw an image to the screen, given an amount of params defined above. truelight@7348: */ truelight@7348: virtual void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) = 0; truelight@7348: truelight@7348: /** truelight@7348: * Convert a sprite from the loader to our own format. truelight@7348: */ truelight@7348: virtual Sprite *Encode(SpriteLoader::Sprite *sprite) = 0; truelight@7348: truelight@7348: virtual ~Blitter() { } truelight@7348: }; truelight@7348: truelight@7348: /** truelight@7348: * The base factory, keeping track of all blitters. truelight@7348: */ truelight@7348: class BlitterFactoryBase { truelight@7348: private: truelight@7348: char *name; truelight@7348: typedef std::map Blitters; truelight@7348: truelight@7348: static Blitters &GetBlitters() truelight@7348: { truelight@7348: static Blitters &s_blitters = *new Blitters(); truelight@7348: return s_blitters; truelight@7348: } truelight@7348: truelight@7348: static Blitter **GetActiveBlitter() truelight@7348: { truelight@7348: static Blitter *s_blitter = NULL; truelight@7348: return &s_blitter; truelight@7348: } truelight@7348: truelight@7348: protected: truelight@7348: /** truelight@7348: * Register a blitter internally, based on his name. truelight@7348: * @param name the name of the blitter. truelight@7348: * @note an assert() will be trigger if 2 blitters with the same name try to register. truelight@7348: */ truelight@7348: void RegisterBlitter(const char *name) truelight@7348: { truelight@7348: /* Don't register nameless Blitters */ truelight@7348: if (name == NULL) return; truelight@7348: truelight@7348: this->name = strdup(name); truelight@7348: std::pair P = GetBlitters().insert(Blitters::value_type(name, this)); truelight@7348: assert(P.second); truelight@7348: } truelight@7348: truelight@7348: public: truelight@7348: BlitterFactoryBase() : truelight@7348: name(NULL) truelight@7348: {} truelight@7348: truelight@7348: virtual ~BlitterFactoryBase() { if (this->name != NULL) GetBlitters().erase(this->name); free(this->name); } truelight@7348: truelight@7348: /** truelight@7348: * Find the requested blitter and return his class. truelight@7348: * @param name the blitter to select. truelight@7348: * @post Sets the blitter so GetCurrentBlitter() returns it too. truelight@7348: */ truelight@7348: static Blitter *SelectBlitter(const char *name) truelight@7348: { truelight@7348: if (GetBlitters().size() == 0) return NULL; truelight@7348: truelight@7348: Blitters::iterator it = GetBlitters().begin(); truelight@7348: for (; it != GetBlitters().end(); it++) { truelight@7348: BlitterFactoryBase *b = (*it).second; truelight@7348: if (strcasecmp(name, b->name) == 0) { truelight@7348: Blitter *newb = b->CreateInstance(); truelight@7348: *GetActiveBlitter() = newb; truelight@7348: return newb; truelight@7348: } truelight@7348: } truelight@7348: return NULL; truelight@7348: } truelight@7348: truelight@7348: /** truelight@7348: * Get the current active blitter (always set by calling SelectBlitter). truelight@7348: */ truelight@7348: static Blitter *GetCurrentBlitter() truelight@7348: { truelight@7348: return *GetActiveBlitter(); truelight@7348: } truelight@7348: truelight@7348: truelight@7348: static char *GetBlittersInfo(char *p, const char *last) truelight@7348: { truelight@7348: p += snprintf(p, last - p, "List of blitters:\n"); truelight@7348: Blitters::iterator it = GetBlitters().begin(); truelight@7348: for (; it != GetBlitters().end(); it++) { truelight@7348: BlitterFactoryBase *b = (*it).second; truelight@7348: p += snprintf(p, last - p, "%18s: %s\n", b->name, b->GetDescription()); truelight@7348: } truelight@7348: p += snprintf(p, last - p, "\n"); truelight@7348: truelight@7348: return p; truelight@7348: } truelight@7348: truelight@7348: /** truelight@7348: * Get a nice description of the blitter-class. truelight@7348: */ truelight@7348: virtual const char *GetDescription() = 0; truelight@7348: truelight@7348: /** truelight@7348: * Create an instance of this Blitter-class. truelight@7348: */ truelight@7348: virtual Blitter *CreateInstance() = 0; truelight@7348: }; truelight@7348: truelight@7348: /** truelight@7348: * A template factory, so ->GetName() works correctly. This because else some compiler will complain. truelight@7348: */ truelight@7348: template truelight@7348: class BlitterFactory: public BlitterFactoryBase { truelight@7348: public: truelight@7348: BlitterFactory() { this->RegisterBlitter(((T *)this)->GetName()); } truelight@7348: truelight@7348: /** truelight@7348: * Get the long, human readable, name for the Blitter-class. truelight@7348: */ truelight@7348: const char *GetName(); truelight@7348: }; truelight@7348: truelight@7348: #endif /* BLITTER_HPP */