#include "Npk.h" #include #include std::mutex Npk_ImgMutex; std::mutex Npk_PngMutex; 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 CharToLong(char* Str) { return *(long long*)Str; } //读整数 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 int ReadLong() { char* CountBuffer = new char[8]; for (int i = 0; i < 8; i++) { this->get(CountBuffer[i]); } 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; } }; 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; } NPK_M::NPK_M() { } void NPK_M::init() { WIN32_FIND_DATAA lpdata; DWORD read; HANDLE hFindFile = FindFirstFileA("ImagePacks2\\*.npk", &lpdata); do { //拼接完整路径 char cat[256] = "ImagePacks2\\"; strcat(cat, lpdata.cFileName); ReadNpk Fs; Fs.open(cat, std::ios::in | std::ios::binary); if (Fs) { std::string Header = Fs.ReadString(); //如果是NPK if (Header._Equal("NeoplePack_Bill")) { //读取img数量 int ImageCount = Fs.ReadInt(); //读取头 NpkInfo* ImgList = new NpkInfo[ImageCount]; for (size_t i = 0; i < ImageCount; i++) { ImgList[i].Offset = Fs.ReadInt(); ImgList[i].Length = Fs.ReadInt(); ImgList[i].Path = Fs.ReadInfo(); } for (int i = 0; i < ImageCount; i++) { IMG img; img.imgOffset = ImgList[i].Offset; img.imgSize = ImgList[i].Length; img.img_index = i; img.lpBelongsFile = lpdata.cFileName; img.lpImgName = ImgList[i].Path; img.lp_lplist = NULL; img.png_sum = 0; map_npk.insert(make_pair(img.lpImgName, img)); } //销毁 delete[]ImgList; } } Fs.close(); } while (FindNextFileA(hFindFile, &lpdata)); FindClose(hFindFile); ReadNpkTable("sprite/interface2/event/chn_event_2016/160927_joustmatches/knight0.img"); return; } LPDWORD NPK_M::LoadImgToMem(IMG* p) { //拼接NPK名称 char dirname[256] = "ImagePacks2\\"; strcat(dirname, p->lpBelongsFile.c_str()); ReadNpk Fs; Fs.open(dirname, std::ios::in | std::ios::binary); if (Fs) { Fs.seekg(p->imgOffset); std::string Flag = Fs.ReadString(); if (Flag._Equal("Neople Img File")) { //索引表大小 long TableLength = Fs.ReadLong(); //img 版本 4字节 int ver = Fs.ReadInt(); //img 帧数 int IndexCount = Fs.ReadInt(); Npk_PngMutex.lock(); //图片数量赋值 p->png_sum = IndexCount; Npk_PngMutex.unlock(); //new出 Png数量的 结构体 ImgInfo* PngList = new ImgInfo[IndexCount]; for (size_t i = 0; i < IndexCount; i++) { PngList[i].Type = Fs.ReadInt(); if (PngList[i].Type == 17) { //引用贴图 int frbuf = Fs.ReadInt(); 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 + p->imgOffset + TableLength + 32; else PngList[i].Offset = PngList[i - 1].Offset + PngList[i - 1].Size; } for (size_t i = 0; i < IndexCount; i++) { Fs.seekg(PngList[i].Offset); BYTE* PngData = Fs.ReadCustomSize(PngList[i].Size); int DeSize = PngList[i].Width * PngList[i].Height * 4; BYTE* bByte = new BYTE[DeSize]; ULONG RealSize = DeSize; int a = uncompress(bByte, &RealSize, PngData, (ULONG)PngList[i].Size); delete[]PngData; if (PngList[i].Type != 16) { int PngByteSize = DeSize * 2; PngList[i].PNGdata = new BYTE[PngByteSize]; for (int e = 0; e < PngByteSize; e += 4) { BYTE NeedData[2]; memset(NeedData, 0, 2); memcpy(NeedData, bByte + (e / 4) * 2, 2); ReadColor(NeedData, PngList[i].Type, PngList[i].PNGdata, e); } delete[]bByte; } else { PngList[i].PNGdata = bByte; } } Npk_PngMutex.lock(); p->lp_lplist = PngList; Npk_PngMutex.unlock(); } } Fs.close(); return 0; } IMG* NPK_M::ReadNpkTable(const std::string imgpath) { std::cout << imgpath << std::endl; IMG* img = NULL; Npk_ImgMutex.lock(); std::map::iterator itr; itr = map_npk.find(imgpath); if (itr == map_npk.end()) { std::string mes = "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!调用了不存在的Img : " + imgpath; //MessageBoxA(0, mes.c_str(), 0, 0); img = &map_npk["sprite/interface/base.img"]; } else { img = &itr->second; } Npk_ImgMutex.unlock(); //如果图片数组不存在 或者 图片数据不存在都要重读 if (!img->lp_lplist || !img->lp_lplist->PNGdata) { LoadImgToMem(img); } return img; } void NPK_M::ReleaseNpkTable(IMG* p) { for (int i = 0; i < p->png_sum; i++) { if (p->lp_lplist[i].PNGdata) { delete p->lp_lplist[i].PNGdata; p->lp_lplist[i].PNGdata = 0; } else { int a = 0; } } //delete[] p->lp_lplist; //p->lp_lplist = NULL; } int Translate24Bto32B_cpp(char* des, char* src, int num) { for (int i = 0; i < (num / 4); i++) { unsigned short aword = *(unsigned short*)src; unsigned short A = aword >> 12; unsigned short R = 15 & aword >> 8; unsigned short G = 15 & aword >> 4; unsigned short B = 15 & aword >> 0; A = (A * 255) / 15; B = (B * 255) / 15; G = (G * 255) / 15; R = (R * 255) / 15; unsigned int aDword = 0; aDword |= A; aDword <<= 8; aDword |= R; aDword <<= 8; aDword |= G; aDword <<= 8; aDword |= B; *(unsigned int*)des = aDword; src += 2; des += 4; } return 0; } int Translate16Bto32B_cpp(char* des, char* src, int num) { for (int i = 0; i < (num / 4); i++) { unsigned short aword = *(unsigned short*)src; unsigned short A = aword >> 15; unsigned short R = 31 & aword >> 10; unsigned short G = 31 & aword >> 5; unsigned short B = 31 & aword >> 0; A = A * 255; B = (B * 255) / 31; G = (G * 255) / 31; R = (R * 255) / 31; unsigned int aDword = 0; aDword |= A; aDword <<= 8; aDword |= R; aDword <<= 8; aDword |= G; aDword <<= 8; aDword |= B; *(unsigned int*)des = aDword; src += 2; des += 4; } return 0; } NPK_M::~NPK_M() { map_npk.clear(); }