293 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			293 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C++
		
	
	
	
| // ReadNpk.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
 | |
| //
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| static void ReadColor(BYTE* Tab, int Type, BYTE* SaveByte, int Offset)
 | |
| {
 | |
|     BYTE a = 0;
 | |
|     BYTE r = 0;
 | |
|     BYTE g = 0;
 | |
|     BYTE b = 0;
 | |
|     switch (Type)
 | |
|     {
 | |
|     case 0x0e:
 | |
|         a = (byte)(Tab[1] >> 7);
 | |
|         r = (byte)((Tab[1] >> 2) & 0x1f);
 | |
|         g = (byte)((Tab[0] >> 5) | ((Tab[1] & 3) << 3));
 | |
|         b = (byte)(Tab[0] & 0x1f);
 | |
|         a = (byte)(a * 0xff);
 | |
|         r = (byte)((r << 3) | (r >> 2));
 | |
|         g = (byte)((g << 3) | (g >> 2));
 | |
|         b = (byte)((b << 3) | (b >> 2));
 | |
|         break;
 | |
|     case 0x0f:
 | |
|         a = (byte)(Tab[1] & 0xf0);
 | |
|         r = (byte)((Tab[1] & 0xf) << 4);
 | |
|         g = (byte)(Tab[0] & 0xf0);
 | |
|         b = (byte)((Tab[0] & 0xf) << 4);
 | |
|         break;
 | |
|     }
 | |
|     SaveByte[Offset + 0] = b;
 | |
|     SaveByte[Offset + 1] = g;
 | |
|     SaveByte[Offset + 2] = r;
 | |
|     SaveByte[Offset + 3] = a;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| class ReadNpk :public std::ifstream
 | |
| {
 | |
|     const BYTE Key[256] = { 112,117,99,104,105,107,111,110,64,110,101,111,112,108,101,32,100,117,110,103,101,111,110,32,97,110,100,32,102,105,103,104,116,101,114,32,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,0 };
 | |
| 
 | |
| public:
 | |
|     //char* 转整数
 | |
|     int CharToInt(char* Str)
 | |
|     {
 | |
|         return *(int*)Str;
 | |
|     }
 | |
| 
 | |
|     //char* 转Long
 | |
|     long long CharToLong(char* Str)
 | |
|     {
 | |
|         return *(long long*)Str;
 | |
|     }
 | |
| 
 | |
| 
 | |
|     //DNFTOOL::ReadInt
 | |
|     int ReadInt()
 | |
|     {
 | |
|         char* CountBuffer = new char[4];
 | |
|         for (int i = 0; i < 4; i++)
 | |
|         {
 | |
|             this->get(CountBuffer[i]);
 | |
|         }
 | |
|         int Count = CharToInt(CountBuffer);
 | |
|         delete[]CountBuffer;
 | |
|         return Count;
 | |
|     }
 | |
| 
 | |
|     //读字符串
 | |
|     std::string ReadString()
 | |
|     {
 | |
|         char* CharBuffer = new char[1024];
 | |
|         this->get(CharBuffer, 1024, '\0');
 | |
|         std::string Str = CharBuffer;
 | |
|         delete[]CharBuffer;
 | |
|         this->seekg(1, std::ios::cur);
 | |
|         return Str;
 | |
|     }
 | |
| 
 | |
|     //读取信息
 | |
|     std::string ReadInfo()
 | |
|     {
 | |
|         char* CharBuffer = new char[256];
 | |
|         char var;
 | |
|         int i = 0;
 | |
|         while (i < 256)
 | |
|         {
 | |
|             this->get(var);
 | |
|             CharBuffer[i] = var ^ Key[i];
 | |
|             ++i;
 | |
|         }
 | |
|         std::string Str = CharBuffer;
 | |
|         delete[] CharBuffer;
 | |
|         return Str;
 | |
|     }
 | |
| 
 | |
|     //读LONG
 | |
|     long long ReadLong()
 | |
|     {
 | |
|         char* CountBuffer = new char[8];
 | |
|         for (int i = 0; i < 8; i++)
 | |
|         {
 | |
|             this->get(CountBuffer[i]);
 | |
|         }
 | |
|         long long Count = CharToLong(CountBuffer);
 | |
|         delete[]CountBuffer;
 | |
|         return Count;
 | |
|     }
 | |
| 
 | |
|     //读指定长度数据
 | |
|     BYTE* ReadCustomSize(int Size)
 | |
|     {
 | |
|         BYTE* CharBuffer = new BYTE[Size];
 | |
|         for (int j = 0; j < Size; j++)
 | |
|         {
 | |
|             char var;
 | |
|             this->get(var);
 | |
|             CharBuffer[j] = var;
 | |
|         }
 | |
|         return CharBuffer;
 | |
|     }
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| struct NpkInfo
 | |
| {
 | |
|     int Offset;
 | |
|     int Length;
 | |
|     std::string Path;
 | |
| };
 | |
| 
 | |
| struct ImgInfo
 | |
| {
 | |
|     //图片格式
 | |
|     int Type;
 | |
|     //压缩类型
 | |
|     int CmpType;
 | |
|     //宽度
 | |
|     int Width;
 | |
|     //高度
 | |
|     int Height;
 | |
|     //大小
 | |
|     int Size;
 | |
|     //Xpos
 | |
|     int Xpos;
 | |
|     //Ypos
 | |
|     int Ypos;
 | |
|     //帧域X
 | |
|     int FrameXpos;
 | |
|     //帧域Y
 | |
|     int FrameYpos;
 | |
|     //偏移
 | |
|     int Offset;
 | |
|     
 | |
| };
 | |
| 
 | |
| // xxxx.img 5
 | |
| 
 | |
| static BYTE* GetNPK()
 | |
| {
 | |
|     typedef  int (*__Decompress)(BYTE* dest, ULONG* destLen, BYTE* source, ULONG sourceLen);
 | |
|     HMODULE hDll = LoadLibrary(L"zlib1.dll");
 | |
| 
 | |
|     __Decompress Decompress = (__Decompress)GetProcAddress(hDll, "uncompress");
 | |
| 
 | |
| 
 | |
|     ReadNpk Fs;
 | |
|     Fs.open("!HUD_阿拉德猜数字.NPK", std::ios::in | std::ios::binary);
 | |
| 
 | |
|     if (Fs)
 | |
|     {
 | |
| 
 | |
|         std::string Header = Fs.ReadString();
 | |
|         //如果是NPK
 | |
|         if (Header._Equal("NeoplePack_Bill"))
 | |
|         {
 | |
|             int Count = Fs.ReadInt();
 | |
|             std::cout << "img数量:" << Count << std::endl;
 | |
| 
 | |
|             //new出 img数量的 结构体
 | |
|             NpkInfo* ImgList = new NpkInfo[Count];
 | |
|             //读取 img列表数据
 | |
|             for (int i = 0; i < Count; i++)
 | |
|             {
 | |
|                 ImgList[i].Offset = Fs.ReadInt();
 | |
|                 ImgList[i].Length = Fs.ReadInt();
 | |
|                 ImgList[i].Path = Fs.ReadInfo();
 | |
|             }
 | |
| 
 | |
|             for (int z = 0; z < Count; z++)
 | |
|             {
 | |
|                 Fs.seekg(ImgList[z].Offset);
 | |
|                 std::string Flag = Fs.ReadString();
 | |
|                 if (Flag._Equal("Neople Img File"))
 | |
|                 {
 | |
|                     //索引表大小
 | |
|                     long long TableLength = Fs.ReadLong();
 | |
|                     //img 版本 4字节
 | |
|                     int ver = Fs.ReadInt();
 | |
|                     //img 帧数
 | |
|                     int IndexCount = Fs.ReadInt();
 | |
| 
 | |
|                     //new出 Png数量的 结构体
 | |
|                     ImgInfo* PngList = new ImgInfo[IndexCount];
 | |
|                     for (int i = 0; i < IndexCount; i++)
 | |
|                     {
 | |
|                         PngList[i].Type = Fs.ReadInt();
 | |
|                         if (PngList[i].Type == 17)
 | |
|                         {
 | |
|                             //引用贴图
 | |
|                             std::cout << Fs.ReadInt() << std::endl;
 | |
|                             continue;
 | |
|                         }
 | |
|                         //压缩类型
 | |
|                         PngList[i].CmpType = Fs.ReadInt();
 | |
|                         //宽度
 | |
|                         PngList[i].Width = Fs.ReadInt();
 | |
|                         //高度
 | |
|                         PngList[i].Height = Fs.ReadInt();
 | |
|                         //大小
 | |
|                         PngList[i].Size = Fs.ReadInt();
 | |
|                         //Xpos
 | |
|                         PngList[i].Xpos = Fs.ReadInt();
 | |
|                         //Ypos
 | |
|                         PngList[i].Ypos = Fs.ReadInt();
 | |
|                         //帧域X
 | |
|                         PngList[i].FrameXpos = Fs.ReadInt();
 | |
|                         //帧域Y
 | |
|                         PngList[i].FrameYpos = Fs.ReadInt();
 | |
|                         //计算偏移
 | |
|                         if (i == 0)PngList[i].Offset = 0 + ImgList[z].Offset + TableLength + 32;
 | |
|                         else PngList[i].Offset = PngList[i - 1].Offset + PngList[i - 1].Size;
 | |
|                     }
 | |
| 
 | |
| 
 | |
| 
 | |
|                     Fs.seekg(PngList[0].Offset);
 | |
|                     std::cout << PngList[0].Size << std::endl;
 | |
|                     BYTE* PngData = Fs.ReadCustomSize(PngList[0].Size);
 | |
| 
 | |
|                     int DeSize = PngList[0].Width * PngList[0].Height * 4;
 | |
|                     BYTE* bByte = new BYTE[DeSize];
 | |
|                     ULONG RealSize;
 | |
|                     int a = Decompress(bByte, &RealSize, PngData, (ULONG)PngList[0].Size);
 | |
|                     delete[]PngData;
 | |
| 
 | |
|                     if (PngList[0].Type != 16)
 | |
|                     {
 | |
|                         int PngByteSize = DeSize * 2;
 | |
|                         BYTE* PngByte = new BYTE[PngByteSize];
 | |
| 
 | |
| 
 | |
|                         for (int e = 0; e < PngByteSize; e += 4)
 | |
|                         {
 | |
|                             BYTE NeedData[4];
 | |
|                             memset(NeedData, 0, sizeof(NeedData));
 | |
|                             memcpy(NeedData, bByte + e, sizeof(NeedData));
 | |
|                             ReadColor(NeedData, PngList[0].Type, PngByte, e);
 | |
|                         }
 | |
|                         delete[]bByte;
 | |
| 
 | |
|                         for (int o = 0; o < PngByteSize; o++)
 | |
|                         {
 | |
|                             //std::cout << (int)PngByte[o] << ",";
 | |
|                         }
 | |
|                         delete[]PngByte;
 | |
|                     }
 | |
| 
 | |
| 
 | |
|                     return bByte;
 | |
| 
 | |
|                     delete[] bByte;
 | |
|                     delete[]PngList;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             //销毁img列表数据
 | |
|             delete[]ImgList;
 | |
|             //销毁Png列表数据
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         std::cout << "打开失败" << std::endl;
 | |
|     }
 | |
|     Fs.close();
 | |
|     return 0;
 | |
| }
 | |
| 
 |