* Add Airship (regular above-ground theme) and Battle (castle/boss theme) music court...
[supertux.git] / src / video / texture_manager.cpp
index d9ff2a7..70b0e95 100644 (file)
@@ -95,36 +95,84 @@ TextureManager::remove_texture(GL::Texture* texture)
 Texture*
 TextureManager::create_image_texture(const std::string& filename)
 {
-  SDL_Surface* image = IMG_Load_RW(get_physfs_SDLRWops(filename), 1);
-  if(image == 0) {
-    std::ostringstream msg;
-    msg << "Couldn't load image '" << filename << "' :" << SDL_GetError();
-    throw std::runtime_error(msg.str());
-  }
-
-  Texture* result = 0;
   try {
-    result = new_texture(image);
-    result->set_filename(filename);
-  } catch(...) {
-    delete result;
+
+    SDL_Surface* image = IMG_Load_RW(get_physfs_SDLRWops(filename), 1);
+    if(image == 0) {
+      std::ostringstream msg;
+      msg << "Couldn't load image '" << filename << "' :" << SDL_GetError();
+      throw std::runtime_error(msg.str());
+    }
+
+    Texture* result = 0;
+    try {
+      result = new_texture(image);
+      result->set_filename(filename);
+    } catch(...) {
+      delete result;
+      SDL_FreeSurface(image);
+      throw;
+    }
+
     SDL_FreeSurface(image);
-    throw;
-  }
+    return result;
+
+  } catch (const std::runtime_error& err) {
+    const std::string dummy_texture_fname = "images/engine/missing.png";
+    if (filename == dummy_texture_fname) throw err;
+
+    // on error, try loading placeholder file
+    try {
+
+      Texture* tex = create_image_texture(dummy_texture_fname);
+      log_warning << "Couldn't load texture '" << filename << "' (now using dummy texture): " << err.what() << std::endl;
+      return tex;
+
+    } catch (...) {
 
-  SDL_FreeSurface(image);
-  return result;
+      // on error (when loading placeholder), try using empty surface
+      try {
+
+       SDL_Surface* image = SDL_CreateRGBSurface(0, 1024, 1024, 8, 0, 0, 0, 0);
+       if(image == 0) {
+         throw err;
+       }
+
+       Texture* result = 0;
+       try {
+         result = new_texture(image);
+         result->set_filename("-dummy-texture-.png");
+       } catch(...) {
+         delete result;
+         SDL_FreeSurface(image);
+         throw err;
+       }
+
+       SDL_FreeSurface(image);
+        log_warning << "Couldn't load texture '" << filename << "' (now using empty one): " << err.what() << std::endl;
+       return result;
+
+      // on error (when trying to use empty surface), give up
+      } catch (const std::runtime_error& err) {
+       throw err;
+      }
+    }
+  }
 }
 
 #ifdef HAVE_OPENGL
 void
 TextureManager::save_textures()
 {
+#ifdef GL_PACK_ROW_LENGTH
+  /* all this stuff is not support by OpenGL ES */
   glPixelStorei(GL_PACK_ROW_LENGTH, 0);
   glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
   glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
   glPixelStorei(GL_PACK_SKIP_ROWS, 0);
   glPixelStorei(GL_PACK_SKIP_IMAGES, 0);
+#endif
+
   glPixelStorei(GL_PACK_ALIGNMENT, 1);
   for(Textures::iterator i = textures.begin(); i != textures.end(); ++i) {
     save_texture(*i);
@@ -141,6 +189,9 @@ TextureManager::save_texture(GL::Texture* texture)
   SavedTexture saved_texture;
   saved_texture.texture = texture;
   glBindTexture(GL_TEXTURE_2D, texture->get_handle());
+
+  //this doesn't work with OpenGL ES (but we don't need it on the GP2X anyway)
+#ifndef GL_VERSION_ES_CM_1_0
   glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH,
                            &saved_texture.width);
   glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT,
@@ -161,6 +212,7 @@ TextureManager::save_texture(GL::Texture* texture)
 
   glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 saved_texture.pixels);
+#endif
 
   saved_textures.push_back(saved_texture);
 
@@ -173,11 +225,14 @@ TextureManager::save_texture(GL::Texture* texture)
 void
 TextureManager::reload_textures()
 {
+#ifdef GL_UNPACK_ROW_LENGTH
+  /* OpenGL ES doesn't support these */
   glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
   glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
   glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
   glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
   glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
+#endif
   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
   for(std::vector<SavedTexture>::iterator i = saved_textures.begin();