293 lines
8.2 KiB
C++
293 lines
8.2 KiB
C++
|
|
// ReadNpk.cpp : <20><><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD> "main" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD>н<EFBFBD><D0BD>ڴ˴<DAB4><CBB4><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
//
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
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* ת<><D7AA><EFBFBD><EFBFBD>
|
|||
|
|
int CharToInt(char* Str)
|
|||
|
|
{
|
|||
|
|
return *(int*)Str;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//char* תLong
|
|||
|
|
long long CharToLong(char* Str)
|
|||
|
|
{
|
|||
|
|
return *(long long*)Str;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
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;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//<2F><><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
|
|||
|
|
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;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//<2F><>ȡ<EFBFBD><C8A1>Ϣ
|
|||
|
|
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;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//<2F><>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;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//<2F><>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
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
|
|||
|
|
{
|
|||
|
|
//ͼƬ<CDBC><C6AC>ʽ
|
|||
|
|
int Type;
|
|||
|
|
//ѹ<><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
int CmpType;
|
|||
|
|
//<2F><><EFBFBD><EFBFBD>
|
|||
|
|
int Width;
|
|||
|
|
//<2F>߶<EFBFBD>
|
|||
|
|
int Height;
|
|||
|
|
//<2F><>С
|
|||
|
|
int Size;
|
|||
|
|
//Xpos
|
|||
|
|
int Xpos;
|
|||
|
|
//Ypos
|
|||
|
|
int Ypos;
|
|||
|
|
//֡<><D6A1>X
|
|||
|
|
int FrameXpos;
|
|||
|
|
//֡<><D6A1>Y
|
|||
|
|
int FrameYpos;
|
|||
|
|
//ƫ<><C6AB>
|
|||
|
|
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_<44><5F><EFBFBD><EFBFBD><EFBFBD>²<EFBFBD><C2B2><EFBFBD><EFBFBD><EFBFBD>.NPK", std::ios::in | std::ios::binary);
|
|||
|
|
|
|||
|
|
if (Fs)
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
std::string Header = Fs.ReadString();
|
|||
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>NPK
|
|||
|
|
if (Header._Equal("NeoplePack_Bill"))
|
|||
|
|
{
|
|||
|
|
int Count = Fs.ReadInt();
|
|||
|
|
std::cout << "img<EFBFBD><EFBFBD><EFBFBD><EFBFBD>:" << Count << std::endl;
|
|||
|
|
|
|||
|
|
//new<65><77> img<6D><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ṹ<EFBFBD><E1B9B9>
|
|||
|
|
NpkInfo* ImgList = new NpkInfo[Count];
|
|||
|
|
//<2F><>ȡ img<6D>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
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"))
|
|||
|
|
{
|
|||
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
|
|||
|
|
long long TableLength = Fs.ReadLong();
|
|||
|
|
//img <20>汾 4<>ֽ<EFBFBD>
|
|||
|
|
int ver = Fs.ReadInt();
|
|||
|
|
//img ֡<><D6A1>
|
|||
|
|
int IndexCount = Fs.ReadInt();
|
|||
|
|
|
|||
|
|
//new<65><77> Png<6E><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ṹ<EFBFBD><E1B9B9>
|
|||
|
|
ImgInfo* PngList = new ImgInfo[IndexCount];
|
|||
|
|
for (int i = 0; i < IndexCount; i++)
|
|||
|
|
{
|
|||
|
|
PngList[i].Type = Fs.ReadInt();
|
|||
|
|
if (PngList[i].Type == 17)
|
|||
|
|
{
|
|||
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ
|
|||
|
|
std::cout << Fs.ReadInt() << std::endl;
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
//ѹ<><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
PngList[i].CmpType = Fs.ReadInt();
|
|||
|
|
//<2F><><EFBFBD><EFBFBD>
|
|||
|
|
PngList[i].Width = Fs.ReadInt();
|
|||
|
|
//<2F>߶<EFBFBD>
|
|||
|
|
PngList[i].Height = Fs.ReadInt();
|
|||
|
|
//<2F><>С
|
|||
|
|
PngList[i].Size = Fs.ReadInt();
|
|||
|
|
//Xpos
|
|||
|
|
PngList[i].Xpos = Fs.ReadInt();
|
|||
|
|
//Ypos
|
|||
|
|
PngList[i].Ypos = Fs.ReadInt();
|
|||
|
|
//֡<><D6A1>X
|
|||
|
|
PngList[i].FrameXpos = Fs.ReadInt();
|
|||
|
|
//֡<><D6A1>Y
|
|||
|
|
PngList[i].FrameYpos = Fs.ReadInt();
|
|||
|
|
//<2F><><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB>
|
|||
|
|
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;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//<2F><><EFBFBD><EFBFBD>img<6D>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
delete[]ImgList;
|
|||
|
|
//<2F><><EFBFBD><EFBFBD>Png<6E>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
std::cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>" << std::endl;
|
|||
|
|
}
|
|||
|
|
Fs.close();
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|