DNF_DLL/test/ReadNpk.hpp

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;
}