/** * @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; }
/** * @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 ); }
/** * @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; }