예제 #1
0
/**
 * @brief Prepares the surface to be loaded as a texture.
 *
 *    @param surface to load that is freed in the process.
 *    @return New surface that is prepared for texture loading.
 */
SDL_Surface* gl_prepareSurface( SDL_Surface* surface )
{
   SDL_Surface* temp;
   int potw, poth;
   SDL_Rect rtemp;
#if ! SDL_VERSION_ATLEAST(1,3,0)
   Uint32 saved_flags;
#endif /* ! SDL_VERSION_ATLEAST(1,3,0) */

   /* Make size power of two. */
   potw = gl_pot(surface->w);
   poth = gl_pot(surface->h);
   if (gl_needPOT() && ((potw != surface->w) || (poth != surface->h))) {

      /* we must blit with an SDL_Rect */
      rtemp.x = rtemp.y = 0;
      rtemp.w = surface->w;
      rtemp.h = surface->h;

      /* saves alpha */
#if SDL_VERSION_ATLEAST(1,3,0)
      SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE);

      /* create the temp POT surface */
      temp = SDL_CreateRGBSurface( 0, potw, poth,
            surface->format->BytesPerPixel*8, RGBAMASK );
#else /* SDL_VERSION_ATLEAST(1,3,0) */
      saved_flags = surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
      if ((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
         SDL_SetAlpha( surface, 0, SDL_ALPHA_OPAQUE );
         SDL_SetColorKey( surface, 0, surface->format->colorkey );
      }

      /* create the temp POT surface */
      temp = SDL_CreateRGBSurface( SDL_SRCCOLORKEY,
            potw, poth, surface->format->BytesPerPixel*8, RGBAMASK );
#endif /* SDL_VERSION_ATLEAST(1,3,0) */

      if (temp == NULL) {
         WARN("Unable to create POT surface: %s", SDL_GetError());
         return 0;
      }
      if (SDL_FillRect( temp, NULL,
               SDL_MapRGBA(surface->format,0,0,0,SDL_ALPHA_TRANSPARENT))) {
         WARN("Unable to fill rect: %s", SDL_GetError());
         return 0;
      }

      /* change the surface to the new blitted one */
      SDL_BlitSurface( surface, &rtemp, temp, &rtemp);
      SDL_FreeSurface( surface );
      surface = temp;

#if ! SDL_VERSION_ATLEAST(1,3,0)
      /* set saved alpha */
      if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA )
         SDL_SetAlpha( surface, 0, 0 );
#endif /* ! SDL_VERSION_ATLEAST(1,3,0) */
   }

   return surface;
}
예제 #2
0
/**
 * @brief Small wrapper that handles recursivity limits.
 *
 *    @param iter Iteration of recursivity.
 *    @return 0 on success.
 */
static int nebu_init_recursive( int iter )
{
   int i;
   char nebu_file[PATH_MAX];
   SDL_Surface* nebu_sur;
   int ret;

   /* Avoid too much recursivity. */
   if (iter > 3) {
      WARN("Unable to generate nebula after 3 attempts, something has really gone wrong!");
      return -1;
   }

   /* Special code to regenerate the nebula */
   if ((nebu_w == -9) && (nebu_h == -9))
      nebu_generate();

   /* Set expected sizes */
   nebu_w  = SCREEN_W;
   nebu_h  = SCREEN_H;
   if (gl_needPOT()) {
      nebu_pw = gl_pot(nebu_w);
      nebu_ph = gl_pot(nebu_h);
   }
   else {
      nebu_pw = nebu_w;
      nebu_ph = nebu_h;
   }

   /* Load each, checking for compatibility and padding */
   glGenTextures( NEBULA_Z, nebu_textures );
   for (i=0; i<NEBULA_Z; i++) {
      nsnprintf( nebu_file, PATH_MAX, NEBULA_PATH_BG, nebu_w, nebu_h, i );

      /* Check compatibility. */
      if (nebu_checkCompat( nebu_file ))
         goto no_nebula;

      /* Try to load. */
      nebu_sur = loadNebula( nebu_file );
      if (nebu_sur == NULL)
         goto no_nebula;
      if ((nebu_sur->w != nebu_w) || (nebu_sur->h != nebu_h))
         WARN("Nebula raw size doesn't match expected! (%dx%d instead of %dx%d)",
               nebu_sur->w, nebu_sur->h, nebu_w, nebu_h );

      /* Load the texture */
      ret = nebu_loadTexture( nebu_sur, nebu_pw, nebu_ph, nebu_textures[i] );
      if (ret)
         goto no_nebula;
   }

   /* Generate puffs after the recursivity stuff. */
   nebu_generatePuffs();

   /* Display loaded nebulas. */
   DEBUG("Loaded %d Nebula Layers", NEBULA_Z);

   nebu_vbo_init();
   nebu_loaded = 1;

   return 0;
no_nebula:
   LOG("No nebula found, generating (this may take a while).");

   /* So we generate and reload */
   ret = nebu_generate();
   if (ret != 0) /* An error has happened - break recursivity*/
      return ret;

   return nebu_init_recursive( iter+1 );
}
예제 #3
0
파일: npng.c 프로젝트: Crockadavin/naev
/**
 * @brief Reads a PNG image into a surface.
 *
 *    @param npng PNG image to load.
 *    @return Surface with data from the PNG image.
 */
SDL_Surface *npng_readSurface( npng_t *npng, int pad_pot, int vflip )
{
   png_bytep *row_pointers;
   png_uint_32 width, height, row, rheight;
   SDL_Surface *surface;
   int channels;
   Uint32 Rmask, Gmask, Bmask, Amask;
   int bit_depth, color_type, interlace_type;

   /* Read information. */
   channels = png_get_channels( npng->png_ptr, npng->info_ptr );
   png_get_IHDR( npng->png_ptr, npng->info_ptr, &width, &height,
         &bit_depth, &color_type, &interlace_type, NULL, NULL );

   /* Pad POT if needed. */
   rheight = height;
   if (pad_pot) {
      width    = gl_pot( width );
      height   = gl_pot( height );
   }

   /* Allocate the SDL surface to hold the image */
   if (SDL_BYTEORDER == SDL_LIL_ENDIAN) {
      Rmask = 0x000000FF;
      Gmask = 0x0000FF00;
      Bmask = 0x00FF0000;
      Amask = (channels == 4) ? 0xFF000000 : 0;
   }
   else {
      int s = (channels == 4) ? 0 : 8;
      Rmask = 0xFF000000 >> s;
      Gmask = 0x00FF0000 >> s;
      Bmask = 0x0000FF00 >> s;
      Amask = 0x000000FF >> s;
   }
   surface = SDL_CreateRGBSurface( SDL_SWSURFACE, width, height,
         bit_depth*channels, Rmask, Gmask, Bmask, Amask );
   if (surface == NULL) {
      ERR( "Out of Memory" );
      return NULL;
   }
   /*if (bit_depth*channels < npng_pitch( npng )) DEBUG(" %d / %d ", bit_depth*channels, npng_pitch( npng ) );*/

   /* Create the array of pointers to image data */
   row_pointers = malloc( sizeof(png_bytep) * rheight );
   if (row_pointers == NULL) {
      ERR( "Out of Memory" );
      return NULL;
   }
   for (row=0; row<rheight; row++) { /* We only need to go to real height, not full height. */
      row_pointers[ vflip ? rheight-row-1 : row ] = (png_bytep)
         (Uint8 *) surface->pixels + row * surface->pitch;
   }

   /* Load the data. */
   npng_readInto( npng, row_pointers );

   /* Free rows. */
   free( row_pointers );
   return surface;
}