#include #include #if ! SDL_VERSION_ATLEAST(2,0,0) #error "This code is only for SDL 2+. No backward compatibility with previous SDL versions, sorry." #endif #include "utils.h" #define MPL_WINDOW_TITLE __FILE__ #define MPL_WINDOW_WIDTH 640 #define MPL_WINDOW_HEIGHT 480 #define MPL_COLOR_KEY 0x00ff00ff /* Uint32 SDL_MapRGB(const SDL_PixelFormat* format, Uint8 r, Uint8 g, Uint8 b) */ void my_SDL_init_or_die(char title[], SDL_Rect win_pos, Uint32 init_flags, Uint32 win_flags, Uint32 rend_flags, SDL_Window **win, SDL_Renderer **rend, SDL_RendererInfo *rend_info, SDL_Rect *viewport); SDL_Texture * my_sdl_load_texture(SDL_Renderer *rend, char *bmpfilepath, SDL_Rect *size); int main(int argc, char *argv[]) { SDL_Window *sdl_win; SDL_Renderer *sdl_rend; SDL_Texture *t1; SDL_RendererInfo sdl_rend_info; SDL_Rect sdl_viewport,t1_size,t1_src,t1_dst; SDL_Event sdl_ev; int mainloop_end=0; SDL_Rect win_pos = { .x=SDL_WINDOWPOS_UNDEFINED, .y=SDL_WINDOWPOS_UNDEFINED, .w=MPL_WINDOW_WIDTH, .h=MPL_WINDOW_HEIGHT }; Uint32 init_flags = SDL_INIT_TIMER|SDL_INIT_AUDIO|SDL_INIT_VIDEO;//|SDL_INIT_EVENTS; Uint32 win_flags = SDL_WINDOW_SHOWN; //|SDL_WINDOW_OPENGL; //Uint32 rend_flags = SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC; Uint32 rend_flags = SDL_RENDERER_ACCELERATED; my_SDL_init_or_die(MPL_WINDOW_TITLE, win_pos, init_flags, win_flags, rend_flags, &sdl_win, &sdl_rend, &sdl_rend_info, &sdl_viewport); t1=my_sdl_load_texture(sdl_rend, "src/sandbox/lemm_15.gif", &t1_size); t1_src=t1_size; t1_src.h=26; t1_dst=t1_src; t1_dst.x=10; t1_dst.y=10; /* Main render loop */ while (!mainloop_end) { /* Check for events */ while (SDL_PollEvent(&sdl_ev)) { if (sdl_ev.type == SDL_QUIT || sdl_ev.type == SDL_KEYDOWN) { mainloop_end = 1; } } /* Draw a gray background */ SDL_SetRenderDrawColor(sdl_rend, 0xA0, 0xA0, 0xA0, 0xFF); SDL_RenderClear(sdl_rend); /* Blit the sprite onto the screen */ SDL_RenderCopy(sdl_rend, t1, &t1_src, &t1_dst); /* Update the screen */ SDL_RenderPresent(sdl_rend); /* Change source rectangle to go to the next animation step */ t1_src.y = (t1_src.y + t1_src.h) % t1_size.h; /* Change dest rectangle to move the sprite if the animation cycle restart */ if (t1_src.y == 0) { t1_dst.x++; t1_dst.y++; } SDL_Delay(50); } SDL_DestroyTexture(t1); SDL_DestroyRenderer(sdl_rend); SDL_DestroyWindow(sdl_win); SDL_Quit(); return 0; } void my_SDL_init_or_die(char title[], SDL_Rect win_pos, Uint32 init_flags, Uint32 win_flags, Uint32 rend_flags, SDL_Window **win, SDL_Renderer **rend, SDL_RendererInfo *rend_info, SDL_Rect *viewport) { int res, i; Uint32 tf; res=SDL_Init(init_flags); MPL_CHECK( res==0, // Expression to evaluate {exit(1);} , // Code to execute if expression is not true SDL_LOG_PRIORITY_CRITICAL, // SDL_LogPriority (_CRITICAL, _ERROR, _WARN, _INFO, DEBUG, _VERBOSE) "SDL_Init failed (%i)",res // var args list starting with a fmt string like in printf() ); *win=SDL_CreateWindow(title,win_pos.x,win_pos.y,win_pos.w,win_pos.h,win_flags); MPL_CHECK( *win, // Just put the pointer if you want to check if it's not NULL {SDL_Quit(); exit(2);}, SDL_LOG_PRIORITY_CRITICAL, "SDL_CreateWindow failed" ); SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION,SDL_LOG_PRIORITY_INFO, "SDL_GetWindowPixelFormat() returns 0x%x", SDL_GetWindowPixelFormat(*win) ); *rend=SDL_CreateRenderer(*win,-1, rend_flags); MPL_CHECK( *rend, {SDL_DestroyWindow(*win);SDL_Quit(); exit(3);}, SDL_LOG_PRIORITY_CRITICAL, "SDL_CreateRenderer(...,SDL_RENDERER_ACCELERATED) failed" ); res=SDL_GetRendererInfo(*rend, rend_info); MPL_CHECK( res==0, {SDL_DestroyRenderer(*rend);SDL_DestroyWindow(*win);SDL_Quit(); exit(4);}, SDL_LOG_PRIORITY_CRITICAL, "res=SDL_GetRendererInfo() failed" ); tf=1; for(i=0;i<16 && tf!=0;i++) { tf=rend_info->texture_formats[i]; SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION,SDL_LOG_PRIORITY_INFO, "rend_info->texture_formats[%i] == 0x%x", i, tf ); } SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION,SDL_LOG_PRIORITY_INFO, "rend_info->flags==%i", rend_info->flags ); if ( (rend_info->flags & SDL_RENDERER_SOFTWARE) == SDL_RENDERER_SOFTWARE) { SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION,SDL_LOG_PRIORITY_INFO, "rend_info->flags contains SDL_RENDERER_SOFTWARE"); } if ( (rend_info->flags & SDL_RENDERER_ACCELERATED) == SDL_RENDERER_ACCELERATED) { SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION,SDL_LOG_PRIORITY_INFO, "rend_info->flags contains SDL_RENDERER_ACCELERATED"); } if ( (rend_info->flags & SDL_RENDERER_PRESENTVSYNC) == SDL_RENDERER_PRESENTVSYNC) { SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION,SDL_LOG_PRIORITY_INFO, "rend_info->flags contains SDL_RENDERER_PRESENTVSYNC"); } if ( (rend_info->flags & SDL_RENDERER_TARGETTEXTURE) == SDL_RENDERER_TARGETTEXTURE) { SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION,SDL_LOG_PRIORITY_INFO, "rend_info->flags contains SDL_RENDERER_TARGETTEXTURE"); } // Remarks : When the window is resized, the current viewport is automatically centered within the new window size. SDL_RenderGetViewport(*rend, viewport); } SDL_Texture * my_sdl_load_texture(SDL_Renderer *rend, char *giffilepath, SDL_Rect *size) { SDL_Surface *s; SDL_Texture *t; SDL_RWops *rwop; //int res; rwop = SDL_RWFromFile(giffilepath,"r"); s = IMG_LoadGIF_RW(rwop); SDL_RWclose(rwop); MPL_CHECK( s, {return NULL;}, SDL_LOG_PRIORITY_WARN, "my_sdl_load_texture(rend, \"%s\") failed",giffilepath ); t = SDL_CreateTextureFromSurface(rend, s); MPL_CHECK( t, {SDL_FreeSurface(s); return NULL;}, SDL_LOG_PRIORITY_WARN, "my_sdl_load_texture(rend, \"%s\") : can't convert surface to texture",giffilepath ); if (size != NULL) { size->x=0; size->y=0; size->w=s->w; size->h=s->h; } /* Surface no longer useful (everything was copied in the texture) */ SDL_FreeSurface(s); return t; }