public string createTextureMod(string inDir, string outFile, List <FoundTexture> textures, MainWindow mainWindow, ref string log) { string errors = ""; int count = 0; List <string> files = Directory.GetFiles(inDir, "*.dds").Where(item => item.EndsWith(".dds", StringComparison.OrdinalIgnoreCase)).ToList(); files.Sort(); List <FileMod> modFiles = new List <FileMod>(); using (FileStream outFs = new FileStream(outFile, FileMode.Create, FileAccess.Write)) { outFs.WriteUInt32(TexExplorer.TextureModTag); outFs.WriteUInt32(TexExplorer.TextureModVersion); outFs.WriteInt64(0); // files info offset - filled later for (int n = 0; n < files.Count(); n++) { string file = files[n]; if (mainWindow != null) { mainWindow.updateStatusLabel("Creating MOD: " + Path.GetFileName(outFile)); mainWindow.updateStatusLabel2("Texture " + (n + 1) + " of " + files.Count() + ", File: " + Path.GetFileName(file)); } string filename = Path.GetFileNameWithoutExtension(file).ToLowerInvariant(); if (!filename.Contains("0x")) { errors += "Texture filename not valid: " + Path.GetFileName(file) + " Texture filename must include texture CRC (0xhhhhhhhh). Skipping texture..." + Environment.NewLine; log += "Texture filename not valid: " + Path.GetFileName(file) + " Texture filename must include texture CRC (0xhhhhhhhh). Skipping texture..." + Environment.NewLine; continue; } int idx = filename.IndexOf("0x"); if (filename.Length - idx < 10) { errors += "Texture filename not valid: " + Path.GetFileName(file) + " Texture filename must include texture CRC (0xhhhhhhhh). Skipping texture..." + Environment.NewLine; log += "Texture filename not valid: " + Path.GetFileName(file) + " Texture filename must include texture CRC (0xhhhhhhhh). Skipping texture..." + Environment.NewLine; continue; } uint crc; string crcStr = filename.Substring(idx + 2, 8); try { crc = uint.Parse(crcStr, System.Globalization.NumberStyles.HexNumber); } catch { errors += "Texture filename not valid: " + Path.GetFileName(file) + " Texture filename must include texture CRC (_0xhhhhhhhh). Skipping texture..." + Environment.NewLine; log += "Texture filename not valid: " + Path.GetFileName(file) + " Texture filename must include texture CRC (_0xhhhhhhhh). Skipping texture..." + Environment.NewLine; continue; } List <FoundTexture> foundCrcList = textures.FindAll(s => s.crc == crc); if (foundCrcList.Count == 0) { errors += "Texture skipped. Texture " + Path.GetFileName(file) + " is not present in your game setup." + Environment.NewLine; log += "Texture skipped. Texture " + Path.GetFileName(file) + " is not present in your game setup." + Environment.NewLine; continue; } int savedCount = count; using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read)) { byte[] src = fs.ReadToBuffer((int)fs.Length); DDSImage image = new DDSImage(new MemoryStream(src)); if (!image.checkExistAllMipmaps()) { errors += "Error in texture: " + Path.GetFileName(file) + " This texture has not all the required mipmaps, skipping texture..." + Environment.NewLine; log += "Error in texture: " + Path.GetFileName(file) + " This texture has not all the required mipmaps, skipping texture..." + Environment.NewLine; continue; } Package pkg = new Package(GameData.GamePath + foundCrcList[0].list[0].path); Texture texture = new Texture(pkg, foundCrcList[0].list[0].exportID, pkg.getExportData(foundCrcList[0].list[0].exportID)); if (texture.mipMapsList.Count > 1 && image.mipMaps.Count() <= 1) { errors += "Error in texture: " + Path.GetFileName(file) + " This texture must have mipmaps, skipping texture..." + Environment.NewLine; log += "Error in texture: " + Path.GetFileName(file) + " This texture must have mipmaps, skipping texture..." + Environment.NewLine; continue; } string fmt = texture.properties.getProperty("Format").valueName; DDSFormat ddsFormat = DDSImage.convertFormat(fmt); if (image.ddsFormat != ddsFormat) { errors += "Error in texture: " + Path.GetFileName(file) + " This texture has wrong texture format, should be: " + ddsFormat + ", skipping texture..." + Environment.NewLine; log += "Error in texture: " + Path.GetFileName(file) + " This texture has wrong texture format, should be: " + ddsFormat + ", skipping texture..." + Environment.NewLine; continue; } if (image.mipMaps[0].origWidth / image.mipMaps[0].origHeight != texture.mipMapsList[0].width / texture.mipMapsList[0].height) { errors += "Error in texture: " + Path.GetFileName(file) + " This texture has wrong aspect ratio, skipping texture..." + Environment.NewLine; log += "Error in texture: " + Path.GetFileName(file) + " This texture has wrong aspect ratio, skipping texture..." + Environment.NewLine; continue; } Stream dst = compressData(src); dst.SeekBegin(); FileMod fileMod = new FileMod(); fileMod.tag = FileTextureTag; fileMod.name = Path.GetFileName(file); fileMod.offset = outFs.Position; fileMod.size = dst.Length; count++; modFiles.Add(fileMod); outFs.WriteStringASCIINull(foundCrcList[0].name); outFs.WriteUInt32(crc); outFs.WriteFromStream(dst, dst.Length); } if (count == savedCount) { continue; } } long pos = outFs.Position; outFs.SeekBegin(); outFs.WriteUInt32(TexExplorer.TextureModTag); outFs.WriteUInt32(TexExplorer.TextureModVersion); outFs.WriteInt64(pos); outFs.JumpTo(pos); outFs.WriteUInt32((uint)GameData.gameType); outFs.WriteInt32(modFiles.Count); for (int i = 0; i < modFiles.Count; i++) { outFs.WriteUInt32(modFiles[i].tag); outFs.WriteStringASCIINull(modFiles[i].name); outFs.WriteInt64(modFiles[i].offset); outFs.WriteInt64(modFiles[i].size); } } if (count == 0) { errors += "There are no texture files in " + inDir + ", mod not generated." + Environment.NewLine; log += "There are no texture files in " + inDir + ", mod not generated." + Environment.NewLine; File.Delete(outFile); } return(errors); }