DLL——SDL_PingGe

这篇随笔专门做SDL的DLL开发。

下面这个版本暂且称为Beta版本吧。

/*
    typedef void (*FUNCTION)(void);
    HMODULE HDll;
    HDll = LoadLibrary("SDL_PingGe.dll");
    if(HDll == NULL)
    {
        printf("Load library failed!\n");
        FreeLibrary(HDll);
        return 0;
    }
    FUNCTION fun = FUNCTION(GetProcAddress(HDll,MAKEINTRESOURCE(1)));
*/
#ifndef __SDL_PINGGE_H__
#define __SDL_PINGGE_H__

//To use this exported function of dll, include this header in your project.
#include <windows.h>

//The SDL header
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"
#include "SDL/SDL_mixer.h"
#include "SDL/SDL_net.h"

#include <string>
#include <sstream>
#include <queue>
#include <cmath>

#ifdef BUILD_DLL
    #define DLL_EXPORT __declspec(dllexport)
#else
    #define DLL_EXPORT __declspec(dllimport)
#endif

#ifdef __cplusplus
extern "C"
{
#endif

namespace PingGe
{
    /*
    Load the picture and optimize it!
    If you want to set the colorkey,make the falg on true!
    Return the surface!
    */
    DLL_EXPORT SDL_Surface*
        Load_Image(std::string filename, Uint8 R = 0x00, Uint8 G = 0x00, Uint8 B = 0x00, bool flag = false);

    /*
    Set the color key
    */
    DLL_EXPORT void
        Color_Key(SDL_Surface* surface, Uint8 R, Uint8 G, Uint8 B);

    /*
    Return true if lock success!
    */
    DLL_EXPORT bool
        Lock(SDL_Surface* surface);

    /*
    Ulock the surface, if the surface is Locked!
    */
    DLL_EXPORT void
        ULock(SDL_Surface* surface);

    /*
    Apply the source_surface on the destination_surface!
    Return true if success!
    */
    DLL_EXPORT bool
        Apply_Surface(SDL_Surface* destination, Sint32 x, Sint32 y, SDL_Surface* source, SDL_Rect* clip = NULL);

    /*
    Return the pixel value at (x, y)!
    NOTE: The surface must be locked before calling this!
    */
    DLL_EXPORT Uint32
        SDL_GetPixel(SDL_Surface* surface, Sint32 x, Sint32 y);

    /*
    Set the pixel at (x, y) to the given value!
    NOTE: The surface must be locked before calling this!
    */
    DLL_EXPORT void
        SDL_PutPixel(SDL_Surface* surface, Sint32 x, Sint32 y, Uint32 pixel);

    /*
    Seedfill the surface if the pixel isn't Fillcolor and Boundarycolor!
    NOTE: The surface must be locked before calling this!
    */
    DLL_EXPORT void
        Seed_Fill(SDL_Surface *surface, Sint32 x, Sint32 y, Uint32 Fill_Color, Uint32 Boundary_Color);

    /*
    Draw a line from (x1,y1) to (x2,y2)!
    NOTE: The surface must be locked before calling this!
    */
    DLL_EXPORT void
        Draw_Line(SDL_Surface* surface, Sint32 x1, Sint32 y1, Sint32 x2, Sint32 y2, Uint32 pixel);

    /*
    Draw a circle which the C is (xc,yc), R is radius!
    NOTE: The surface must be locked before calling this!
    */
    DLL_EXPORT void
        Draw_Circle(SDL_Surface* surface, Sint32 xc, Sint32 yc, Sint32 radius, Uint32 pixel);

    /*
    Draw a rect!
    NOTE: The surface must be locked before calling this!
    */
    DLL_EXPORT void
        Draw_Rect(SDL_Surface* surface, Sint32 x1, Sint32 y1, Sint32 x2, Sint32 y2, Uint32 pixel);

    /*
    Draw a Fillrect with pixel!
    NOTE: The surface must be locked before calling this!
    */
    DLL_EXPORT void
        Draw_FillRect(SDL_Surface* surface, Sint32 x1, Sint32 y1, Sint32 x2, Sint32 y2, Uint32 pixel);

    /*
    Fill color with color_fill in the boundary!
    NOTE: The surface must be locked before calling this!
    */
    DLL_EXPORT void
        Color_Fill(SDL_Surface *surface, Sint32 x, Sint32 y, Uint32 fill_color, Uint32 boundary_color);

    /*
    Zoom the surface as W:width and H:height!
    If you don't use the old surface, better to free it!
    NOTE: The surface must be locked before calling this!
    */
    DLL_EXPORT SDL_Surface*
        SDL_ScaleSurface(SDL_Surface *surface, Sint32 width, Sint32 height);


    //The timer
    class DLL_EXPORT Timer
    {
        public:
            //Initializes variables
            Timer(void);

            //The various clock actions
            void Start(void);
            void Stop(void);
            void Pause(void);
            void Unpause(void);

            //Gets the timer's time
            int Get_Ticks(void);

            //Checks the status of the timer
            bool Is_Started(void);
            bool Is_Paused(void);
        private:
            //The clock time when the timer started
            int startTicks;

            //The ticks stored when the timer was paused
            int pausedTicks;

            //The timer status
            bool paused;
            bool started;
    };


    //The logo shower
    class DLL_EXPORT Logo
    {
        public:
            //Initializes variables
            Logo(SDL_Surface* _Logo, SDL_Surface* _Destination, Sint32 _Center_x, Sint32 _Center_y);

            //Reduce the logo 'Time' times, Fps
            void Act1(Sint32 Time, Sint32 _Fps);

            //Fly in from left
            void Act2(Sint32 _Fps);

            //Up to down show
            void Act3(Sint32 _Fps);

        private:
            SDL_Surface *logo, *destination;

            //The center-coordinate of the logo in the destination surface
            Sint32 Center_x, Center_y;
    };


    //Hide the old_cursor and show the new_cursor
    class DLL_EXPORT Cursor
    {
        public:
            //Load the screen and the cursor_surface
            Cursor(SDL_Surface *_background, SDL_Surface *_cursor, Sint32 _click_x = 0, Sint32 _click_y = 0);

            void Get_Background(void);
            void Cursor_Blit(void);
            void Blit_Background(void);
            void Update_Background(void);

            //You only need to use this function
            void Show_Cursor(Sint32 _x, Sint32 _y);

        private:
            SDL_Surface *cursor;
            SDL_Surface *cursor_s;
            SDL_Surface *background;
            Sint32 x, y;
            Sint32 click_x, click_y;
            SDL_Rect old_rect;
    };


    //The button
    class DLL_EXPORT Button
    {
        public:
            //Initialize the variables
            Button(SDL_Surface *surface, Sint32 x, Sint32 y, Sint32 w, Sint32 h);

            //Set the button nature
            void Set_Button_Pic     (SDL_Surface* surface);
            void Set_MOUSEOVER_Clip (Sint32 x, Sint32 y, Sint32 w, Sint32 h);
            void Set_MOUSEOUT_Clip  (Sint32 x, Sint32 y, Sint32 w, Sint32 h);
            void Set_MOUSEDOWN_Clip (Sint32 x, Sint32 y, Sint32 w, Sint32 h);
            void Set_MOUSEUP_Clip   (Sint32 x, Sint32 y, Sint32 w, Sint32 h);

            /*
            Handles events and set the button's sprite region
            Return Button::CLIP_MOUSEOVER, if cursor is over the button
            etc..
            */
            Sint32 Handle_Events(SDL_Event event);

            //Shows the button on the screen
            void Show(void);

        private:
            //The attributes of the button
            SDL_Rect box;

            //The part of the button sprite sheet that will be shown
            SDL_Rect* clip;

            //The button surface
            SDL_Surface* button;

            //The background surface
            SDL_Surface* background;

            //The clip cut a surface in four pieces
            SDL_Rect clips[4];

        public:
            //The button states in the sprite sheet
            Sint32  CLIP_MOUSEOVER,
                    CLIP_MOUSEOUT,
                    CLIP_MOUSEDOWN,
                    CLIP_MOUSEUP;
    };
}

#ifdef __cplusplus
}
#endif

//#undef VS_DLL

#endif // __SDL_PINGGE_H__
View Code
#include "SDL_PingGe.h"

using namespace std;

namespace PingGe
{

DLL_EXPORT SDL_Surface*
    Load_Image(std::string filename, Uint8 R, Uint8 G, Uint8 B, bool flag)
    {
        //The image that's loaded
        SDL_Surface* loadedImage = NULL;

        //The optimized image that will be used
        SDL_Surface* optimizedImage = NULL;

        //Load the image
        loadedImage = IMG_Load(filename.c_str());

        //If the image loaded
        if(loadedImage != NULL)
        {
            //Create an optimized image
            optimizedImage = SDL_DisplayFormatAlpha(loadedImage);

            //Free the old image
            SDL_FreeSurface(loadedImage);

            //If the image was optimized just fine
            if(optimizedImage != NULL && flag == true)
            {
                //Map the color key
                Uint32 colorkey = SDL_MapRGB(optimizedImage->format, R, G, B);

                //Set all pixels of color R, G, B to be transparent
                SDL_SetColorKey(optimizedImage, SDL_RLEACCEL | SDL_SRCCOLORKEY, colorkey);
            }
        }

        //Return the optimized image
        return optimizedImage;
    }

DLL_EXPORT void
    Color_Key(SDL_Surface* surface, Uint8 R, Uint8 G, Uint8 B)
    {
        //Map the color key
        Uint32 colorkey = SDL_MapRGB(surface->format, R, G, B);

        //Set all pixels of color R, G, B to be transparent
        SDL_SetColorKey(surface, SDL_RLEACCEL | SDL_SRCCOLORKEY, colorkey);
    }

DLL_EXPORT bool
    Lock(SDL_Surface* surface)
    {
        if(SDL_MUSTLOCK(surface))
        {
            if(SDL_LockSurface(surface)<0)
            {
                return false;
            }
        }
        return true;
    }

DLL_EXPORT void
    ULock(SDL_Surface* surface)
    {
        if(SDL_MUSTLOCK(surface))
        {
            SDL_UnlockSurface(surface);
        }
    }

DLL_EXPORT bool
    Apply_Surface(SDL_Surface* destination, Sint32 x, Sint32 y, SDL_Surface* source, SDL_Rect* clip)
    {
        //Holds offsets
        SDL_Rect offset;

        //Get offsets
        offset.x = x;
        offset.y = y;

        //Blit
        if(SDL_BlitSurface(source, clip, destination, &offset) == -1)
        {
            return false;
        }
        return true;
    }

DLL_EXPORT Uint32
    SDL_GetPixel(SDL_Surface* surface, Sint32 x, Sint32 y)
    {
        Sint32 bpp = surface->format->BytesPerPixel;

        /* Here p is the address to the pixel we want to retrieve */
        Uint8 *p=(Uint8*)surface->pixels + y*surface->pitch + x*bpp;//?

        switch(bpp)
        {
            case 1:
            {
                return *p;
            }
            case 2:
            {
                return *(Uint16*)p;
            }
            case 3:
            {
                if(SDL_BYTEORDER==SDL_BIG_ENDIAN)
                {
                    return p[0]<<16|p[1]<<8|p[2];
                }
                else
                {
                    return p[0]|p[1]<<8|p[2]<<16;
                }
            }
            case 4:
            {
                return *(Uint32*)p;
            }
            default:
            {
                return 0;   /* shouldn't happen, but avoids warnings */
            }
        }
    }

DLL_EXPORT void
    SDL_PutPixel(SDL_Surface* surface, Sint32 x, Sint32 y, Uint32 pixel)
    {
        Sint32 bpp = surface->format->BytesPerPixel;
        /* Here p is the address to the pixel we want to set */
        Uint8 *p = (Uint8*)surface->pixels + y * surface->pitch + x * bpp;

        switch(bpp)
        {
            case 1:
            {
                *p = pixel;
            }
            break;
            case 2:
            {
                *(Uint16*)p = pixel;
            }
            break;
            case 3:
            {
                if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
                {
                    p[0] = (pixel>>16)  & 0xff;
                    p[1] = (pixel>>8)   & 0xff;
                    p[2] = (pixel)      & 0xff;
                }
                else
                {
                    p[0] = (pixel)      & 0xff;
                    p[1] = (pixel>>8)   & 0xff;
                    p[2] = (pixel>>16)  & 0xff;
                }
            }
            break;
            case 4:
            {
                *(Uint32*)p = pixel;
            }
            break;
        }
    }

DLL_EXPORT void
    Seed_Fill(SDL_Surface *surface, Sint32 x, Sint32 y, Uint32 Fill_Color, Uint32 Boundary_Color)
    {
        Uint32 color = PingGe::SDL_GetPixel(surface, x, y);

        if((color != Boundary_Color) && (color != Fill_Color))
        {
            PingGe::SDL_PutPixel(surface, x, y, Fill_Color);
        }
    }

DLL_EXPORT void
    Draw_Line(SDL_Surface* surface, Sint32 x1, Sint32 y1, Sint32 x2, Sint32 y2, Uint32 pixel)
    {
        double delta_x, delta_y, x, y;
        Sint32 dx, dy, steps, k;
        dx = x2 - x1;
        dy = y2 - y1;

        if(abs(dx) > abs(dy))
        {
            steps = abs(dx);
        }
        else
        {
            steps = abs(dy);
        }

        delta_x = (double)dx / (double)steps;
        delta_y = (double)dy / (double)steps;

        x = x1;
        y = y1;

        PingGe::SDL_PutPixel(surface, x, y, pixel);
        for(k = 0; k < steps; k++)
        {
            x += delta_x;
            y += delta_y;
            PingGe::SDL_PutPixel(surface, x, y, pixel);
        }
    }

DLL_EXPORT void
    Draw_Circle(SDL_Surface* surface, Sint32 xc, Sint32 yc, Sint32 radius, Uint32 pixel)
    {
        Sint32 x, y, p;
        x = 0;
        y = radius;
        p = 3 - 2 * radius;

        while(x < y)
        {
            PingGe::SDL_PutPixel(surface, xc + x, yc + y, pixel);
            PingGe::SDL_PutPixel(surface, xc - x, yc + y, pixel);
            PingGe::SDL_PutPixel(surface, xc + x, yc - y, pixel);
            PingGe::SDL_PutPixel(surface, xc - x, yc - y, pixel);
            PingGe::SDL_PutPixel(surface, xc + y, yc + x, pixel);
            PingGe::SDL_PutPixel(surface, xc - y, yc + x, pixel);
            PingGe::SDL_PutPixel(surface, xc + y, yc - x, pixel);
            PingGe::SDL_PutPixel(surface, xc - y, yc - x, pixel);
            if(p < 0)
            {
                p = p + 4 * x + 6;
            }
            else
            {
                p = p + 4 * (x - y) + 10;
                y -= 1;
            }
            x += 1;
        }
        if(x == y)
        {
            PingGe::SDL_PutPixel(surface, xc + x, yc + y, pixel);
            PingGe::SDL_PutPixel(surface, xc - x, yc + y, pixel);
            PingGe::SDL_PutPixel(surface, xc + x, yc - y, pixel);
            PingGe::SDL_PutPixel(surface, xc - x, yc - y, pixel);
            PingGe::SDL_PutPixel(surface, xc + y, yc + x, pixel);
            PingGe::SDL_PutPixel(surface, xc - y, yc + x, pixel);
            PingGe::SDL_PutPixel(surface, xc + y, yc - x, pixel);
            PingGe::SDL_PutPixel(surface, xc - y, yc - x, pixel);
        }
    }

DLL_EXPORT void
    Draw_Rect(SDL_Surface* surface, Sint32 x1, Sint32 y1, Sint32 x2, Sint32 y2, Uint32 pixel)
    {
        PingGe::Draw_Line(surface, x1, y1, x2, y1, pixel);
        PingGe::Draw_Line(surface, x2, y1, x2, y2, pixel);
        PingGe::Draw_Line(surface, x2, y2, x1, y2, pixel);
        PingGe::Draw_Line(surface, x1, y2, x1, y1, pixel);
    }

DLL_EXPORT void
    Draw_FillRect(SDL_Surface* surface, Sint32 x1, Sint32 y1, Sint32 x2, Sint32 y2, Uint32 pixel)
    {
        for(int x = x1; x <= x2; x++)
        {
            PingGe::Draw_Line(surface, x, y1, x, y2, pixel);
        }
    }

struct node
{
    int x, y;
}temp, next;
DLL_EXPORT void
    Color_Fill(SDL_Surface *surface, Sint32 x, Sint32 y, Uint32 fill_color, Uint32 boundary_color)
    {
        const int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
        temp.x=x;temp.y=y;

        queue<node>que;
        que.push(temp);
        while(!que.empty())
        {
            temp = que.front();
            que.pop();

            Uint32 color = PingGe::SDL_GetPixel(surface, temp.x, temp.y);
            if((color == fill_color) || (color == boundary_color))
            {
                continue;
            }
            PingGe::SDL_PutPixel(surface, temp.x, temp.y, fill_color);
            for(int i = 0; i < 4; i++)
            {
                next.x = temp.x + dir[i][0];
                next.y = temp.y + dir[i][1];
                que.push(next);
            }
        }
    }

DLL_EXPORT SDL_Surface*
    SDL_ScaleSurface(SDL_Surface *surface, Sint32 width, Sint32 height)
    {
        SDL_Surface *_ret = SDL_CreateRGBSurface(surface->flags, width, height, surface->format->BitsPerPixel,
        surface->format->Rmask, surface->format->Gmask, surface->format->Bmask, surface->format->Amask);

         double _stretch_factor_x = (static_cast <double> (width)  / static_cast <double> (surface->w)),
                _stretch_factor_y = (static_cast <double> (height) / static_cast <double> (surface->h));

        PingGe::Lock(_ret);
        for(Sint32 y = 0; y < surface->h; y++)                      //Run across all Y pixels.
        {
            for(Sint32 x = 0; x < surface->w; x++)                  //Run across all X pixels.
            {
                for(Sint32 o_y = 0; o_y < _stretch_factor_y; ++o_y) //Draw _stretch_factor_y pixels for each Y pixel.
                    {
                        for(Sint32 o_x = 0; o_x < _stretch_factor_x; ++o_x) //Draw _stretch_factor_x pixels for each X pixel.
                            {
                                PingGe::SDL_PutPixel(_ret, static_cast<Sint32>(_stretch_factor_x * x) + o_x,
                                static_cast<Sint32>(_stretch_factor_y * y) + o_y, PingGe::SDL_GetPixel(surface, x, y));
                            }
                    }
            }
        }
        PingGe::ULock(_ret);

        return _ret;
    }




/*****************Timer*****************/
Timer::Timer(void)
{
    //Initialize the variables
    startTicks = 0;
    pausedTicks = 0;
    paused = false;
    started = false;
}
void Timer::Start(void)
{
    //Start the timer
    started = true;

    //Unpause the timer
    paused = false;

    //Get the current clock time
    startTicks = SDL_GetTicks();
}
void Timer::Stop(void)
{
    //Stop the timer
    started = false;

    //Unpause the timer
    paused = false;
}
void Timer::Pause(void)
{
    //If the timer is running and isn't already paused
    if( ( started == true ) && ( paused == false ) )
    {
        //Pause the timer
        paused = true;

        //Calculate the paused ticks
        pausedTicks = SDL_GetTicks() - startTicks;
    }
}
void Timer::Unpause(void)
{
    //If the timer is paused
    if( paused == true )
    {
        //Unpause the timer
        paused = false;

        //Reset the starting ticks
        startTicks = SDL_GetTicks() - pausedTicks;

        //Reset the paused ticks
        pausedTicks = 0;
    }
}
int  Timer::Get_Ticks(void)
{
    //If the timer is running
    if( started == true )
    {
        //If the timer is paused
        if( paused == true )
        {
            //Return the number of ticks when the timer was paused
            return pausedTicks;
        }
        else
        {
            //Return the current time minus the start time
            return SDL_GetTicks() - startTicks;
        }
    }

    //If the timer isn't running
    return 0;
}
bool Timer::Is_Started(void)
{
    return started;
}
bool Timer::Is_Paused(void)
{
    return paused;
}
/*****************Timer*****************/


/***************Logo_Show***************/
Logo::Logo(SDL_Surface* _Logo, SDL_Surface* _Destination, Sint32 _Center_x, Sint32 _Center_y)
{
    logo = _Logo;
    destination = _Destination;
    Center_x = _Center_x;
    Center_y = _Center_y;
}
void Logo::Act1(Sint32 Time, Sint32 _Fps)
{
    Timer Fps;
    for(Sint32 i = 0; i <= Time; i++)
    {
        Fps.Start();
        SDL_Surface* img = PingGe::SDL_ScaleSurface(logo, (logo->w) - 2*i, (logo->h) - i);

        SDL_Rect Dest_rect;
        Dest_rect.x = (Center_x - (img->w)/2);
        Dest_rect.y = (Center_y - (img->h)/2);

        SDL_FillRect(destination, 0, SDL_MapRGB(destination->format, 0xff, 0xff, 0xff));
        SDL_BlitSurface(img, 0, destination, &Dest_rect);
        SDL_FreeSurface(img);
        SDL_Flip(destination);

        if(Fps.Get_Ticks() < 1000 / _Fps)
        {
            SDL_Delay((1000 / _Fps) - Fps.Get_Ticks());
        }
    }
}
void Logo::Act2(Sint32 _Fps)
{
    Timer Fps;

    SDL_Rect Dest_rect, clip[3], Update_rect[3];

    Dest_rect.x = (destination->w - logo->w) / 2;
    Dest_rect.y = (destination->h - logo->h) / 2;

    clip[0].x = 10;     Update_rect[2].x = 0;
    clip[0].y = 20;     Update_rect[2].y = Dest_rect.y;
    clip[0].w = 110;    Update_rect[2].w = Dest_rect.x + 335;
    clip[0].h = 145;    Update_rect[2].h = logo->h;

    clip[1].x = 120;    Update_rect[1].x = 0;
    clip[1].y = 20;     Update_rect[1].y = Dest_rect.y;
    clip[1].w = 125;    Update_rect[1].w = Dest_rect.x + 245;
    clip[1].h = 145;    Update_rect[1].h = logo->h;

    clip[2].x = 245;    Update_rect[0].x = 0;
    clip[2].y = 20;     Update_rect[0].y = Dest_rect.y;
    clip[2].w = 90;     Update_rect[0].w = Dest_rect.x + 120;
    clip[2].h = 145;    Update_rect[0].h = logo->h;

    SDL_FillRect(destination, 0, SDL_MapRGB(destination->format, 0xff, 0xff, 0xff));
    SDL_Flip(destination);
    for(int i = -clip[2].w; i <= Dest_rect.x + clip[2].x; i++)
    {
        Fps.Start();

        SDL_FillRect(destination, 0, SDL_MapRGB(destination->format, 0xff, 0xff, 0xff));
        PingGe::Apply_Surface(destination, i, Dest_rect.y + clip[0].y, logo, &clip[2]);
        SDL_UpdateRects(destination, 1, &Update_rect[2]);

        if(Fps.Get_Ticks() < 1000 / _Fps)
        {
            SDL_Delay((1000 / _Fps) - Fps.Get_Ticks());
        }
    }
    for(int i = -clip[1].w; i <= Dest_rect.x + clip[1].x; i++)
    {
        Fps.Start();

        SDL_FillRect(destination, 0, SDL_MapRGB(destination->format, 0xff, 0xff, 0xff));
        PingGe::Apply_Surface(destination, i, Dest_rect.y + clip[0].y, logo, &clip[1]);
        SDL_UpdateRects(destination, 1, &Update_rect[1]);

        if(Fps.Get_Ticks() < 1000 / _Fps)
        {
            SDL_Delay((1000 / _Fps) - Fps.Get_Ticks());
        }
    }
    for(int i = -clip[0].w; i <= Dest_rect.x + clip[0].x; i++)
    {
        Fps.Start();

        SDL_FillRect(destination, 0, SDL_MapRGB(destination->format, 0xff, 0xff, 0xff));
        PingGe::Apply_Surface(destination, i, Dest_rect.y + clip[0].y, logo, &clip[0]);
        SDL_UpdateRects(destination, 1, &Update_rect[0]);

        if(Fps.Get_Ticks() < 1000 / _Fps)
        {
            SDL_Delay((1000 / _Fps) - Fps.Get_Ticks());
        }
    }
    Act3(_Fps);
}
void Logo::Act3(Sint32 _Fps)
{
    Timer Fps;

    SDL_Rect Dest_rect, up_down_clip, right_left_clip, small_rect_clip;

    Dest_rect.x = (destination->w - logo->w) / 2;
    Dest_rect.y = (destination->h - logo->h) / 2;

    up_down_clip.x = Dest_rect.x;
    up_down_clip.y = Dest_rect.y;
    up_down_clip.w = logo->w;
    up_down_clip.h = 1;

    right_left_clip.x = Dest_rect.x + 425;
    right_left_clip.y = Dest_rect.y + 165;
    right_left_clip.w = 1;
    right_left_clip.h = logo->h;

    small_rect_clip.x = Dest_rect.x + 425;
    small_rect_clip.y = Dest_rect.y + 165;
    small_rect_clip.w = 15;
    small_rect_clip.h = 15;

    PingGe::Apply_Surface(destination, Dest_rect.x, Dest_rect.y, logo);
    for(int i = up_down_clip.y; i <= right_left_clip.y; i++)
    {
        Fps.Start();

        up_down_clip.y++;
        SDL_UpdateRects(destination, 1, &up_down_clip);

        if(Fps.Get_Ticks() < 1000 / _Fps)
        {
            SDL_Delay((1000 / _Fps) - Fps.Get_Ticks());
        }
    }

    SDL_UpdateRects(destination, 1, &small_rect_clip);

    for(int i = right_left_clip.x; i >= up_down_clip.x; i--)
    {
        Fps.Start();

        right_left_clip.x--;
        SDL_UpdateRects(destination, 1, &right_left_clip);

        if(Fps.Get_Ticks() < 1000 / _Fps)
        {
            SDL_Delay((1000 / _Fps) - Fps.Get_Ticks());
        }
    }
}
/***************Logo_Show***************/


/****************Cursor****************/
Cursor::Cursor(SDL_Surface *_background, SDL_Surface *_cursor, Sint32 _click_x, Sint32 _click_y)
{
    background = _background;
    cursor = _cursor;
    cursor_s = SDL_CreateRGBSurface(_cursor->flags, _cursor->w, _cursor->h, _cursor->format->BitsPerPixel,
               _cursor->format->Rmask, _cursor->format->Gmask, _cursor->format->Bmask, _cursor->format->Amask);

    click_x = _click_x;
    click_y = _click_y;

    //Close the old cursor
    SDL_ShowCursor(0);

    old_rect.x = 0;
    old_rect.y = 0;
    old_rect.w = 0;
    old_rect.h = 0;
}
void Cursor::Get_Background(void)
{
    /* Blits a surface sized chunk of background to that surface */
    SDL_Rect src;
    SDL_Rect dst;

    src.x = x;
    src.y = y;
    src.w = cursor_s->w;
    src.h = cursor_s->h;

    dst.x = 0;
    dst.y = 0;
    dst.w = cursor_s->w;
    dst.h = cursor_s->h;
    SDL_BlitSurface(background, &src, cursor_s, &dst);
}
void Cursor::Cursor_Blit(void)
{
    SDL_Rect dest;

    dest.x = x;
    dest.y = y;
    dest.w = cursor->w;
    dest.h = cursor->h;
    SDL_BlitSurface(cursor, NULL, background, &dest);
}
void Cursor::Blit_Background(void)
{
    SDL_Rect dest;

    dest.x = x;
    dest.y = y;
    dest.w = cursor_s->w;
    dest.h = cursor_s->h;
    SDL_BlitSurface(cursor_s, NULL, background, &dest);
    old_rect = dest;
}
void Cursor::Update_Background(void)
{
    SDL_Rect clip[2];
    clip[0].x = x-50;
    clip[0].y = y-50;
    clip[0].w = cursor->w+100;
    clip[0].h = cursor->h+100;
    clip[1] = old_rect;

    clip[1].x = clip[1].x-50;
    clip[1].y = clip[1].y-50;
    clip[1].w = clip[1].w+100;
    clip[1].h = clip[1].h+100;
    SDL_UpdateRects(background, 2, clip);
}
void Cursor::Show_Cursor(Sint32 _x, Sint32 _y)
{
    x = _x - click_x;
    y = _y - click_y;
    Get_Background();
    Cursor_Blit();
    Update_Background();
    Blit_Background();
}
/****************Cursor****************/


/****************Button****************/
Button::Button(SDL_Surface *surface, Sint32 x, Sint32 y, Sint32 w, Sint32 h)
{
    //Init
    CLIP_MOUSEOVER    = 0;
    CLIP_MOUSEOUT     = 1;
    CLIP_MOUSEDOWN    = 2;
    CLIP_MOUSEUP      = 3;

    //Set the background surface
    background = surface;

    //Set the button's attributes
    box.x = x;
    box.y = y;
    box.w = w;
    box.h = h;

    //Set the default sprite
    clip = &clips[ CLIP_MOUSEOUT ];
}
void Button::Set_Button_Pic(SDL_Surface* surface)
{
    button = surface;
}
void Button::Set_MOUSEOVER_Clip (Sint32 x, Sint32 y, Sint32 w, Sint32 h)
{
    clips[ CLIP_MOUSEOVER ].x = x;
    clips[ CLIP_MOUSEOVER ].y = y;
    clips[ CLIP_MOUSEOVER ].w = w;
    clips[ CLIP_MOUSEOVER ].h = h;
}
void Button::Set_MOUSEOUT_Clip  (Sint32 x, Sint32 y, Sint32 w, Sint32 h)
{
    clips[ CLIP_MOUSEOUT ].x = x;
    clips[ CLIP_MOUSEOUT ].y = y;
    clips[ CLIP_MOUSEOUT ].w = w;
    clips[ CLIP_MOUSEOUT ].h = h;
}
void Button::Set_MOUSEDOWN_Clip (Sint32 x, Sint32 y, Sint32 w, Sint32 h)
{
    clips[ CLIP_MOUSEDOWN ].x = x;
    clips[ CLIP_MOUSEDOWN ].y = y;
    clips[ CLIP_MOUSEDOWN ].w = w;
    clips[ CLIP_MOUSEDOWN ].h = h;
}
void Button::Set_MOUSEUP_Clip   (Sint32 x, Sint32 y, Sint32 w, Sint32 h)
{
    clips[ CLIP_MOUSEUP ].x = x;
    clips[ CLIP_MOUSEUP ].y = y;
    clips[ CLIP_MOUSEUP ].w = w;
    clips[ CLIP_MOUSEUP ].h = h;
}
Sint32 Button::Handle_Events(SDL_Event event)
{
    //The mouse offsets
    Sint32 x = 0, y = 0;

    //If the mouse moved
    if( event.type == SDL_MOUSEMOTION )
    {
        //Get the mouse offsets
        x = event.motion.x;
        y = event.motion.y;

        //If the mouse is over the button
        if( ( x > box.x ) && ( x < box.x + box.w ) && ( y > box.y ) && ( y < box.y + box.h ) )
        {
            //Set the button sprite
            clip = &clips[ CLIP_MOUSEOVER ];

            return CLIP_MOUSEOVER;
        }
        //If not
        else
        {
            //Set the button sprite
            clip = &clips[ CLIP_MOUSEOUT ];

            return CLIP_MOUSEOUT;
        }
    }
    //If a mouse button was pressed
    if( event.type == SDL_MOUSEBUTTONDOWN )
    {
        //If the left mouse button was pressed
        if( event.button.button == SDL_BUTTON_LEFT )
        {
            //Get the mouse offsets
            x = event.button.x;
            y = event.button.y;

            //If the mouse is over the button
            if( ( x > box.x ) && ( x < box.x + box.w ) && ( y > box.y ) && ( y < box.y + box.h ) )
            {
                //Set the button sprite
                clip = &clips[ CLIP_MOUSEDOWN ];

                return CLIP_MOUSEDOWN;
            }
        }
    }
    //If a mouse button was released
    if( event.type == SDL_MOUSEBUTTONUP )
    {
        //If the left mouse button was released
        if( event.button.button == SDL_BUTTON_LEFT )
        {
            //Get the mouse offsets
            x = event.button.x;
            y = event.button.y;

            //If the mouse is over the button
            if( ( x > box.x ) && ( x < box.x + box.w ) && ( y > box.y ) && ( y < box.y + box.h ) )
            {
                //Set the button sprite
                clip = &clips[ CLIP_MOUSEUP ];

                return CLIP_MOUSEUP;
            }
        }
    }
    return -1;
}
void Button::Show(void)
{
    //Show the button
    PingGe::Apply_Surface(background, box.x, box.y, button, clip);
}
/****************Button****************/
}
View Code

 

posted @ 2013-10-06 22:18  瓶哥  Views(291)  Comments(0Edit  收藏  举报