zoukankan      html  css  js  c++  java
  • DLL——SDL_PingGe

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

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

    /*
        typedef void (*FUNCTION)(void);
        HMODULE HDll;
        HDll = LoadLibrary("SDL_PingGe.dll");
        if(HDll == NULL)
        {
            printf("Load library failed!
    ");
            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
  • 相关阅读:
    ajax实现异步请求的过程
    GET和POST的区别,何时使用POST?
    函数有几种调用方式?
    substring、slice、substr的区别
    Spring 调用 Stored Procedure 并获取返回值
    Oracle 中, 使用 Instr 函数 替换 OR
    Oracle Materialized View refresh
    Oracle中Union 和 Union All
    toString() 和 强制类型转换 (String)
    2013年这一年
  • 原文地址:https://www.cnblogs.com/pingge/p/3354736.html
Copyright © 2011-2022 走看看