public void ChangeImageData(int index, ImageData newData) { //Read the old data BinaryReader reader = new BinaryReader(baseStream); reader.BaseStream.Seek(0, SeekOrigin.Begin); Byte[] oldData = reader.ReadBytes((int)baseStream.Length); //Get old image we want to change and create the corresponding new file data bytes from the new image GfxImage image = images[index]; Byte[] imageDataToWrite = image.CreateImageData(newData); //The new bytes which are to be written to the gfx file int nextImageStartOffset = offsetTable.GetImageOffset(index + 1); //Get the current offset of the next image int offset = Math.Max(0, ((images[index].DataOffset + imageDataToWrite.Length) - nextImageStartOffset) - 1); //Our data could be larger, calculate how much larger Byte[] newDataBuffer = new Byte[(int)baseStream.Length + offset]; //Our new data Buffer.BlockCopy(oldData, 0, newDataBuffer, 0, image.DataOffset); //Fill it with the old data, up until our new image. We don't need to rewrite it, it still works //write new data Buffer.BlockCopy(imageDataToWrite, 0, newDataBuffer, image.DataOffset, imageDataToWrite.Length); //Our new image gets written to the new gfx file if (offset != 0) //We want to move all images that follow our changed image, if our new image is bigger { offsetTable.AddOffsetToFollowing(index + 1, offset); File.WriteAllBytes("14TEST.gil", offsetTable.GetData()); //TODO! Change file name! } //Write new width and height int newImageOffset = offsetTable.GetImageOffset(index); if (image.headType) //All sizes are 8Bit when true { newDataBuffer[newImageOffset] = (Byte)newData.width; //width newDataBuffer[newImageOffset + 1] = (Byte)newData.height; //height } else //16bit values { newDataBuffer[newImageOffset] = (Byte)newData.width; //width 1. Byte newDataBuffer[newImageOffset + 1] = (Byte)(newData.width >> 8); //width 2. Byte newDataBuffer[newImageOffset + 2] = (Byte)newData.height; //height 1. Byte newDataBuffer[newImageOffset + 3] = (Byte)(newData.height >> 8); //height 2. Byte } //All files end with 0 and 1! This marks the end of the file newDataBuffer[nextImageStartOffset + offset - 1] = 0; newDataBuffer[nextImageStartOffset + offset - 2] = 1; Buffer.BlockCopy(oldData, nextImageStartOffset - offset, newDataBuffer, offsetTable.GetImageOffset(index + 1), oldData.Length - nextImageStartOffset); File.WriteAllBytes("14TEST.gfx", newDataBuffer); //TODO! Change file name! }
public void ChangeImageData(string groupID, int index, ImageData[] newDatas) { if (newDatas[0].GetUsedColors().Length > 255) { throw new Exception("Imported images cannot have more than 255 colors!"); } //Prepare the new palette Palette p = paletteCollection.GetPalette(); int start = paletteCollection.GetOffset(GetImage(index).jobIndex); int palettePosition = 0; for (int j = 0; j < newDatas.Length; j++) { GfxImage i = images[index + j]; i.Width = newDatas[j].width; i.Height = newDatas[j].height; //i.DataOffset = offsetTable.GetImageOffset(index + j) + 12; palettePosition += RecreatePaletteAt(start, palettePosition, newDatas[j]); i.buffer = i.CreateImageData(newDatas[j]); int nextImageStartOffset = offsetTable.GetImageOffset(index + j + 1); //Get the current offset of the next image int offset = Math.Max(0, i.DataOffset + i.buffer.Length - nextImageStartOffset - 1); //Our data could be larger, calculate how much larger if (offset != 0) //We want to move all images that follow our changed image, if our new image is bigger { offsetTable.AddOffsetToFollowing(index + j + 1, offset); } i.DataOffset = 0; //Hack, the data is still at the same offset, but the way the we handle the reading forces us to set it to 0, as we write the new image data to buffer[0...] instead of buffer[DataOffset...] } byte[] gfxDataBuffer = GetData(); byte[] pilDataBuffer = paletteCollection.GetPilFile().GetData(); byte[] paletteDataBuffer = paletteCollection.GetData(); string fileId = groupID; File.WriteAllBytes(fileId + ".gfx", gfxDataBuffer); File.WriteAllBytes(fileId + ".pi4", pilDataBuffer); File.WriteAllBytes(fileId + ".p46", paletteDataBuffer); File.WriteAllBytes(fileId + ".pi2", pilDataBuffer); File.WriteAllBytes(fileId + ".p26", paletteDataBuffer); File.WriteAllBytes(fileId + ".gil", offsetTable.GetData()); }
/// <summary> /// Temporary function to remove the DIL and JIL "feature" - turns out, the game uses it for more than palette informations /// </summary> public void RemoveDILDependence() { //Prepare the colors for the palette generation ImageData[] colorData = new ImageData[images.Length]; for (int j = 0; j < images.Length; j++) { colorData[j] = images[j].GetImageData(); uint[] colorsToBeAdded = colorData[j].GetUsedColors(); } PilFileReader pil = paletteCollection.GetPilFile(); pil.Resize(images.Length); paletteCollection.SetPalette(new Palette((256 * images.Length + 20) * 2)); //maximum size for a palette. We could shrink it to size, but we don't have to for (int j = 0; j < images.Length; j++) { GfxImage i = images[j]; int newPaletteOffset = 255 * j + 20; //Set according to JIL/normal palette offset. i.paletteOffset = newPaletteOffset; i.palette = paletteCollection.GetPalette(); //RecreatePalette(j, 255 * j + 20, colorData[j]); //Skip repeating JIL entries. They share the same palette i.buffer = i.CreateImageData(colorData[j]); i.DataOffset = 0; //Hack, the data is still at the same offset, but the way the we handle the reading forces us to set it to 0, as we write the new image data to buffer[0...] instead of buffer[DataOffset...] } byte[] gfxDataBuffer = GetData(); byte[] pilDataBuffer = paletteCollection.GetPilFile().GetData(); byte[] paletteDataBuffer = paletteCollection.GetData(); //directionIndexList.FakeLookupOffset(images.Length, jobIndexList); //Make every DIL entry point to itself. Doesnt work though in game //jobIndexList.FakeLookupOffset(images.Length); File.WriteAllBytes("3.gfx", gfxDataBuffer); //TODO! Change file name! File.WriteAllBytes("3.pi4", pilDataBuffer); //TODO! Change file name! File.WriteAllBytes("3.p46", paletteDataBuffer); //TODO! Change file name! File.WriteAllBytes("3.pi2", pilDataBuffer); //TODO! Change file name! File.WriteAllBytes("3.p26", paletteDataBuffer); //TODO! Change file name! File.WriteAllBytes("3.dil", directionIndexList.GetData()); //TODO! Change file name! File.WriteAllBytes("3.jil", jobIndexList.GetData()); //TODO! Change file name! }
/// <summary> /// Changes the images starting from index. /// </summary> /// <param name="groupID"></param> /// <param name="index"></param> /// <param name="newDatas"></param> /// <returns></returns> public void ChangeImageData(string groupID, int index, ImageData[] newDatas) { if (newDatas[0].GetUsedColors().Length > 255) { throw new Exception("Imported images cannot have more than 255 colors!"); } //Prepare the new palette Palette p = paletteCollection.GetPalette(); int palettePosition = 0; int addedLength = 0; int oldIndex = (GetImage(index) as GfxImage)?.jobIndex ?? 0; for (int j = 0; j < newDatas.Length; j++) { if (index + j >= images.Length) { Array.Resize(ref images, index + j + 1); paletteCollection.GetPilFile().Resize(images.Length); p.AddEntry(); paletteCollection.GetPilFile().SetOffset(index + j, (paletteCollection.GetPilFile().GetOffset(index + j - 1) + 256 * 2)); images[index + j] = new GfxImage( null, p, paletteCollection.GetOffset(index + j)); images[index + j].jobIndex = index + j; offsetTable.AddOffset(); offsetTable.offsetTable[index + j] = (int)baseStream.Length + addedLength; } GfxImage i = images[index + j]; if (i.jobIndex != oldIndex) { palettePosition = 0; } int start = paletteCollection.GetOffset(i.jobIndex); i.Width = newDatas[j].width; i.Height = newDatas[j].height; //i.DataOffset = offsetTable.GetImageOffset(index + j) + 12; palettePosition += RecreatePaletteAt(start, palettePosition, newDatas[j]); i.buffer = i.CreateImageData(newDatas[j]); addedLength += i.buffer.Length; int nextImageStartOffset = offsetTable.GetImageOffset(index + j + 1); //Get the current offset of the next image int offset = Math.Max(0, offsetTable.GetImageOffset(index + j) + i.HeaderSize + i.buffer.Length - nextImageStartOffset - 1); //Our data could be larger, calculate how much larger if (offset != 0) //We want to move all images that follow our changed image, if our new image is bigger { offsetTable.AddOffsetToFollowing(index + j + 1, offset); } i.DataOffset = 0; //Hack, the data is still at the same offset, but the way the we handle the reading forces us to set it to 0, as we write the new image data to buffer[0...] instead of buffer[DataOffset...] oldIndex = i.jobIndex; Console.WriteLine($"{j}/{newDatas.Length} importing..."); } //return GetDataBufferCollection(groupID); }