SDL_PingGe 1.2
加入了像素填充函数,必须要在一个指定颜色的边界范围内,边界必须没有缺口。
加入了鼠标类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* 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); /* 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); 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; SDL_Rect old_rect; }; } #ifdef __cplusplus } #endif //#undef VS_DLL #endif // __SDL_PINGGE_H__
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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 0, G 0xFF, B 0xFF to be transparent SDL_SetColorKey(optimizedImage, SDL_RLEACCEL | SDL_SRCCOLORKEY, colorkey); } } //Return the optimized image return optimizedImage; } 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) { 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); //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; y = _y; Get_Background(); Cursor_Blit(); Update_Background(); Blit_Background(); } /****************Cursor****************/ }
——现在的努力是为了小时候吹过的牛B!!