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

 

你可能感兴趣的:(ping)