2121static SDL_Surface* load_png (const char * path)
2222{
2323 int width, height, channels;
24- uint8_t * data = stbi_load (path, &width, &height, &channels, 4 );
24+ using png_data = std::unique_ptr<uint8_t , decltype (&stbi_image_free)>;
25+ png_data data (stbi_load (path, &width, &height, &channels, 4 ),
26+ stbi_image_free);
2527
26- if (!data || width % 512 != 0 || height % 448 != 0 || channels != 4 ) {
27- stbi_image_free (data );
28+ if (!data. get () || width % 512 != 0 || height % 448 != 0 || channels != 4 ) {
29+ SDL_LogError ( SDL_LOG_CATEGORY_VIDEO , " Invalid skin format: %s " , path );
2830 return nullptr ;
2931 }
3032
3133 SDL_Surface* tmp = SDL_CreateSurfaceFrom (
32- width, height, SDL_PIXELFORMAT_RGBA32 , data, width * 4 /* RGBA*/ );
34+ width, height, SDL_PIXELFORMAT_RGBA32 , data. get () , width * 4 /* RGBA*/ );
3335 if (!tmp) {
34- stbi_image_free (data);
36+ SDL_LogError (SDL_LOG_CATEGORY_VIDEO , " Error creating skin surface: %s" ,
37+ SDL_GetError ());
3538 return nullptr ;
3639 }
3740
@@ -42,7 +45,6 @@ static SDL_Surface* load_png(const char* path)
4245 }
4346
4447 SDL_DestroySurface (tmp);
45- stbi_image_free (data);
4648 return surface;
4749}
4850
@@ -52,25 +54,26 @@ SDL_Surface* Skin::initialize(const std::string& name)
5254
5355 if (!search (APP_DATADIR )) {
5456 // try portable variant
55- const char * app_dir = SDL_GetBasePath ();
56- if (app_dir) {
57- std::string path = app_dir;
58- path += " data" ;
59- search (path);
60- }
57+ std::filesystem::path path (SDL_GetBasePath ());
58+ path /= " data" ;
59+ search (path);
6160 }
6261
6362 // search for specified skin
64- for (size_t i = 0 ; i < available.size (); ++i) {
65- const std::string& path = available[i];
66- if (name == get_name (path)) {
63+ for (size_t i = 0 ; i < skins.size (); ++i) {
64+ if (name == skins[i].stem ().string ()) {
6765 image = load (i);
6866 break ;
6967 }
7068 }
71- // fallback: load first available
72- for (size_t i = 0 ; !image && i < available.size (); ++i) {
73- image = load (i);
69+ if (!image) {
70+ // fallback: load first available
71+ for (size_t i = 0 ; i < skins.size (); ++i) {
72+ image = load (i);
73+ if (image) {
74+ break ;
75+ }
76+ }
7477 }
7578
7679 return image;
@@ -80,11 +83,11 @@ SDL_Surface* Skin::prev()
8083{
8184 SDL_Surface* image = nullptr ;
8285
83- for (ssize_t i = current - 1 ; !image && i >= 0 ; --i) {
86+ for (ssize_t i = skin_index - 1 ; !image && i >= 0 ; --i) {
8487 image = load (i);
8588 }
86- for (ssize_t i = available .size () - 1 ;
87- !image && i > static_cast <ssize_t >(current ); --i) {
89+ for (ssize_t i = skins .size () - 1 ;
90+ !image && i > static_cast <ssize_t >(skin_index ); --i) {
8891 image = load (i);
8992 }
9093
@@ -95,10 +98,10 @@ SDL_Surface* Skin::next()
9598{
9699 SDL_Surface* image = nullptr ;
97100
98- for (size_t i = current + 1 ; !image && i < available .size (); ++i) {
101+ for (size_t i = skin_index + 1 ; !image && i < skins .size (); ++i) {
99102 image = load (i);
100103 }
101- for (size_t i = 0 ; !image && i < current ; ++i) {
104+ for (size_t i = 0 ; !image && i < skin_index ; ++i) {
102105 image = load (i);
103106 }
104107
@@ -107,30 +110,28 @@ SDL_Surface* Skin::next()
107110
108111SDL_Surface* Skin::load (size_t index)
109112{
110- const std::string & path = available [index];
111- SDL_Surface* image = load_png (path.c_str ());
113+ const std::filesystem::path & path = skins [index];
114+ SDL_Surface* image = load_png (path.string (). c_str ());
112115 if (image) {
113- name = get_name ( path);
114- current = index;
116+ skin_name = path. stem (). string ( );
117+ skin_index = index;
115118 }
116119 return image;
117120}
118121
119- bool Skin::search (const std::string& path )
122+ bool Skin::search (const std::filesystem::path& dir )
120123{
121124 int count;
122- char ** files = SDL_GlobDirectory (path .c_str (), " *.png" , 0 , &count);
125+ char ** files = SDL_GlobDirectory (dir. string () .c_str (), " *.png" , 0 , &count);
123126 for (int i = 0 ; i < count; ++i) {
124- const std::string skin_path = path + files[i];
125- available .push_back (skin_path );
127+ std::filesystem::path path = dir / files[i];
128+ skins .push_back (path );
126129 }
127130 SDL_free (files);
128131 return count > 0 ;
129132}
130133
131- std::string Skin::get_name ( const std::string& path ) const
134+ const std::string& Skin::name ( ) const
132135{
133- const size_t dir_end = path.find_last_of (" \\ /" ) + 1 ;
134- const size_t ext_start = path.rfind (' .' );
135- return path.substr (dir_end, ext_start - dir_end);
136+ return skin_name;
136137}
0 commit comments