/** * Loads an X-Com palette from a file. X-Com palettes are just a set * of RGB colors in a row, on a 0-63 scale, which have to be adjusted * for modern computers (0-255 scale). * @param filename Filename of the palette. * @param ncolors Number of colors in the palette. * @param offset Position of the palette in the file (in bytes). * @sa http://www.ufopaedia.org/index.php?title=PALETTES.DAT */ void Palette::loadDat(const std::string &filename, int ncolors, int offset) { if (_colors != 0) throw Exception("loadDat can be run only once"); _count = ncolors; _colors = new SDL_Color[_count]; memset(_colors, 0, sizeof(SDL_Color) * _count); // Load file and put colors in palette std::ifstream palFile (filename.c_str(), std::ios::in | std::ios::binary); if (!palFile) { throw Exception(filename + " not found"); } // Move pointer to proper palette palFile.seekg(offset, std::ios::beg); Uint8 value[3]; for (int i = 0; i < _count && palFile.read((char*)value, 3); ++i) { // Correct X-Com colors to RGB colors _colors[i].r = value[0] * 4; _colors[i].g = value[1] * 4; _colors[i].b = value[2] * 4; _colors[i].unused = 255; } _colors[0].unused = 0; palFile.close(); }
TilesetPtr TilesetType_Zone66::open(stream::inout_sptr psTileset, SuppData& suppData) const { PaletteTablePtr pal; // Only load the palette if one was given if (suppData.find(SuppItem::Palette) != suppData.end()) { ImagePtr palFile(new Palette_VGA(suppData[SuppItem::Palette], 6)); pal = palFile->getPalette(); pal->at(Z66_TRANSPARENT_COLOUR).alpha = 0; } return TilesetPtr(new Tileset_Zone66(psTileset, pal)); }
TilesetPtr TilesetType_HarryCHR::open(stream::inout_sptr psTileset, SuppData& suppData) const { PaletteTablePtr pal; if (suppData.find(SuppItem::Palette) != suppData.end()) { ImagePtr palFile(new Palette_HarryGMF(suppData[SuppItem::Palette])); pal = palFile->getPalette(); } else { throw stream::error("no palette specified (missing supplementary item)"); } return TilesetPtr(new Tileset_HarryCHR(psTileset, pal)); }
TilesetPtr TilesetType_HarryCHR::create(stream::inout_sptr psTileset, SuppData& suppData) const { psTileset->truncate(CHR_WIDTH * CHR_HEIGHT * 256); psTileset->seekp(0, stream::start); char empty[CHR_WIDTH * CHR_HEIGHT]; memset(empty, 0x00, CHR_WIDTH * CHR_HEIGHT); for (int i = 0; i < 256; i++) psTileset->write(empty, CHR_WIDTH * CHR_HEIGHT); PaletteTablePtr pal; if (suppData.find(SuppItem::Palette) != suppData.end()) { ImagePtr palFile(new Palette_VGA(suppData[SuppItem::Palette], 6)); pal = palFile->getPalette(); } else { throw stream::error("no palette specified (missing supplementary item)"); } return TilesetPtr(new Tileset_HarryCHR(psTileset, pal)); }
int ConvertMutToBmp(const string &fileName) { DataReader mutFile(fileName); if (mutFile.IsOpen()) { //Check it's the right file type. char actualHeader[6]; memset(actualHeader,0,sizeof(actualHeader)); for (int i = 0; i < 6; ++i) { actualHeader[i] = mutFile.ReadByte(); } if (strcmp(actualHeader, siegeHeader) != 0) //The same header files - we're good to process them. { cout << "Error: not a valid MUT file\n"; mutFile.Close(); return -1; } char imageData[8192]; memset(imageData,0,sizeof(imageData)); for (int i = 8191; i >= 0; --i) //Siege stores its images upside-down, so reverse it here. { imageData[i] = mutFile.ReadByte(); } mutFile.Close(); DataReader palFile("siege.pal"); char* palette = NULL; if (palFile.IsOpen()) //Read our palette information { if (static_cast<int>(palFile.GetFileSize()) == 768) { palette = new char[palFile.GetFileSize()]; for (int i = 0; i < palFile.GetFileSize(); ++i) { palette[i] = palFile.ReadByte(); } palFile.Close(); } else { cout << "Error: Pallete incorrect size\n"; return -1; } } else { cout << "Error: Failed reading Siege.pal\n"; return -1; } //Start building a BMP file size_t lastBackslash = fileName.find_last_of("/\\"); string newFileName = fileName.substr(lastBackslash+1, fileName.length() - lastBackslash - 4); newFileName+="bmp"; if (DataFile::FileExists(newFileName)) { cout << "Error: " << newFileName << " already exists - remove it before proceeding\n"; return -1; } DataWriter bmpFile(newFileName); if (bmpFile.IsOpen()) { bmpFile.Write("BM", 2); //BMP file format bmpFile.Write(9270,4);//File size bmpFile.Write(0,2); //Unused bmpFile.Write(0,2); //Unused bmpFile.Write(1078,4);//Offset //IMAGE HEADER bmpFile.Write(40,4);//header size bmpFile.Write(16,4);//Width bmpFile.Write(512,4);//Height bmpFile.Write(1,2);//Colour planes bmpFile.Write(8,2);//Colour depth - 256 colour bmpFile.Write(0,4);//Compression bmpFile.Write(8192,4); //Image size bmpFile.Write(0,4); //Horizontal resolution bmpFile.Write(0,4); //Vertical resolution bmpFile.Write(0,4); //colour pallette count - 0 means autodetect bmpFile.Write(0,4); //important colours //PALETTE for(int i = 0; i < 256; ++i) { bmpFile.Write(palette[(i*3)+2]); //Red //Colours are stored as BGR in Siege's palette - backwards again bmpFile.Write(palette[(i*3)+1]); //Green bmpFile.Write(palette[(i*3)]); //Blue bmpFile.Write(0); //Unused - bitmaps pad the alpha channel to keep things in a nice DWORD size } //IMAGE DATA for (int j = 0; j < 8192; ++j) { bmpFile.Write(imageData[j]); } } else { cout << "Error: could not open " << newFileName << " for writing\n"; if (palette) { delete[] palette; } return -1; } if (palette) { delete[] palette; } cout << "Successfully created " << newFileName << "\n"; return 0; } else { cout << "Error - could not open " << fileName << " for reading\n"; return -1; } }