/** * Loads the contents of a TFTD BDY image file into * the surface. BDY files are compressed with a custom * algorithm. * @param filename Filename of the BDY image. * @sa http://www.ufopaedia.org/index.php?title=Image_Formats#BDY */ void Surface::loadBdy(const std::string &filename) { // Load file and put pixels in surface std::ifstream imgFile (filename.c_str(), std::ios::in | std::ios::binary); if (!imgFile) { throw Exception(filename + " not found"); } // Lock the surface lock(); Uint8 dataByte; int pixelCnt; int x = 0, y = 0; int currentRow = 0; while (imgFile.read((char*)&dataByte, sizeof(dataByte))) { if (dataByte >= 129) { pixelCnt = 257 - (int)dataByte; imgFile.read((char*)&dataByte, sizeof(dataByte)); currentRow = y; for (int i = 0; i < pixelCnt; ++i) { if (currentRow == y) // avoid overscan into next row setPixelIterative(&x, &y, dataByte); } } else { pixelCnt = 1 + (int)dataByte; currentRow = y; for (int i = 0; i < pixelCnt; ++i) { imgFile.read((char*)&dataByte, sizeof(dataByte)); if (currentRow == y) // avoid overscan into next row setPixelIterative(&x, &y, dataByte); } } } // Unlock the surface unlock(); imgFile.close(); }
/** * Loads the contents of an X-Com SPK image file into * the surface. SPK files are compressed with a custom * algorithm since they're usually full-screen images. * @param filename Filename of the SPK image. * @sa http://www.ufopaedia.org/index.php?title=Image_Formats#SPK */ void Surface::loadSpk(const std::string &filename) { // Load file and put pixels in surface std::ifstream imgFile (filename.c_str(), std::ios::in | std::ios::binary); if (!imgFile) { throw Exception(filename + " not found"); } // Lock the surface lock(); Uint16 flag; Uint8 value; int x = 0, y = 0; while (imgFile.read((char*)&flag, sizeof(flag))) { flag = SDL_SwapLE16(flag); if (flag == 65535) { imgFile.read((char*)&flag, sizeof(flag)); flag = SDL_SwapLE16(flag); for (int i = 0; i < flag * 2; ++i) { setPixelIterative(&x, &y, 0); } } else if (flag == 65534) { imgFile.read((char*)&flag, sizeof(flag)); flag = SDL_SwapLE16(flag); for (int i = 0; i < flag * 2; ++i) { imgFile.read((char*)&value, 1); setPixelIterative(&x, &y, value); } } } // Unlock the surface unlock(); imgFile.close(); }
/** * Loads the contents of an X-Com SCR image file into * the surface. SCR files are simply uncompressed images * containing the palette offset of each pixel. * @param filename Filename of the SCR image. * @sa http://www.ufopaedia.org/index.php?title=Image_Formats#SCR_.26_DAT */ void Surface::loadScr(const std::string &filename) { // Load file and put pixels in surface std::ifstream imgFile (filename.c_str(), std::ios::in | std::ios::binary); if (!imgFile) { throw Exception(filename + " not found"); } // Lock the surface lock(); Uint8 value; int x = 0, y = 0; while (imgFile.read((char*)&value, 1)) { setPixelIterative(&x, &y, value); } if (!imgFile.eof()) { throw Exception("Invalid SCR file"); } // Unlock the surface unlock(); imgFile.close(); }
/** * Copies the exact contents of another surface onto this one. * Only the content that would overlap both surfaces is copied, in * accordance with their positions. This is handy for applying * effects over another surface without modifying the original. * @param surface Pointer to surface to copy from. */ void Surface::copy(Surface *surface) { /* SDL_BlitSurface uses colour matching, and is therefor unreliable as a means to copy the contents of one surface to another instead we have to do this manually SDL_Rect from; from.x = getX() - surface->getX(); from.y = getY() - surface->getY(); from.w = getWidth(); from.h = getHeight(); SDL_BlitSurface(surface->getSurface(), &from, _surface, 0); */ const int from_x = getX() - surface->getX(); const int from_y = getY() - surface->getY(); lock(); for (int x = 0, y = 0; x < getWidth() && y < getHeight();) { Uint8 pixel = surface->getPixel(from_x + x, from_y + y); setPixelIterative(&x, &y, pixel); } unlock(); }
/** * Shifts all the colors in the surface by a set amount. * This is a common method in 8bpp games to simulate color * effects for cheap. * @param off Amount to shift. * @param min Minimum color to shift to. * @param max Maximum color to shift to. * @param mul Shift multiplier. */ void Surface::offset(int off, int min, int max, int mul) { if (off == 0) return; // Lock the surface lock(); for (int x = 0, y = 0; x < getWidth() && y < getHeight();) { Uint8 pixel = getPixel(x, y); int p; if (off > 0) { p = pixel * mul + off; } else { p = (pixel + off) / mul; } if (min != -1 && p < min) { p = min; } else if (max != -1 && p > max) { p = max; } if (pixel > 0) { setPixelIterative(&x, &y, p); } else { setPixelIterative(&x, &y, 0); } } // Unlock the surface unlock(); }
/** * Inverts all the colors in the surface according to a middle point. * Used for effects like shifting a button between pressed and unpressed. * @param mid Middle point. */ void Surface::invert(Uint8 mid) { // Lock the surface lock(); for (int x = 0, y = 0; x < getWidth() && y < getHeight();) { Uint8 pixel = getPixel(x, y); if (pixel > 0) { setPixelIterative(&x, &y, pixel + 2 * ((int)mid - (int)pixel)); } else { setPixelIterative(&x, &y, 0); } } // Unlock the surface unlock(); }
/** * Loads the contents of an X-Com SCR image file into * the surface. SCR files are simply uncompressed images * containing the palette offset of each pixel. * @param filename Filename of the SCR image. * @sa http://www.ufopaedia.org/index.php?title=Image_Formats#SCR_.26_DAT */ void Surface::loadScr(const std::string &filename) { // Load file and put pixels in surface std::ifstream imgFile(filename.c_str(), std::ios::binary); if (!imgFile) { throw Exception(filename + " not found"); } std::vector<char> buffer((std::istreambuf_iterator<char>(imgFile)), (std::istreambuf_iterator<char>())); // Lock the surface lock(); int x = 0, y = 0; for (std::vector<char>::iterator i = buffer.begin(); i != buffer.end(); ++i) { setPixelIterative(&x, &y, *i); } // Unlock the surface unlock(); }